Reverting Vue Draggable Components to Their Original Position Upon Dropping Them

In my Vue 3 project, I'm implementing vuedraggable to enable element reordering within an expansion panel. However, I've encountered an issue where the dragged elements revert to their original positions upon release. This behavior suggests that the underlying list in vuedraggable is not being properly updated when elements are moved, causing them to reset. Below is a snippet of the relevant code:

<v-expansion-panels>
  <v-expansion-panel v-for="feature in groupedFeatures" :key="feature.type">
    <v-expansion-panel-title>
      <div>{{ translateFeatureType(feature.type) }}</div>
    </v-expansion-panel-title>
    <v-expansion-panel-text>
      <draggable v-model="feature.details" group="featureGroup" item-key="model_name">
        <template #item="{element, index}">
          <div :key="element.model_name">
            <p><strong>Model:</strong> {{ element.model_name }}</p>
            <p>{{ element.value }}</p>
          </div>
        </template>
      </draggable>
    </v-expansion-panel-text>
  </v-expansion-panel>
</v-expansion-panels>

Imports used in this project:

import { ref, onMounted, computed } from 'vue';
import axios from 'axios';
import { useRoute } from 'vue-router';
import draggable from 'vuedraggable';

const route = useRoute();
const features = ref([]);
const messages = ref([]);

The onMounted function implementation:

