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>
The default value of the select element can be set by using the 'selected' attribute on the required option. This is a boolean attribute.
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.
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.
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}}
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!
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;
});
});
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With