What are the steps to dynamically divide a single list into multiple lists using Vue-draggable and Vuex?

I have created an array that collects input from the user by answering multiple questions. The values are then stored in my vuex store, and the results are displayed on the screen as a draggable list.

computed: {
  allValues() {
        const val1 = this.responses1
        const val2 = this.responses2
        const val3 = this.responses3
        const val4 = this.responses4
        const val5 = this.responses5
        const val6 = this.responses6
        const val7 = this.responses7
        const coreValues = val1.concat(val2,val3,val4,val5,val6,val7)
        this.$store.dispatch('corevalues/loadCoreValues', coreValues)
        return this.$store.getters['corevalues/getCoreValues']
    }
  }

Draggable List

 <draggable :v-model="allValues" 
    options:='group: "allValues"'>
     <transition-group>
      <div v-for="val in allValues" :key="val.value">
          {{val.value}}
      </div>
    </transition-group>
 </draggable>

{{ allValues }}

However, I am facing an issue where although I can drag and sort the values on-screen, they do not reorder in the Vuex Store, only visually.

1) Requirement: Reordering in the Vuex Store

2) Requirement: Ability to drag values into multiple columns for grouping

How can I ensure that changes made on the screen reflect in the store, even creating a new array, and how can I split the list into multiple columns?

Code Sandbox link: https://codesandbox.io/embed/vue-template-j53g3

EDIT: Following Sabee's response

I have added the following code:

watch:{
    allValues: {
        handler: function(newValue) {
          console.log('here', newValue)
          this.$store.dispatch("corevalues/loadCoreValues", newValue);
        }
    },
    deep: true // deep watching changes
  },

Despite implementing the above code, the array {{ allValues }} remains unchanged in order even after re-arranging it on-screen.

https://i.sstatic.net/yUWZn.png

2nd edit

I have updated the code based on the recommendations given.

Although the console logs 'Drag Ended,' the Core Values in the store still show no update, even after 'reloading state' via dev tools.

https://i.sstatic.net/72bIx.png

Answer №1

You have the option to utilize

watch:{
 list: {
        handler: function(newValue) {
            // carry out your tasks

           // this.$store.commit("updateList", value);
           // commit your changes to store 
  }

        },
        deep: true // monitoring deep changes
    }

}

This method allows you to monitor changes and re-ordering, as well as providing a good solution to incorporate a button for saving user modifications to the store.

