Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knockout js 'with' binding, hide if array is empty

I have a category drop down list which controls a sub category drop down list. I want to hide the sub categories drop down list if the sub category array is empty for the selected category.

Sample code below:

<script>

    self.categories = ko.observableArray([
            {"name": "top 1", "subcategories":[
                                              {"name": "sub 1"},
                                              {"name": "sub 2"}
                                              ]},
            {"name": "top 2", "subcategories":[]}
    ]);

    self.selected_category = ko.observable();
    self.selected_sub_category = ko.obserable();

</script>

<div>
    <select data-bind="options: categories, optionsText: "name", optionsCaption: "Select", value: selected_category"></select>
</div>  
<div data-bind="with:selected_category">
    <select data-bind="options: subcategories, optionsText: "name", optionsCaption: "Select", value: selected_sub_category"></select>
</div>  

like image 961
the-a-train Avatar asked Apr 14 '13 15:04

the-a-train


1 Answers

You need to combine the with binding with the if (or the visible) binding where you can specify your condition:

<div data-bind="with: selected_category">
    <!-- ko if: subcategories.length > 0 -->
    <select data-bind="options: subcategories, optionsText: 'name', 
        optionsCaption: 'Select', value: $parent.selected_sub_category"></select>
    <!-- /ko -->
</div> 

Demo JSFiddle.

Note the usage of the $parent in the value: $parent.selected_sub_category, you need that to access "parent" object because the with creates a child context.

If you don't want to render the whole div when the sub collection is empty then you need to move the with and if outside your div because KO not allow to use multiple control-flow bindings on the same element.

So in that case your HTML would look like this:

<!-- ko with:selected_category -->
    <!-- ko if: subcategories.length > 0 -->
        <div class="mydiv">    
            <select data-bind="options: subcategories, optionsText: 'name', 
                    optionsCaption: 'Select', 
                    value: $parent.selected_sub_category">
            </select>    
        </div> 
    <!-- /ko -->
<!-- /ko -->

Demo JSFiddle.

like image 169
nemesv Avatar answered Oct 26 '22 00:10

nemesv