I have a Knockout component which template prints two nested lists of items (checkboxes in my interface): a first foreach loop iterates through some "parents" items, a second (and nested) list iterates through each of the parents items and, if children are found, prints the children. The requirement is that if the user clicks on a parent item (that is, on a parent checkbox), all the children checkboxes become checked.
In my code, both parents and children checkboxes listen to an observable that is first set to false and then, when a parent is selected, is set to true - result: that parent's children get selected. My issue is that, this way, since every checkbox listen to the same observable, I end up with ALL the checkboxes selected, not only my selected parents + children, which is what I want.
Not sure how I should approach this issue some other way, here is my code:
ko.components.register("types",{
viewModel: function(){
var self = this;
// Data
self.types = ko.observableArray();
self.isPChecked = ko.observable(false);
nut.structuredDocumentTypes()
.done(function (types) {
self.types(types);
});
// Behaviours
self.selectChildren = function(parent) {
self.isPChecked(true);
console.log(self.isPChecked(),parent);
}
},
template:
'<div id="doctypes" class="wfp-form wfpTreeList">\
<h2 class="hidden">Document Types</h2>\
<ul class="wfpList" data-bind="foreach: types">\
<!-- ko if: $index() > 0 -->\
<li class="root">\
<input\
type="checkbox"\
name="types"\
class="wfp-checkbox"\
data-select="multi"\
data-bind="\
checked: $component.isPChecked,\
event: { change: $component.selectChildren },\
value: $data.id">\
<input\
type="checkbox"\
name="acc"\
data-bind="\
attr: { class: \'lvl\' + $data.id, id: \'acc\' + $data.id }">\
<label\
data-bind="attr: { for: \'acc\' + $data.id }">\
<i class="ico-angle-down"></i>\
</label>\
<span data-bind="text: $data.label" class="root-title"></span>\
<ul data-bind="attr: { \'data-lvl\': \'lvl\' + $index(), id: \'lvl\' + $data.id }">\
<!-- ko foreach: $data.members -->\
<li>\
<label data-bind="attr: { for: \'dt-child-\' + $parent.id + \'-\' + $index() }">\
<input\
name="types"\
type="checkbox"\
data-bind="\
checked: $component.isPChecked,\
value: $data.id,\
attr: { id: \'dt-child-\' + $parent.id + \'-\' + $index() }">\
<span data-bind="text: $data.label"></span>\
</label>\
</li>\
<!-- /ko -->\
</ul>\
</li>\
<!-- /ko -->\
</ul>\
</div>'
});
UPDATE: JSON looks like this:
[{
"id": 4,
"members": [
{
"last_modified_date": "2016-08-04T14:59:25.958Z",
"id": 31,
"label": "Backgrounders & Information Notes"
},
{
"last_modified_date": "2016-08-04T14:59:25.961Z",
"id": 32,
"label": "Biographies"
},
],
"label": "Event-/Stakeholder related documentation",
},
{
"id": 2,
"members": [
{
"last_modified_date": "2016-08-04T14:59:25.875Z",
"id": 1,
"label": "Books"
},
{
"last_modified_date": "2016-08-04T14:59:25.878Z",
"id": 2,
"label": "Briefs, Summaries, Synthesis, Highlights"
},
],
"label": "Publications"
}]
Thanks all.