Tauha
Tauha

Reputation: 109

Knockout 3 level optgroup binding

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

Answers (1)

Maciej Kwas
Maciej Kwas

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

Related Questions