I am using Vuejs for template and databinding. Here is my HTML:
<div id="message"></div>
<div id="items">
<div v-show="list.length > 0">
<button v-on="click: selectMode = true"
v-show="!selectMode">Start Selection</button>
<button v-on="click: selectMode = false"
v-show="selectMode">End Selection</button>
<button v-on="click: selectAll">Select All</button>
<button v-on="click: remove">Remove</button>
</div>
<ul>
<list-item v-repeat="list"></list-item>
</ul>
</div>
<script type="text/html" id="template">
<li>
<input type="checkbox" v-show="$parent.selectMode"
v-model="selected" name="checkbox" value="{{Id}}" />
<label>{{Name}}</label>
</li>
</script>
And JS:
var message = document.getElementById("message");
var items = [
{ Id: 1, Name: "Apple" },
{ Id: 2, Name: "Orange" },
{ Id: 3, Name: "Banana" },
{ Id: 4, Name: "Mango" }
];
var data = {
list: items,
selectedList: [],
selectMode: false
}
var vue = new Vue({
el: "#items",
data: data,
methods: {
selectAll: function(){
if(!this.selectMode){
this.selectMode = true;
}
for(var i = 0; i < this.list.length; i++){
this.list[i].$set("selected", true);
}
},
remove: function(){
var length = this.selectedList.length;
if(length === 0){
show("Nothing to remove");
return;
}
while(length > 0){
var index = this.selectedList.pop();
this.list.splice(index, 1);
length--;
}
}
},
components:{
'list-item': {
template: "#template",
computed: {
selected: {
get: function(){
return this.$parent
.selectedList
.indexOf(this.$index) > 0;
},
set: function(value){
show(this.Name + " " + (value ? "Selected" : "Deselected") + " at index: " + this.$index);
if(value){
this.$parent
.selectedList
.$add(this.$index);
}
else{
this.$parent
.selectedList
.$remove(this.$index);
}
}
}
}
}
}
});
function show(mess){
message.innerHTML = mess;
setTimeout(function(){
message.innerHTML = "";
}, 5000);
}
Vuejs duly binds the template with list, and items are listed as expected in <li>
tags. The problem is computed property: selected
. The setter of this property is triggered when the checkbox is clicked, however, if the property is set in code, the setter isn't called.
When "Start Selection" button is hit, checkboxes are visible for each item. When user clicks on checkbox, setter of computed selected
property is invoked. However, if you press, "Select All" button, which sets selected
property to true
, checkboxes are visible, and they are duly checked, but setter of selected
property isn't triggered, which is unexpected. Why isn't this working? Either I am missing something, or this is a bug in Vuejs.
Here is a link to fiddle: http://jsfiddle.net/dreamakshay/c76rwugz/5/. These are few things you can try.
Run > Click Start Selection > Tick Checkboxes (setter triggered) > Message in Div, and "Remove" will remove the selected items.
Run > Click Select All (all checked) > Press Remove > An unexpected error in Div "Nothing to remove", which shouldn't happen.
Any help is appreciated.