How to set selected select option in Handlebars template

前端 未结 17 2082
猫巷女王i
猫巷女王i 2020-12-12 12:55

With a Handlebars.js template like this...


                        
    
提交评论

  • 2020-12-12 13:38

    Improved answer of @lazd to select first option when nothing matches.

    Handlebars.registerHelper('select', function(value, options) {
        // Create a select element 
        var select = document.createElement('select');
    
    
    // Populate it with the option HTML
    $(select).html(options.fn(this));
    
    //below statement doesn't work in IE9 so used the above one
    //select.innerHTML = options.fn(this); 
    
        // Set the value
        select.value = value;
    
        // Find the selected node, if it exists, add the selected attribute to it
        if (select.children[select.selectedIndex]) {
            select.children[select.selectedIndex].setAttribute('selected', 'selected');
        } else { //select first option if that exists
            if (select.children[0]) {
                select.children[0].setAttribute('selected', 'selected');
            }
        }
        return select.innerHTML;
    });
    

    Usage remains same:

    <select>
        {{#select status}}
        <option>Option 1</option>
        <option>Option 2</option>
        <option value="Option 3">Option 3 (extra info)</option>
        <option value="Option 4">Option 4 (more extra)</option>
        {{/select}}
    </select>
    
    0 讨论(0)
  • 2020-12-12 13:39

    This might take more code in the template, but it is easier to read:

    .js

    Handlebars.registerHelper('select', function(selected, option) {
        return (selected == option) ? 'selected="selected"' : '';
    });
    

    .hbs

    <select name="status">
        <option value="public" {{{select story.status 'public'}}}>Public</option>
        <option value="private" {{{select story.status 'private'}}}>Private</option>
        <option value="unpublished" {{{select story.status 'unpublished'}}}>Unpublished</option>
    </select>
    
    0 讨论(0)
  • 2020-12-12 13:43

    I know this does not answer the question directly, but in this situation, I passed the unselected html options to the template, and after it is rendered, I use jquery to mark as selected the value that the json object indicates

    0 讨论(0)
  • 2020-12-12 13:44

    I saw the extremely clever solution posted by @janjarfalk and realized it didn't work for options defined without a value attribute (such as <option>Value</option>). My application needed that, and I wanted a helper done in vanilla JavaScript for performance, so I came up with the following.

    This solution will support <option>Both a label and a value</option> in addition to <option value="aValue">A label</option> and will be much faster as it doesn't use jQuery.

    Handlebars.registerHelper('select', function(value, options) {
        // Create a select element 
        var select = document.createElement('select');
    
        // Populate it with the option HTML
        select.innerHTML = options.fn(this);
    
        // Set the value
        select.value = value;
    
        // Find the selected node, if it exists, add the selected attribute to it
        if (select.children[select.selectedIndex])
            select.children[select.selectedIndex].setAttribute('selected', 'selected');
    
        return select.innerHTML;
    });
    

    Usage:

    <select>
        {{#select status}}
        <option>Option 1</option>
        <option>Option 2</option>
        <option value="Option 3">Option 3 (extra info)</option>
        <option value="Option 4">Option 4 (more extra)</option>
        {{/select}}
    </select>
    
    0 讨论(0)
  • 2020-12-12 13:46

    I just ran into this problem, here's a solution for when the options are dynamic..

    Instead of creating a select helper, I created an option helper that accepts the value of the item you wish to be selected.

    Handlebars.registerHelper('option', function(value) {
      var selected = value.toLowerCase() === (this.toString()).toLowerCase() ? 'selected="selected"' : '';
      return '<option value="' + this + '" ' + selected + '>' + this + '</option>';
    });
    

    And in my template.

    {{#items}}
        {{{option ../selected_value}}}
    {{/items}}
    

    Please note the ../ to access the parent's scope as it's not likely the selected_value will be inside of the items array.

    Cheers.

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