VUE component for Select all option

Tags: ,



In my application I have multiple tables on same page (also multiple pages). Each table has “Select all” option and checkboxes in each row. Code reuse would be really helpfull but I cant get this working. Currently I have following methods, but I always get Error in render: “TypeError: Cannot read property ‘includes’ of undefined”. Right now this is code is inside one component, but should be available to another one. How can I properly extra this to standalone component and then use it in others?

In mounted method there is a field selected : {}.

Vue HTML template:

<input type="checkbox" v-bind:checked="isSelected(sts.id, 'country')"
      @click="toggleSelected(sts.id, 'country')">

Vue methods:

isSelected(id, group) {
  return this.selected[group].includes(id);
},

toggleAll(event, group, items) {
  let state = $(event.target).prop("checked");
  for (let st of items) {
    if (state === true) {
      this.addSelected(st, group);
    } else {
      this.removeSelected(st, group);
    }
  }
},

addSelected(id, group) {
  if (!this.isSelected(id, group)) {
    this.selected[group].push(id);
  }
},

removeSelected(id, group) {
  this.selected[group] = this.selected[group].filter(item => item !== id);
},

toggleSelected(id, group) {
  if (this.isSelected(id, group)) {
    this.removeSelected(id, group);
  } else {
    this.addSelected(id, group);
  }
},

Answer

Your code expects this.selected to be populated with each group before isSelected() is called. You’ll need to add logic into that method to check if this.selected[group] exists, and add it if not.

Also, Vue already offers most of the functionality you are writing, for example this should take care of the logic for toggling each checkbox:

    <input
        type="checkbox"
        v-model="selected.country"
        :value="sts.id"
    >

(Ref: https://vuejs.org/v2/guide/forms.html#Checkbox)

For the “toggle all” functionality, you could create a helper method like this in a separate file, and then import it as needed:

toggleAllHelper(selectedItems, items) {
  const allBoxesChecked = items.every((item) => {
    return selectedItems.includes(item.id));
  });

  return allBoxesChecked ? [] : items.map(item => item.id);
},

You would use it like this inside the component:

import { toggleAllHelper } from 'helpers.js';

...

methods: {
    toggleAll(groupName, items) {
        const selectedArray = toggleAllHelper(this.selected[groupName], items);
        this.selected[groupName] = selectedArray;
    }
}

However, for this to work, first you would need to make sure this.selected already contains every group name that it needs, as I mentioned earlier.



Source: stackoverflow