Dynamic Binding of Checkboxes in Vuex

I am encountering a problem with binding checkboxes using Vuex. Even though I am using v-model with a variable that has a getter and setter to set or get the value in the store, I keep getting incorrect data in the store. The issue arises when I click on a checkbox multiple times, as it either overwrites or removes the store values. Can someone assist me in understanding why this is happening? Here is the link to the jsFiddle.

Here is the code:

const store = new Vuex.Store({
state: {
checkboxes: {},
checked: {}
},
mutations: {
  setCheckboxes(state, dataObj){
    console.log(dataObj);
    state.checkboxes = dataObj.data;
    let firstElem = dataObj.data[Object.keys(dataObj.data)[0]];
    state.checked[firstElem.parent_id] = [firstElem.id];
    console.log(state.checked);
  },
  setTreeState(state, dataObj){
    state.checked[dataObj.id] = dataObj.value;
    console.log(state.checked);
  }
 }
});


Vue.component('checkboxTree', {
  template: "#checkboxTree",
});

Vue.component('checkboxToggle', {
  template: "#checkboxToggle",
  data(){
    return {
      store
    }
  },
  computed: {
    value:{
      get(){ 
        return store.state.checked[this.checkbox.parent_id];
      },
      set(val){ 
        store.commit({
        type: 'setTreeState',
        id: this.checkbox.parent_id,
        value: val
      });
    },
  },
},
props: ['checkbox']
});

const app = new Vue({
  el: "#app",
  store,
  data: {
    checkboxData: {
    ...
    },

  },
  mounted(){
    this.$store.commit({
      type: 'setCheckboxes',
      data: this.checkboxData
    });
  }
})

And here is the template:

<div id="app">
  <checkbox-tree :checkboxData="checkboxData"></checkbox-tree>
</div>    

<template id="checkboxTree">
  <div>
    <p>checkbox tree</p>
  <form>
   <ul>
     <li v-for="checkbox in $store.state.checkboxes">
       <checkbox-toggle :checkbox="checkbox"></checkbox-toggle>
     </li>
   </ul>
  </form>
  </div>
</template>

<template id="checkboxToggle">
  <div>
  <label>{{ checkbox.id }}</label>
   <input type="checkbox" 
    :value="checkbox.id"
    :id="'checkbox-' + checkbox.id"
    :name="'checkbox-' + checkbox.id"
    v-model="value"
    >
  </div>
</template>

Answer №1

For the purpose of storing ids of selected objects in the variable checked, I modified your code structure considerably:

const removeIDFromArray = (array, value) => {
const newArray = [...array];
  const index = newArray.indexOf(value);
  if (index > -1) {
    newArray.splice(index, 1);
    return newArray;
  }
  return array;
}

const storage = new Vuex.Store({
  state: {
    checkboxes: {},
    checked: [],
  },
  mutations: {
    addToChecked(state, id) {
    state.checked.push(id);
    },
removeFromChecked(state, id) {
      const newArray = removeIDFromArray(state.checked, id);
      state.checked = newArray;
    },
    setCheckboxes(state, data) {
      state.checkboxes = data;
    },
  }
});

Vue.component('checkboxTree', {
  template: "#checkboxTree",
  computed: {
    checkboxes() {
    return this.$store.state.checkboxes;
    },
  },
});

Vue.component('checkboxToggle', {
  template: "#checkboxToggle",
computed: {
    value:{
      get(){
        return this.$store.state.checked.indexOf(this.checkbox.id) > -1;
      },
      set(val){
        const mutation = val ? 'addToChecked' : 'removeFromChecked';
        this.$store.commit(mutation, this.checkbox.id);
      },
    },
  },
  props: ['checkbox'],
});

const app = new Vue({
  el: "#app",
  store: storage,
  data: {
    checkboxData: {
      "5479": {
        "id": 5479,
        "title": "Location of Services",
        "type": "checkbox",
        "dependencies": "",
        "description": "",
        "parent_id": 5478,
        "npas": ""
      },
      "5480": {
        "id": 5480,
        "title": "Methods of Providing Services",
        "type": "checkbox",
        "dependencies": "",
        "description": "",
        "parent_id": 5478,
        "npas": "50"
      },
      "5481": {
        "id": 5481,
        "title": "Scope and Procedure of Client Assistance in Service Delivery",
        "type": "checkbox",
        "dependencies": "",
        "description": "",
        "parent_id": 5478,
        "npas": "54"
      },
    }
  },
  computed: {
  stateStructure() {
    return JSON.stringify(this.$store.state, null, 2);
    },
  },
  mounted() {
    this.$store.commit('setCheckboxes', this.checkboxData);
    const firstElementKey = Object.keys(this.checkboxData)[0];
    const firstElement = this.checkboxData[firstElementKey];
    this.$store.commit('addToChecked', firstElement.id);
  }
})
<script src="https://unpkg.com/vue"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>

<div id="app">
  <checkbox-tree :checkboxData="checkboxData"></checkbox-tree>
  <pre v-text="stateStructure"></pre>
</div>

<template id="checkboxTree">
  <div>
    <p>Checkbox Tree</p>
    <form>
      <ul>
        <li v-for="checkbox in checkboxes">
          <checkbox-toggle :checkbox="checkbox"></checkbox-toggle>
        </li>
      </ul>
    </form>
  </div>
</template>

<template id="checkboxToggle">
  <div>
   <label>{{ checkbox.id }}</label>
   <input 
     type="checkbox" 
     :value="checkbox.id" 
     :id="'checkbox-' + checkbox.id" 
     :name="'checkbox-' + checkbox.id"
     v-model="value">
    {{value}}
  </div>
