Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the selected item in a radio button group in handlebars template?

In a handlebars template, how do you set a radio button group to the right value using only the template? Can this be done directly in the template?

For an example, let's say there's a radio button group like this:

<label><input type="radio" name="mode" value="auto">Auto</label><br>
<label><input type="radio" name="mode" value="on">On</label><br>
<label><input type="radio" name="mode" value="off">Off</label><br>

The data coming into the template has a value for mode:

{mode: "on"}

I want to end up with this after template expansion:

<input type="radio" name="mode" value="auto">Auto<br>
<input type="radio" name="mode" value="on" checked>On<br>
<input type="radio" name="mode" value="off">Off<br>

So that the HTML in the form initially shows the "on" value being selected.

like image 903
jfriend00 Avatar asked Sep 26 '14 19:09

jfriend00


3 Answers

You can write a helper function to help you with this use case. I like to keep all my block helpers in a designated JS file - but you can put them anywhere inside your scripts.

Handlebars.registerHelper ("setChecked", function (value, currentValue) {
    if ( value == currentValue ) {
       return "checked";
    } else {
       return "";
    }
 });

and in your template you would use it like this:

<label><input type="radio" name="mode" value="auto" {{{setChecked auto mode}}}>Auto</label><br>
<label><input type="radio" name="mode" value="on" {{{setChecked on mode}}}>On</label><br>
<label><input type="radio" name="mode" value="off" {{{setChecked off mode}}}>Off</label><br>

This should work.

This link is a good starting point to block helpers: http://handlebarsjs.com/block_helpers.html

like image 62
Birgit Martinelle Avatar answered Sep 18 '22 23:09

Birgit Martinelle


Late addition for anyone else wanting the same: this works (quotes, undefined values, and all):

Handlebars.registerHelper('checked', function(value, test) {
    if (value == undefined) return '';
    return value==test ? 'checked' : '';
});

Assuming a variable with the name of the input is passed to the Handlebars context, it is used as:

<input type="radio" name="mode" value="auto" {{checked mode 'auto'}}>Auto<br>
<input type="radio" name="mode" value="on" {{checked mode 'on'}}>On<br>
<input type="radio" name="mode" value="off" {{checked mode 'off'}}>Off<br>

Alternatively...

If you don’t like having the helper calls in each input, you could wrap the inputs in a helper as follows:

Handlebars.registerHelper('checked', function(value, options) {
    const div = document.createElement('div'); // create a container div
    div.innerHTML = options.fn(this);          // parse content into dom
    div.querySelectorAll('input[type=radio]').forEach(function(input) {
        // if input has value matching supplied value, check it
        if (input.value == value) input.defaultChecked = true;
    });
    return div.innerHTML;
});

Which would then be used as follows:

{{#checked mode}}
<input type="radio" name="mode" value="auto">Auto<br>
<input type="radio" name="mode" value="on">On<br>
<input type="radio" name="mode" value="off">Off<br>
{{/checked}}

Note a slightly different approach would be required for checkboxes, as they can have multiple values set.

Remember helpers take precedence over context variables, so if you had an input named ‘checked’, you would have to use a path reference e.g. {{./checked}}.

like image 45
ChrisV Avatar answered Sep 21 '22 23:09

ChrisV


I really liked the answer from ChrisV, once I understood it. I really struggled to get there from here. Please consider this a supporting comment to the answers above. I will say my use case was a tiny bit different. I'm using Express and I wanted to set the checkbox from a route. It wasn't totally clear to me how to call the helper function. Obviously, I'm using two different radio button groupings.

In app.js, where I initially setup the view engine

var hbs = require('hbs');
hbs.registerPartials(__dirname + '/views/partials');
hbs.registerHelper('checked', function (value, test) {
  if (value == undefined) return '';
  return value == test ? 'checked' : '';
});
app.set('view engine', 'hbs');

I set the route in index.js

var express = require('express');
var router = express.Router();
router.get('/display_form', function (req, res, next) {
//... play with data.  use req.query.optionsRadiosA, etc...
//  var outputA = "video"
    res.render('formpage', {
        title: 'Setup Page',
        optionsRadiosA: outputA,    // use variable
        optionsRadiosB: 'Audio'     // or use string
    });
});

and finally, my template, formpage.hbs (extract shown...)

<h1>{{title}}</h1>
<form class="pure-form">
    <h2>Channel A Setup</h2>           
    <label for="option-A1">
         <input id="option-A1" type="radio" name="optionsRadiosA" value="Video" {{checked optionsRadiosA 'Video'}}> Video
    </label>
    <label for="option-A2">
        <input id="option-A2" type="radio" name="optionsRadiosA" value="Audio" {{checked optionsRadiosA 'Audio'}}> Audio
    </label>
    <h2>Channel B Setup</h2>
    <label for="option-B1">
        <input id="option-B1" type="radio" name="optionsRadiosB" value="Video" {{checked optionsRadiosB 'Video'}}> Video
    </label>
    <label for="option-B2">
         <input id="option-B2" type="radio" name="optionsRadiosB" value="Audio" {{checked optionsRadiosB 'Audio'}}> Audio
    </label>
    <input type="submit" value="Update the Channel Feeds">
</form>
like image 31
zipzit Avatar answered Sep 18 '22 23:09

zipzit