Reputation: 109
I'm trying to bind a select/list box where i have 3 levels of data, i want my output to look like below
<select>
<optgroup label="Root 1">
<optgroup label="Group 1">
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</optgroup>
</optgroup>
<optgroup label="Root 2">
<optgroup label="Group 2">
<option>Option A</option>
<option>Option B</option>
<option>Option C</option>
</optgroup>
</optgroup>
</select>
And this is how I'm trying to bind
<div id="termdata">
<select id="termsList" name="Term" data-bind="foreach: allterms">
<optgroup data-bind="attr: { label: name}, foreach: termRoot">
<optgroup data-bind="attr: { label: name},foreach: termGroup">
<option data-bind="text: name"></option>
</optgroup>
</optgroup>
</select>
</div>
var termData = [{
"name": "Root 1", "termRoot": [{
"name": "Group 1", "termGroup": [{
"terms": [{
"name": "option 1"
}, { "name": "option 2" }, { "name": "option 3" }]
}]
}]
}, {
"name": "Root 2", "termRoot": [{
"name": "Group 2", "termGroup": [{
"terms": [{
"name": "option A"
}, { "name": "option B" }, { "name": "option C" }]
}]
}]
}];
var TermViewModel = function () {
var self = this;
self.allterms = ko.observableArray(termData);
}
ko.applyBindings(new TermViewModel(), document.querySelector('#termdata'));
I'm receiving following error
Message: Unable to process binding "foreach: function(){return terms }" Message: terms is not defined
whereas terms exists on groupTerms
Upvotes: 1
Views: 160
Reputation: 6459
From what I see you have invalid html loop syntax, and besides: nested optgroups are theoretically wrong and will be flattened anyway while rendering dom. This one should work:
<div id="termdata">
<select id="termsList" name="Term" data-bind="foreach: allterms">
<optgroup data-bind="attr: {label: name}"></optgroup>
<!-- ko foreach: { data: termRoot, as: 'root' } -->
<optgroup data-bind="attr: {label: root.name},
foreach: { data: root.termGroup[0].terms, as: 'group' }">
<option data-bind="text: group.name">ds</option>
</optgroup>
<!-- /ko -->
</select>
</div>
Notice that termGroup
is an Array, so theoretically you should loop over it as well (I've just used first index however - root.termGroup[0].terms
), whereas you are trying to display termGroup.name
in your syntax and there is no such thing since- as I said- termGroup is an Array.
Upvotes: 2