Drop down lists with Handlebars
The technique I use for rendering drop down lists with Handlebars is to use a view model that encapsulates the select options as an array. This is similar to how I code C# MVC views.
What's nice is that the view model can encapsulate the creation of lists, select options, and various pieces of logic. In general if the code would make the view difficult to read, I push it into a view model.
Drop down lists naturally get messy since there can be many options, and rendering the list with a value selected requires the correct option to have the selected
HTML attribute applied to it.
For instance, say you want to render a drop down list to look like:
<p>
<label>Mode:</label>
<select name="config[mode]">
<option value=""></option>
<option value="live">Live</option>
<option value="test" selected="selected">Test</option>
</select>
</p>
<p>
<label>Pair:</label>
<select name="config[pair]">
<option value=""></option>
<option value="ltc_btc" selected="selected">LTC / BTC</option>
<option value="nmc_btc">NMC / BTC</option>
</select>
</p>
We can create a view model prior to rendering (I'm using Backbone in this example):
render: function() {
console.log('Rendering bot editor');
var viewmodel = this.model.attributes
, html;
// add mode options to view model
viewmodel.modeoption = [
{ name: '' },
{ name: 'Live', value: 'live', selected: viewmodel.config.mode === 'live' },
{ name: 'Test', value: 'test', selected: viewmodel.config.mode === 'test' }
];
// add pair options to view model
viewmodel.pairoption = [
{ name: '' },
{ name: 'LTC / BTC', value: 'ltc_btc', selected: viewmodel.config.pair === 'ltc_btc' },
{ name: 'NMC / BTC', value: 'nmc_btc', selected: viewmodel.config.pair === 'nmc_btc' }
];
// render using the template
this.$el.html(template(viewmodel));
return this;
},
As you can see, the viewmodel
gets initialized with the model attributes. Then two arrays which constitute the drop down list options get built; modeoptions
and pairoptions
.
These two arrays contain objects with name
, value
, and selected
properties and will be used by Handlebars to render the innards of the drop down list.
<p>
<label>Mode:</label>
<select name="config[mode]">
{{#each modeoption }}
<option value="{{value}}" {{#selected}}selected="selected"{{/selected}}>{{name}}</option>
{{/each}}
</select>
</p>
<p>
<label>Pair:</label>
<select name="config[pair]">
{{#each pairoption}}
<option value="{{value}}" {{#selected}}selected="selected"{{/selected}}>{{name}}</option>
{{/each}}
</select>
</p>
The template will interate over each option in each array. It will use a block level check against the selected
property add the appropriate HTML attribute.
Fairly simple and clean.