I’m trying to create a list of check boxes with Knockout.js. The list itself comes from a data-bound source, as well as which items in the list are selected. The model I have looks something like this:
var ViewModel = function ()
{
this.areas = [{AreaId: 1, Name: 'Test 1'}, {AreaId: 2, Name: 'Test 2'}, {AreaId: 3, Name: 'Test 3'}];
this.AreasImpacted = ko.observableArray([1, 2]);
};
Now, I want to create a list of check boxes with the labels Test 1, Test 2, and Test 3. I want to have Test 1 and Test 2 checked. My HTML looks like so:
<span class="areas" data-bind="foreach: areas">
<label><input type="checkbox" data-bind="value: AreaId, checked: $parent.AreasImpacted" /><span data-bind="text: Name"></span></label>
</span>
This does draw each check box with the proper name, and I can verify the value attribute of each checkbox is being set correctly, however nothing gets checked! I’ve also tried setting this.AreasImpacted to just 2. When I do that, all 3 checkboxes are checked!
Totally confused!
Update:
If I change the model to:
this.AreasImpacted = ko.observableArray(['1', '2']);
Then things work as expected.
If I had to guess, I’d say the for-each binding is translating each value to a string. I’m curious if this is by-design, or a Knockout.js bug. I would expect the input’s value to be numeric, as that’s what I bound it to.
Bug Filed:
Since the above code does not work as documented, I’ve filed a bug on GitHub.
You’ll need to change things up a bit, to check if the
AreaIdof the area you’re rendering is contained in theAreasImpactedarray:See this fiddle for a working demo.
NOTE: Using this technique, checking or unchecking one of the bound check boxes will not update the data source.
Alternatively, you can make the array a list of strings, like such:
See this fiddle for a demo.
As noted in the comments, the KnockoutJS documentation seems to suggest that the OP’s original syntax should work. You can even get that to work by making the items in the array into strings (demo).
The KnockoutJS source can tell us why this happens. Look at the
checked.jsdefault binding to see the relevant bit of code that will decide whether to check an input or not:In this context:
valueis the array of area id’s (numbers, in the OP’s original code)elementis the<input .../>checkbox HtmlElementAs such, the
element.valuewill always be of type string, which is why the checkbox will only be checked if the items in the array are also strings.Whether this is a bug in KnockoutJS, or just some unexpected but logical behavior: I’m not sure.