</template>

You have the freedom to populate checked as per your requirements using this revised code.

Furthermore, here is a jsfiddle link you might find useful: https://jsfiddle.net/oniondomes/ckj7mgny/

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

Creating a combination of associative keys and numbers within an array using JavaScript

To summarize, my question starts below: I have simply read a JSON file with the following contents: [{"FirstCategory":"Bath","SecondCategory":"Bath Accessories","ThirdCategory":""}, {"FirstCategory":"Bath","SecondCategory":"Faucets","ThirdCategory":""}, ...

What is the best way to display multiple levels of content within a v-for loop?

I am looking to create 20 expansion panels using a v-for loop to display the categories fetched from my JSON in each panel header. Additionally, I want to populate each expansion panel's content with the corresponding names retrieved from allItems dat ...

When dynamically loading content with ajax, dynamic content fails to function properly

Currently, I am attempting to incorporate dynamic content loading after the user logs in by utilizing $.ajax. Here is how it's being done: $.ajax({ url: "functions.php", type: "GET", data: login_info, datatype: 'html', a ...

Transmit information to a Django UpdateAPIView using Axios

Currently, I am including the Email in the body of an Axios patch request. const userData = await this.$axios.patch(`/user/${id}/update/`, { email: value }) This data is being sent to the specified API View within Django Rest Framework. ...

Angular 6 - Consistently returning a value of -1

I'm facing an issue with updating a record in my service where the changes are not being reflected in the component's data. listData contains all the necessary information. All variables have relevant data stored in them. For example: 1, 1, my ...

ContainerView: challenges encountered when dynamically inserting views

ContainerView.pushObject() does not automatically connect dynamically added views with a Container object. The absence of an auto-wired container leads to a rendering error when a view renders a template containing a handlebars render helper. SIMPLE SCENA ...

The callback functions, such as afterMove, are not being executed

This code snippet is copied from Owl Carousel's official website. I am having trouble getting the callback functions like afterMove to work. Can anyone help me figure out why the afterMove function is not being called? It seems that none of the callba ...

Component built in ReactJS for file uploads to a server running on Spring MVC/Data-REST

For quite some time, I have been on the lookout for a ReactJS component that enables file uploading from a browser, with the ability to save it to the server where the ReactJS application is deployed. I've come across several components that facilita ...

Execute supplementary build scripts during the angular build process

I've developed an Angular application that loads an iframe containing a basic html page (iframe.html) and a Vanilla JavaScript file (iframe.js). To facilitate this, I've placed these 2 files in the assets folder so that they are automatically cop ...

Navigating through the content of slots within recurring slots in a subcomponent in Vue.js

I am encountering an issue with a child component, where each row in an object is rendered inside a div with a specific slot. I need to pass data from the parent for each of these elements. I've been attempting to iterate through every element of the ...

Transferring a JavaScript variable to PHP using Ajax within the same webpage

Check out my HTML and JavaScript code: <form id="form" action="javascript:void(0)"> <input type="submit" id="submit-reg" value="Register" class="submit button" onclick="showtemplate('anniversary')" style='font-family: georgia;font- ...

The issue of jQuery, Ajax, and MVC6 parameters becoming null after an Ajax request has been identified

Hello everyone, I am a beginner in asp.net core, c# and MVC 6. Currently, I am facing an issue with sending data over ajax to my controller. function sendAjaxData() { $.ajax({ url: "AjaxWithData", // using hardcoded value for testing purpose type ...

Transferring a JSON array from Google App Engine to Cloud Storage using GO

I am attempting to upload a JSON array to Google Cloud Storage, which is posted by an App Engine application using the code below: saveData : function saveData() { var _this = this, save = this.shadowRoot.querySelector('#save-data'), ...

Typescript: Verifying the type of an interface

In my code, I have a function called getUniqueId that can handle two different types of interfaces: ReadOnlyInfo and EditInfo. Depending on the type passed to this function, it will return a uniqueId from either interface: interface ReadOnlyInfo { item ...

What is the process for uploading an image and entering text into the same row in Google Sheets?

Hello, I am currently working on a Google Script web app that enables users to upload 10 photos along with comments for each photo. This information will then be inserted into a Google Sheet when the user clicks the 'upload' button on the web app ...

extract elements from dataset

Attempting to splice an array but encountering index issues var kode_pelayanan = []; function deleteKodePelayanan(index){ kode_pelayanan.splice(index, 1); console.log(kode_pelayanan); } Experimented in the console with an array for kode_pelayanan ...

What are the advantages of using the CRUD coding style with Redux?

Seeking guidance on the best coding style for a single page application regarding the use of React Redux For instance, consider a standard CRUD page where data is presented in a table with a pop-up modal form. The table's data comes from server-side ...

JQuery not refreshing data values

function addToRewardDatabase() { var rewardValue = "98"; $.post("db/mkreward.php", { proid: getURLParameter("id") }, function(data) { rewardValue = "99"; alert(rewardValue); }); alert(rewardValue); return ...

Despite returning an "OK" status, the jQuery Ajax Codebehind Post fails to function properly

Attempting to call a function in ASP.NET with jQuery Ajax: var params = "{'name':" + "\"" + name + "\"}"; $.ajax({ type: "POST", url: "CreateTopic.aspx/CreateNewTopic", data: params, ...

Tips for integrating external JavaScript libraries and stylesheets into a widget

I am currently working on developing a custom Javascript widget that requires users to insert specific lines of code into their web pages. This code will then dynamically add an externally hosted javascript file, allowing me to inject HTML content onto the ...