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

Why does using rgba color with an alpha value cause my div to become see-through?

I am currently attempting to assign a background color to a specific style of pop-up, but whenever I use a value that includes an alpha channel, it ends up being transparent. This is the CSS code I have been using: --color: 255, 144, 106, 0.18; background ...

Next.js: Uh-oh! Looks like we've hit an obstacle with Error 413 Request Entity

I've encountered an issue while attempting to upload large files using Next.js. I've set up an onChange function for my file input, and here's the code snippet: const handleFileUpload = () => new Promise(async (resolve) => { if(ref ...

Whenever I attempt to run the NPM install command in the Terminal, it seems to generate multiple errors

I am encountering an issue on my work laptop. I have the latest versions of Angular, Nodejs, Nodesass, and VScode installed in the local environment path. Whenever I download an Angular template from Github and try to do NPM Install, it consistently thro ...

What is the best way to wrap `useFetch` in order to leverage reactivity?

When I wrap useFetch() as a composable to customize the baseURL and automatically set an authentication token, I encounter reactivity issues when calling the composable within a component without using the await keyword. Typically, I would call const { dat ...

Error message: npm command not recognized while running commands within an Electron application

While developing an electron app, I utilize shell commands with child_process.exec. One of the commands I use is npm run start, which functions perfectly in a development environment. However, upon building the application for production, all npm commands ...

Encountering an issue while attempting to access a JSON file using the fetch method

When attempting to read a json file locally, I encountered an error that looks like this: Fetch API cannot load file:///var/www/desktop-electron//dashboard/bnb.json. URL scheme "file" is not supported Below is the code snippet being used: fetch(`${drr}/ ...

Angular7 & Electron: Resolving the Issue of Loading Local Resources

I am encountering difficulties while working with electron. Although I can successfully load my project using ng serve, I encounter an error when attempting to open it with electron as shown in the developer tools Not allowed to load local resource: fil ...

The statusMessage variable is not defined within the "res" object in a Node Express application

I am currently developing a Node.js & Express.js application and I am in need of creating a route to display the app's status. router.get('/status', function(req, res) { res.send("Current status: " + res.statusCode + " : " + res.stat ...

JavaScript Application - Problem with Universal Windows Script

I recently built a website utilizing material design lite for the aesthetics: Here are the scripts included: <script src="./mdl/material.min.js"></script> <script src="Scripts/angular.min.js"></script> The necessary .css fi ...

Encountering issues with Node.js and Socket.io not displaying results on Internet Explorer when using a secure connection

I have successfully integrated socket.io, node.js, and express to serve real-time json data to multiple browsers except for IE (tested on version 9) over a secure connection. Everything was functioning smoothly until I switched to HTTPS. From the server&ap ...

What is the best way to create an array within an object during the parsing process

When working with a JSON object, I need to assign a value stored in the session against an ID. The JSON data is as follows: [ { "id": "a", "text": "a", "icon": true, "li_attr": { "id": "a" }, "a_attr": { "href": "#" ...

Experiencing difficulties with JWT implementation and seeking to transmit the JWT token to additional APIs

I am currently working on implementing JWT authentication in node js/express js: Below is the sample code I have written for this purpose: const jwt = require('jsonwebtoken'); const secretKey = crypto.randomBytes(64).toString('hex'); c ...

Environment variables in Node process are uninitialized

I'm currently in the process of developing my first Express application, which requires interaction with an API using a secure API key. To ensure the security of this key and any future environment variables, I have decided to store them in a .env fil ...

Problems arise when JQuery fails to function properly alongside ajax page loading

While utilizing ajax to load the page, I encountered an issue where the jQuery on the loaded page template was not functioning until the page was manually refreshed. The ready function being used is: jQuery(document).ready(function() { jQuery(' ...

Validator alert for AMP scripts

I have implemented the amp version for my content management system. Since each article has a different body, some include amp-instagram while others include amp-facebook, and so on. In order to cover all bases, I have added both amp-facebook and amp-inst ...

Is it possible to use both interfaces and string union types in TypeScript?

My goal is to create a method that accepts a key argument which can be either a string or an instance of the indexable type interface IValidationContextIndex. Here is the implementation: /** * Retrieves all values in the ValidationContext container. ...

several javascript onclick event listeners for manipulating the DOM

I am currently experimenting with d3 and attempting to create a simple webpage to showcase my d3 examples for future reference. The page displays the output of the d3 code (specifically, the force layout from Mike Bostock) and then embeds the correspondin ...

Using Vue JS to assign a computed value within a component

Is there a way to update the computed property in mycomponentone when the "Click me child" button is clicked? I am currently experiencing issues with this functionality... Interestingly, when I click on the "Click me parent" button, the props are successf ...

Converting Ajax to JSON with Jquery offline and Manifest for enhanced offline web applications

Looking to create an offline web application, I'm in the process of transitioning from Ajax to JSON using JQuery offline. Here is the initial Ajax code: $.ajax({ url: contentpage, data: contentpagedata, cache: false }).done(function( html ) { ...

Changing the size of the logo as you scroll through the page

I have implemented the following code to resize the logo as I scroll down the page. $(document).on('scroll', function() { if ($(document).scrollTop() >= 10) { $('.logo img').css('width', '50px'); } else ...