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

前端 未结 4 1090
感动是毒
感动是毒 2020-12-19 06:48

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,

相关标签:
4条回答
  • 2020-12-19 07:29

    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>
    
    0 讨论(0)
  • 2020-12-19 07:32

    My own solution is:

    helper:

    Handlebars.registerHelper ("setRadio", function (value, options) {
        var $el = $(options.fn(this));
        if ( value == $el.val() ) {
           return $el.attr("checked", "checked")[0].outerHTML;
        } else {
           return options.fn(this);
        }
    

    Usage in template:

                {{#setRadio stars}}<input class="star-rating__input" id="{{id}}-star-rating-5" type="radio" name="{{id}}" value="5" >{{/setRadio}}
                <label class="star-rating__ico fa fa-star-o fa-lg" for="{{id}}-star-rating-5" title="5 out of 5 stars"></label>
    
                {{#setRadio stars}}<input class="star-rating__input" id="{{id}}-star-rating-4" type="radio" name="{{id}}" value="4">{{/setRadio}}
                <label class="star-rating__ico fa fa-star-o fa-lg" for="{{id}}-star-rating-4" title="4 out of 5 stars"></label>
    
                {{#setRadio stars}}<input class="star-rating__input" id="{{id}}-star-rating-3" type="radio" name="{{id}}" value="3">{{/setRadio}}
                <label class="star-rating__ico fa fa-star-o fa-lg" for="{{id}}-star-rating-3" title="3 out of 5 stars"></label>
    
                {{#setRadio stars}}<input class="star-rating__input" id="{{id}}-star-rating-2" type="radio" name="{{id}}" value="2">{{/setRadio}}
                <label class="star-rating__ico fa fa-star-o fa-lg" for="{{id}}-star-rating-2" title="2 out of 5 stars"></label>
    
                {{#setRadio stars}}<input class="star-rating__input" id="{{id}}-star-rating-1" type="radio" name="{{id}}" value="1">{{/setRadio}}
                <label class="star-rating__ico fa fa-star-o fa-lg" for="{{id}}-star-rating-1" title="1 out of 5 stars"></label>
    
    0 讨论(0)
  • 2020-12-19 07:39

    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

    0 讨论(0)
  • 2020-12-19 07:45

    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}}.

    0 讨论(0)
提交回复
热议问题