12

Is it possible to pass a JavaScript object/hash into a Handlebars helper call? I'd like to do something like this:

<label>Label here</label>
{{#textField {'id':'text_field_1', 'class':'some-class', size:30} }}{{/textField}}
<p>Help text here.</p>

Here is a jsFiddle. Currently it produces the following error

Uncaught Error: Parse error on line 3:
...bel>  {{#textField {'id':'text_field_1'
----------------------^
Expecting 'CLOSE', 'CLOSE_UNESCAPED', 'STRING', 'INTEGER', 'BOOLEAN', 'ID', 'DATA', 'SEP', got 'INVALID' 

Alternatively I could probably do this and split on ',', but I am not fond of the syntax:

{{#textField "'id'='text_field_1','class'='some-class',size=30"}}{{/textField}}

NOTE: I specifically do NOT want to pass data/attributes (id, class, size, etc.) into the template() method as a JSON object. I want everything in the template.

Chad Johnson
  • 18,956
  • 30
  • 98
  • 192

2 Answers2

14

Solved. I did this:

Helper:

Handlebars.registerHelper('textField', function(options) {
    var attributes = [];

    for (var attributeName in options.hash) {
      attributes.push(attributeName + '="' + options.hash[attributeName] + '"');
    }

    return new Handlebars.SafeString('<input type="text" ' + attributes.join(' ') + ' />');
});

And the template:

<label>Label here</label>
{{textField id="text_field_1" class="some-class" size="30" data-something="data value"}}
<p>Help text here.</p>

Per the documentation (bottom of the page), you can pass in a variable number of parameters to a helper method, and they will be available in options.hash (assuming "options" is a parameter to your helper method). And what's also nice about this is that you can use named parameters, and parameter order doesn't matter.

Chad Johnson
  • 18,956
  • 30
  • 98
  • 192
  • 1
    How can we pass a text&value dynamically?. Tried the following but this couldn't workout. Anyway? `{{textField id="text_field_1" class="some-class" size="30" data-something="data value"{{this.number}} }}` Actually i need to append value to data-attribute with text – Newbie Aug 19 '16 at 09:58
10

I found another best way to pass objects.

Template:

{{textField dataAttribs='{"text":"Hello", "class": "text-field"}'}}

Helper:

Handlebars.registerHelper('textField', function(options) {
    var attribs;

    attribs = JSON.parse(options.hash.dataAttribs);
    console.log(attribs.text + " -- " + attribs.class);
    ......
    ........
});

JSFiddle for this

user10
  • 4,826
  • 6
  • 38
  • 61
  • +1 for retaining the hash mapping as originally asked for by the poster — though I tend to like the API of the accepted answer a bit more as it mimics HTML attributes. – srquinn Jun 29 '14 at 23:38
  • 1
    The accepted answer works best when you know the keys upfront. If you don't, this is a decent workaround. – mynameistechno Mar 13 '15 at 21:28