onMounted(async () => {
    const threadData = await fetchEmailThreads(route.params.id);
  if (threadData) {
    features.value = threadData.features;
    messages.value = threadData.messages;
  }

Function for grouping features:

const groupedFeatures = computed(() => {
  const featureMap = new Map();
  features.value.forEach(f => {
    if (!featureMap.has(f.type)) {
      featureMap.set(f.type, { type: f.type, details: [] });
    }
    featureMap.get(f.type).details.push({ model_name: f.model_name, value: f.value });
  });
  return Array.from(featureMap.values());
});

Sample data structure received from the server:

{
  "chat_id": 1,
  "features": [
    {
      "model_name": "Vicuna-13B",
      "type": "abstract_feature",
      "value": "---Feature Content---"
    },
    ...
  ],
  "inst_id": 0,
  "messages": [
    {
      "content": "Message Content...",
      ...
    }
  ],
  "subject": "Topic"
}

How can I ensure that the elements in the list are correctly updated and maintain their new positions after being dragged?

Answer №1

Your groupedFeatures is not being treated as a vue ref, but instead as a computed value. Therefore, updating it with a callback from draggable won't work.

My suggestion is to reevaluate how you're calculating groupedFeatures. I recommend performing this calculation once within the onMounted callback, where you initially set your features.

const groupedFeatures = ref([]);

onMounted(async() => {
  const threadData = await fetchEmailThreads(route.params.id);
  if (!threadData) return;

  const featureMap = new Map();
  features.value.forEach(f => {
    if (!featureMap.has(f.type)) {
      featureMap.set(f.type, {
        type: f.type,
        details: []
      });
    }
    featureMap.get(f.type).details.push({
      model_name: f.model_name,
      value: f.value
    });
  });
  groupedFeatures.value = Array.from(featureMap.values());
});

By making these adjustments, your issue should be resolved.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Data Sharing Among Components in Vue without Using Parent/Child Relationship

I'm working on an HTML site and I want to incorporate some Vue.js components onto the page. For example, I'd like to have an input field in the header as a Vue component. <header><search-component></search-component></header ...

"Encountered an error while trying to define a Boolean variable due

I am in the process of creating a TF2 trading bot with price checking capabilities. I encounter an issue while trying to define a boolean variable to determine if the item is priced in keys or not. My attempt at replacing isKeys with data[baseName].prices ...

Transform a Vue.JS project into a Nuxt.JS project

Is it possible to transform a Vue.JS project into a Nuxt.JS project? Vue.js Project If you want to view the complete Vue.JS project, click here. This project utilizes the npm package vue-conversational-form to convert web forms into conversations using ...

Discovering the current time and start time of today in EST can be achieved by utilizing Moment.js

Need help with creating Start and End Time stamps using Moment.js in EST: Start Time should reflect the beginning of today End Time should show the current time. This is how I have implemented it using moment.js: var time = new Date(); var startTime=D ...

invoking a function in javascript from react

Currently, I am grappling with the task of invoking a JavaScript function from within React while adapting a "React" based "Menu" onto some existing jQuery functions. Below you can find my code for the menu: class Menus extends React.Component{ co ...

What is the best way to avoid duplicating child components in conditional rendering?

Scenario I have created a custom button component using Vue: <custom-button type="link">Save</custom-button> This is the template for my custom button component: // custom-button.vue <template> <a v-if="type === &apo ...

working with JSON array information

I have a JSON array retrieved from a database that I need to manipulate. Currently, it consists of 8 separate elements and I would like to condense it down to just 2 elements while nesting the rest. The current structure of my JSON looks like this: { "i ...

What could be causing the submission failure of the form post validation?

My Code: <form method="post" name="contact" id="frmContact" action="smail.php"> ... <label for="security" class="smallPercPadTop">Please enter the result:</label> <br /><h3 id="fNum" class="spnSecurity"></h3>& ...

Implementing a delay between two div elements using jQuery

I have two Divs with the class "sliced", each containing three images with the class "tile". When I animate using jQuery, I am unable to add a delay between the "sliced" classes. However, I have successfully added a delay between the "tile" classes. index ...

Making HTTP requests with axios in Node.js based on multiple conditions

I'm facing an issue with making get calls using axios to both activeURl and inactiveURl. The goal is to handle error messages from the activeUrl call by checking data from the inactiveUrl. However, I keep receiving error messages for the inactiveURL e ...

Switching Over to Burger Menu

I created a burger menu using HTML, CSS, and jQuery that switches from a full-width menu to a burger menu. However, I'm facing an issue with toggling the dropdown when the menu collapses. Here's my code: <!DOCTYPE html> <html> < ...

"Trouble with server communication: data array not being passed to hbs

In my GET route, I have the following: app.get(("/employee/:id"), (req, res) => { data.getEmployeeByNum(req.params.id).then((data) => { res.render("employee", {employee: data}); }).catch(function(reason) { res.render("employe ...

Creating an ongoing loop endlessly using recursion in node.js

Seeking assistance in creating a recursive loop to continuously iterate through functions in Node.js for flow control. I have tried online tutorials but still struggling to comprehend it fully. Can anyone provide guidance or point me towards a proper tutor ...

Experiencing a bug in my express application: TypeError - Unable to access properties of undefined (reading 'prototype')

I've encountered the TypeError: Cannot read properties of undefined (reading 'prototype') error in my javascript file. Despite researching online, it seems that many attribute this issue to importing {response} from express, but I am not doi ...

Verify if the term is present in an external JSON file

I am currently using tag-it to allow users to create tags for their posts. At the moment, users can type any word, but I have a list of prohibited words stored in JSON format. I am looking for a way to integrate this list into the tagit plugin so that if ...

Using Vue.js in conjunction with Gulp: A Beginner's Guide

Currently, I am working on a small project that involves gulp. I have a desire to incorporate vue.js into this project but do not have the knowledge on how to configure vue.js in the gulpfile.js. I am seeking guidance on the configuration of gulpfile to i ...

Comparing NextJs hydration with using the client-side approach

Currently exploring the ins and outs of NextJs to grasp its fundamental features. It is my understanding that by default, NextJs components operate on the server-side and utilize Hydration to enable interactivity shortly after displaying pre-rendered HTML ...

Showing a text value from a Github Gist on a Hugo website

I seem to be struggling with a seemingly simple task and I can't figure out what I'm missing. Any assistance would be greatly appreciated. I am working on generating a static site using Hugo. On one of my pages, I want to implement a progress ba ...

The element was rendered numerous times

I have implemented a conditional rendering logic using a v-if-statement as shown below: <div v-if="resp > 1023"> <PdfViewer /> </div> <div v-else> <PdfViewer /> </div> The issue I am facing is that ...

What is the best method for sending the styled and checked option via email?

Just finished customizing the checkboxes on my contact form at cleaners.se/home. Here's my question: If I select "telefon," how can I ensure that this option is sent to my email? In Contact Form 7, I used to simply type a shortcode. Is there a simila ...