Reputation: 5290
I have a series of text fields with a button next to each field. When the user taps the button next to one of the fields I want to apply a particular style to that button (to change its colour) - essentially allowing the user to "tick" that they have checked that field (similar to a checklist).
There are nine text fields/buttons on the page, and I have the status of all the buttons stored in an array called items_checked
which is initialized in data()
as the following:
items_checked: [false, false, false, false, false, false, false, false, false]
Each button has the following code:
<button class="btn btn-danger" v-on:click="toggleChecked(0)" v-bind:class="{'itemChecked' : items_checked[0]}">
where the number indicates the index of the button (i.e. 0 is the first button, 1 is the second button, etc.) to correspond to the equivalent boolean in items_checked
.
The v-on:click
event just toggles the checked status in the items_checked
for the tapped button:
toggleChecked (itemIndex) {
if (this.items_checked[itemIndex] === false) {
this.items_checked[itemIndex] = true
} else {
this.items_checked[itemIndex] = false
}
console.log(this.items_checked)
}
This works as the console.log
shows the boolean values toggling.
However, the v-bind
does not work as the itemChecked
class does not get applied to the button. It seems to be an issue binding to a boolean value within an array, as when I bind just to a standard boolean declared within data()
it works fine.
I do eventually need all the checked statuses stored in an array, so that I can evaluate that all have been checked before allowing the user to submit the page.
Any help would be appreciated.
Upvotes: 2
Views: 1055
Reputation: 22403
This is common reactivity problem.
In document:
Due to limitations in JavaScript, Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g.
vm.items[indexOfItem] = newValue
When you modify the length of the array, e.g.
vm.items.length = newLength
You can use deep copy
toggleChecked (itemIndex) {
this.items_checked[itemIndex] = !this.items_checked[itemIndex]
this.items_checked = JSON.parse(JSON.stringify(this.items_checked))
console.log(this.items_checked)
}
Another solution is using Vue.set
toggleChecked (itemIndex) {
var oldValue = this.items_checked[itemIndex]
this.$set(this.items_checked, itemIndex, !oldValue)
console.log(this.items_checked)
}
Upvotes: 2