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); } },
Advertisement
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://v2.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.