Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind properties to html template to reduce html code

Tags:

knockout.js

I have a knockout observable with a large list of properties. I currently have a lot of repeated html, that basically is the same apart from the property name. Is there any way I can use the equivalent of for/in with knockout templates?

I have a number of fields (approx. 20) that I want to display in a bootstrap form so each of them will use the following html:

<div class="form-group">
    <label data-bind="text: $parent.locale.fields.XYZ" for="XYZ" class="col-sm-3 control-label no-padding-right"></label>
    <div class="col-sm-9">
        <input data-bind="value: XYZ" type="text" name="XYZ" class="col-xs-10 col-sm-5" />
    </div>
</div>

Where XYZ is the name of the field. Is there any way I can loop through each property so that I do not have to repeat the html code for each field?

Here is a fiddle example: http://jsfiddle.net/robgallen/mSYZj/. Please note that my fields are not really called field1, field2 etc. so I cannot use a numerical loop.

like image 865
Space Monkey Avatar asked Feb 16 '26 23:02

Space Monkey


1 Answers

You can use the Object.keys (only IE9+) to get the property names of a given object.

Then you can use this in a foreach where you can use the $data to access the property name and use the array indexer syntax to get to your observables:

<form data-bind="foreach: Object.keys(data())" role="form">    
    <div class="form-group">
        <label data-bind="text: $parent.locale.fields[$data], 
                          attr: { for: [$data] }" 
             class="col-sm-3 control-label no-padding-right"></label>
        <div class="col-sm-9">
            <input data-bind="value: $parent.data()[$data], 
                          attr: { name: [$data] }" 
                 type="text" class="col-xs-10 col-sm-5" />
        </div>
    </div>    
</form>

Demo JSFiddle.

In production you probably don't want to use Object.keys directly in your binding but you can generate the property name array within your viewmodel (you can also exclude some of the properties etc.).

like image 127
nemesv Avatar answered Feb 20 '26 06:02

nemesv