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.

comments powered by Disqus