Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting the selected value of a Select element in Handlebars

I have a handlebars template that I am embedding in my html page. There is a select element with all of the available options already rendered. How can I set the selected value of the select list when I render my template?

<script id="my-template" type="text/x-handlebars-template">      
    <div id="my-modal">
      <form action="/TestAction" method="post">
        <input id="MyId" name="MyId" type="hidden" value="{{MyId}}" />      
        <label for="Test">Test: (optional)</label>
        <select id="Test" name="Test">
          <option value="">-- Choose Test --</option>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
          <option value="4">4</option>
        </select>
      </form>
    </div>
</script>
like image 897
Keith Rousseau Avatar asked Mar 29 '12 00:03

Keith Rousseau


People also ask

How do you set the select box value?

The default value of the select element can be set by using the 'selected' attribute on the required option. This is a boolean attribute.

How do you get the selected value of an element?

The value of the selected element can be found by using the value property on the selected element that defines the list. This property returns a string representing the value attribute of the <option> element in the list. If no option is selected then nothing will be returned.

What are handlebars in Javascript?

Handlebars. js is a Javascript library used to create reusable webpage templates. The templates are combination of HTML, text, and expressions. The expressions are included in the html document and surrounded by double curly braces.


4 Answers

If you don't want to build out the option as part of the helper, you can use a combination of a small custom handlebars helper and parent context, denoted using the ../ syntax:

First write the helper:

Handlebars.registerHelper('selected', function(option, value){
    if (option === value) {
        return ' selected';
    } else {
        return ''
    }
});

And then in your template you call your helper and pass in the parent context inside the each loop to check for selectedState

{{#each states}}
    <option value="{{this}}" {{selected this ../selectedState}}>{{this}}</option>
{{/each}}
like image 148
Matt Waldron Avatar answered Jan 25 '23 17:01

Matt Waldron


I took the {{#each}} helper as inspiration, and wrote a custom helper that does the same thing: loops over a list, and continually appends the contents of the arguments to an output string. (From here: Handlebars block helpers)

In this case, I'm not passing in a chunk of template HTML to serve as the function's options parameter, like you would when using {{#each}}. Instead I am just building up the <option> tags by brute force, and testing every iteration of the context list. Lastly, I return a big long string of <option></option> tags, and hopefully one of them has selected="selected".

The function:

Handlebars.registerHelper('options_selected', function(context, test) {
    var ret = '';
    for (var i = 0, len = context.length; i < len; i++) {
        var option = '<option value="' + context[i]+'"';
        if (test.toLowerCase() == context[i].toLowerCase()) {
            option += ' selected="selected"';
        }
        option += '>'+ Handlebars.Utils.escapeExpression(context[i]) + '</option>';
        ret += option;
    }

    return new Handlebars.SafeString(ret);
});

The tag in use:

<script id="form-state" type="text/x-handlebars-template">
    <select name="state">
    {{{options_selected states selectedState}}}
    </select>
</script>

Please suggest any edits that would improve this, thanks!

like image 38
Ari Lacenski Avatar answered Jan 25 '23 18:01

Ari Lacenski


You can use values straight in the Handlebars template like so.

Handlebars Template

<select id="distance">
        <option value="15" {{#if (isEqual 15 distance)}} selected {{/if}}>15</option>
        <option value="25" {{#if (isEqual 25 distance)}} selected {{/if}}>25</option>
        <option value="50" {{#if (isEqual 50 distance)}} selected {{/if}}>50</option>
        <option value="100" {{#if (isEqual 100 distance)}} selected {{/if}}>100</option>
        <option value="300" {{#if (isEqual 300 distance)}} selected {{/if}}>300</option>
</select>

Handlebars Helper

define(['hbs/handlebars'], function (Handlebars) {
  'use strict';

  Handlebars.registerHelper('isEqual', function (expectedValue, value) {
    return value === expectedValue;
  });
});
like image 30
Stacker-flow Avatar answered Jan 25 '23 16:01

Stacker-flow


Here is a solution (built over EmberJS to ease the JS part)

I refactored your sample a little, to have objects for proposed values, which can by the way carry the selected attribute...

The template part:

<script type="text/x-handlebars" data-template-name="my-template">
    <div id="my-modal">
      <form action="/TestAction" method="post">
        <input id="MyId" name="MyId" type="hidden" value="{{MyId}}" />      
        <label for="Test">Test: (optional)</label>
        <select id="Test" name="Test">
          <option value="">-- Choose Test --</option>
          {{#each values}}
              <option {{bindAttr value="id" selected="selected"}}>{{label}}</option>
          {{/each}}
        </select>
      </form>
    </div>
</script>

The JS part:

App.MyView = Ember.View.extend
    templateName: 'my-template'

    MyId: 42
    values: [{
        id: 1,
        label: '1'
    }, {
        id: 2,
        label: '2'
    }, {
        id: 3,
        label: '3',
        selected: true
    }, {
        id: 4,
        label: '4'
    }]

You can try it @ http://jsfiddle.net/MikeAski/uRUc3/

like image 24
Mike Aski Avatar answered Jan 25 '23 18:01

Mike Aski