UPDATE It appears that drag changes are not being monitored :( ... However, in vue-draggable there are events like @end https://i.sstatic.net/spiEi.png Upon completion of a drag, you can save the sorted array in the vuex store

 <draggable :v-model="allValues" @end="onEnd">
          <transition-group>
            <div v-for="val in allValues" :key="val.value">{{val.value}}</div>
          </transition-group>
        </draggable>

And in the methods

  methods: {
    onEnd(){
      console.log("Drag ended")
        this.$store.dispatch("corevalues/loadCoreValues", this.allValues);
    },

Finally

<script>
import draggable from "vuedraggable";
export default {
  components: {
    draggable
  },
  data() {
    return {
      num: 1,
      allValues:[],
      responses1: [],
      responses2: [],
      responses3: [],
      responses4: [],
      responses5: [],
      responses6: [],
      responses7: [],
      question: [
        {
          id: 1,
          question: "What do you believe defines the culture at your company?"
        },
        {
          id: 2,
          question:
            "What values do you bring to your work that you consistently uphold whether or not they are rewarded?"
        },
        {
          id: 3,
          question:
            "What do you truly stand for in your work? What do you believe your company truly stands for?"
        },
        {
          id: 4,
          question:
            "What do your customers believe about you? What do they believe you stand for?"
        },
        {
          id: 5,
          question:
            "What values does your company consistently adhere to in the face of obstacles?"
        },
        {
          id: 6,
          question: "What are your company’s greatest strengths?"
        },
        {
          id: 7,
          question:
            "What are the top three to five most important behaviours you should expect from every employee (including you)?"
        }
      ]
    };
  },
  computed: {
    number(number) {
      return this.number + number;
    },
    // allValues: {
    //   // get() {
    //   //   const val1 = this.responses1;
    //   //   const val2 = this.responses2;
    //   //   const val3 = this.responses3;
    //   //   const val4 = this.responses4;
    //   //   const val5 = this.responses5;
    //   //   const val6 = this.responses6;
    //   //   const val7 = this.responses7;
    //   //   const coreValues = val1.concat(val2, val3, val4, val5, val6, val7);
    //   //   // this.$store.dispatch("corevalues/loadCoreValues", coreValues);
    //   //   // return this.$store.getters["corevalues/getCoreValues"];
    //   //   return coreValues;
    //   // },
    // }
  },
  watch: {
    responses1: {
      handler: function(newValue) {
        console.log(newValue)
        this.appendWithoutDuplicates(this.responses1)
      },
      deep: true // watching deeply for changes if needed
    },
    // responses from 2 to 7: { 
    //   handler: function(newValue) {
    //     console.log(newValue)
    //     this.appendWithoutDublicates(this.responses1)
    //   },
    //   deep: true // watching deeply for changes if needed
    // },
    allValues: {
      handler: function(newValue) {
        console.log(newValue)
       this.$store.dispatch("corevalues/loadCoreValues", newValue);
      },
      deep: true // watching deeply for changes if needed
    },

  },
  methods: {
    appendWithoutDuplicates(values){
      this.allValues = this.allValues.concat(values.filter(item => {
            return this.allValues.findIndex(obj => obj.value === item.value) < 0;
         }));
    },
    onEnd() {
      console.log("Drag ended");
      console.log(this.allValues);
      this.$store.dispatch("corevalues/loadCoreValues", this.allValues);
    },
    setValues() {
      // this.allValues = coreValues
    },
    questionNumber(num) {
      this.num += num;
    },
    addresponse1: function() {
      var elem = document.createElement("tr");
      this.responses1.push({
        value: ""
      });
    },
    removeElement1: function(index) {
      this.responses1.splice(index, 1);
    },
    addresponse2: function() {
      var elem = document.createElement("tr");
      this.responses2.push({
        value: ""
      });
    },
    removeElement2: function(index) {
      this.responses2.splice(index, 1);
    },
    addresponse3: function() {
      var elem = document.createElement("tr");
      this.responses3.push({
        value: ""
      });
    },
    removeElement3: function(index) {
      this.responses3.splice(index, 1);
    },
    addresponse4: function() {
      var elem = document.createElement("tr");
      this.responses4.push({
        value: ""
      });
    },
    removeElement4: function(index) {
      this.responses4.splice(index, 1);
    },
    addresponse5: function() {
      var elem = document.createElement("tr");
      this.responses5.push({
        value: ""
      });
    },
    removeElement5: function(index) {
      this.responses5.splice(index, 1);
    },
    addresponse6: function() {
      var elem = document.createElement("tr");
      this.responses6.push({
        value: ""
      });
    },
    removeElement6: function(index) {
      this.responses6.splice(index, 1);
    },
    addresponse7: function() {
      var elem = document.createElement("tr");
      this.responses7.push({
        value: ""
      });
    },
    removeElement7: function(index) {
      this.responses7.splice(index, 1);
    }
  }
};
</script>

Also update the draggable section

<draggable :list="allValues" @end="onEnd">
  <transition-group>
    <div v-for="val in allValues" :key="val.value">{{val.value}}</div>
  </transition-group>
</draggable>

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

Store the ajax call response in a dynamic function

Currently, I am in the process of creating a series of user-friendly formulas, similar to those found in Excel, for a form builder website. One of the features I have developed is a Lookup function that allows users to specify the value they want and the v ...

Creating content by extracting key value pairs from a JSON object retrieved from Firebase

After setting up a Firebase database and populating it with JSON data, I found code from the Firebase documentation that allows me to update the data in real time. While this works well for my needs, I also want to access the values in the JSON to create l ...

The Countdown feature is currently only functioning on the initial button and not on any of the other buttons

I could use some assistance. I have a download button with a countdown, but there seems to be an issue with the button's functionality. It only works on the first button, or if the second button is clicked first, it starts the countdown on the first b ...

Unspecified data returned from PHP script via jQuery AJAX

Encountering an issue while trying to use AJAX to get a PHP response from a form. The JavaScript appears to be correct as it functions when the content of login_ajax.php is reduced to just: echo 'CORRECT' //or echo 'INCORRECT' Howev ...

Change the size of Jive Addon Tile in a vertical orientation

Seeking assistance with resizing the tile container in an angular application embedded within a Jive tile when the view changes. Any advice on how to tackle this issue? This particular tile is deployed to a Jive Cloud instance using a Jive add-on. ...

Broken links detected in the Full Page Navigation menu on a one-page website

The hyperlinks on this particular page seem to be malfunctioning despite the fact that the li.a tags are correctly targeting specific section IDs. Markup: <header> <a href="#0" class="nav_icon"><i></i></a> </header> ...

Tips for obtaining the base URL using JavaScript

As I construct a website using the CodeIgniter framework, I utilize the base_url helper function to load various resources. For example: <link rel="stylesheet" type="text/css" href="'.base_url('assets/css/themes/default.css').'" id= ...

The value 'true' was returned for an attribute 'exact' that is not of boolean type

How can I resolve this warning? Sample Code const Main = (header, navigation) => { return ( <> <div> {navigation !== false && <Navigation />} </div> </> ) } I attempted this soluti ...

Using Angular components to manipulate the CSS in the DOM

Struggling with dom manipulation in an angular/node.js environment using typescript for my visualcomponent.html The second inline styling works fine, showing the h1 in blue color. However, I run into issues when trying to embed strings within the innerHTM ...

Obtain the value stored in the variable named "data"

I'm trying to calculate the sum of data values using jQuery, similar to this example: { label: "Beginner", data: 2}, { label: "Advanced", data: 12}, { label: "Expert", data: 22}, and then add them together. Like so: var sum = data1+data2+dat ...

Drag and drop to upload files

Is there a way to enable drag-and-drop functionality for uploading and downloading files between a user's computer and web browser? If so, what is the best approach - ASP.NET with AJAX or JS/JQuery? ...

What is the best way to access AngularJS Service code from an Android webview?

I've been attempting to initiate contact with an AngularJS service through the Android webview component, but I haven't had any luck so far. Do you have any suggestions on how I can achieve this? Here is the JavaScript code that I've been t ...

Direct attention to the modal display

I'm having trouble auto-focusing an input field when a modal is displayed. Here's what I've tried, but it doesn't seem to be working: jQuery(document).ready(function($) { $('#myModal').on('show.bs.modal', functi ...

Choose an option to adjust the transparency of the image

I'm struggling with a select option and need some assistance. I have a select dropdown list where I want the image opacity to change from 0.3 to 1 when selected or onchange event occurs. The catch is, I can't use the value of the option because i ...

Updating the innerHTML of a frameset

I have a unique challenge that involves loading the frameset of www.example.com/2.html when accessing www.example.com/en/test/page.html. Successfully accomplished this task. Now, after loading 2.html in the frameset, I want to modify ".html" to ".html" t ...

When troubleshooting AJAX in Chrome, only the library lines are displayed in the call stack

While using "XHR breakpoints" to identify which line is triggering an AJAX request, I noticed that the call stack only shows Angular.js library lines. This makes it difficult to pinpoint the exact line in my code that triggered the request. What steps shou ...

Is the `$route` automatically included as a parameter when utilizing `this.$router.push()`?

As the title suggests, I'm curious about whether this.$router.push() automatically adds this.$route to the parameter. A friend mentioned that it does, but I couldn't find any documentation to confirm this. In a nutshell, here's the code sni ...

What could be the reason for the child event not updating the state in the parent component (Vue)?

I have a component called customize-charts which contains a Vuetify drawer: <template> <v-col> <v-btn style="float: right" class="mr-4 mt-2" small @click="toggleCustomize" v-if="!open">Custom ...

Adding functions to the window scroll event

Rather than constantly invoking the handler, John Resig proposes using setInterval() to optimize the number of times it is called - check out his thoughts at http://ejohn.org/blog/learning-from-twitter/ In his blog post, John presents the following soluti ...

Ways to verify that window.open is being invoked from a React component

In my React component, I have a set of nested components, each with its own checkbox. The state hook rulesToDownload starts as an empty array and dynamically adds or removes IDs based on checkbox selection. Upon clicking the 'download' button, t ...