With a Handlebars.js template like this...
@lazd's answer does not work for <option>
elements within an <optgroup>
.
selectedIndex
is numbered monotonically for all <option>
s, but select.children
holds the <optgroup>
s, and select.children[n].children
holds the <option>
s within <optgroup>
n (with numbering restarting within each <optgroup>
, of course).
This alternative version will work for <option>
elements within <optgroup>
s:
Handlebars.registerHelper('select-optgrp', function(value, options) {
var select = document.createElement('select'); // create a select element
select.innerHTML = options.fn(this); // populate it with the option HTML
select.value = value; // set the value
var g = 0, i = select.selectedIndex; // calculate which index of which optgroup
while (i >= select.children[g].children.length) { i -= select.children[g].children.length; g++; }
if (select.children[g].children[i]) { // if selected node exists add 'selected' attribute
select.children[g].children[i].setAttribute('selected', true);
}
return select.innerHTML;
});
Another one solution using express-handlebars
and dynamic options is this.
Helper function (From all options takes the one we want and change it to selected).
select: function(selected, options) {
return options.fn(this)
.replace( new RegExp(' value=\"' + selected + '\"'), '$& selected="selected"')
.replace( new RegExp('>' + selected + '</option>'), ' selected="selected"$&');
}
handlebars file (I just use #each inside select to receive me data and worked like a charm).
<select name="justAname">
{{#select content.campusId}}
{{#each campus}}
<option value="{{id}}">{{name}}</option>
{{/each}}
{{/select}}
</select>
I prefer to use a template approach. By this I mean the layout of the option tag itself is specified in the handlebars template (where someone might look for it) and not in the javascript helper. Template inside the block helper is passed into the helper script and can be used by calling options.fn() which then uses any script changes you have made in your helper.
Template:
<select>
{{#optionsList aStatusList sCurrentStatusCode 'statusCode'}}
<option {{isSelected}} value="{{statusCode}}">{{statusName}}</option>
{{/optionsList}}
</select>
Slightly modified data (not required but a little more "real world" for me)
var myOrder =
{
"id" : 1,
"name" : "World",
"statusName" : "OverDue", /* status should NOT be here! */
"statusCode" : "1",
"date" : "2012-12-21"
}
var sCurrentStatusCode = myOrder.statusCode;
var aStatusList =
[
{
"statusName" : "Node",
"statusCode" : 0
},
{
"statusName" : "Overdue",
"statusCode" : 1
},
{
"statusName" : "Completed",
"statusCode" : 2
},
{
"statusName" : "Sent to Payer",
"statusCode" : 3
}
]
Javascript registered helper:
Handlebars.registerHelper( 'optionsList',
function ( aOptions, sSelectedOptionValue, sOptionProperty, options )
{
var out = "";
for ( var i = 0, l = aOptions.length; i < l; i++ )
{
aOptions[ i ].isSelected = '';
if( ( sOptionProperty != null && sSelectedOptionValue == aOptions[ i ][ sOptionProperty ] ) || ( sSelectedOptionValue == aOptions[ i ] ) )
{
aOptions[ i ].isSelected = ' selected="selected" ';
}
out = out + options.fn( aOptions[ i ] );
}
return out;
} );
optionsList is what I have chosen to name this helper
aStatusList an array of status objects contain several properties including the status value/name (in most cases I have encountered this would be the status code not the status name that is stored )
sCurrentStatus is the previously selected status code (not the value) and is the option value that i would like to have the selected in this generated option list.
statusCode is the string property name within a aStatusList object that I will test to see if it matches myStatus that is aStutusList[ loopIndex ][statusCode]
If you have very few options and you don't want to write a helper, here is what you can do:
//app.js
var data = {selectedVal: 'b'};
// can also use switch ... case ...
if (data.selectedVal === 'a') {
data.optionASelected = true;
} else if (data.selectedVal === 'b') {
data.optionBSelected = true;
}
// assuming you have a template function to handle this data
templateFunc(data);
In your template file:
<!-- template.html -->
<select id="select-wo-helper" >
<option value="a" {{#if optionASelected}} selected {{/if}}>A</option>
<option value="b" {{#if optionBSelected}} selected {{/if}}>B</option>
</select>
Again this may NOT be the best solution of all, but it probably is a very quick work around when you are dealing very few options and wanted a quick fix.
Handlebars.registerHelper('select', function( value, options ){
return options.fn(this)
.replace( new RegExp(' value=\"' + value + '\"'), '$& selected="selected"')
.replace( new RegExp('>' + value + '</option>'), ' selected="selected"$&');
});
user.country from db session
country stored in country.json file
<select id="country" name="country" class="form-control">
<option value="" selected="selected">(please select a country)</option>
{{#select user.country}}
{{#each countries as |value key| }}
<option value="{{ value.code }}">{{ value.name }}</option>
{{/each}}
{{/select}}
</select>