3

I'm building a simple webapp with just Handlebars.js and some jQuery.

Now I have a list of data, and i present them through a Handlebars-template. Then I want some actions associated with these, e.g. update one element, or delete one. I have buttons that one associates with these actions, the problem is that I cannot manage to get onclick-methods associated with buttons in the template to work.

I read this question and answer, which lead me to adding the extra bracket and helpermethod, but it still doesn't work. See code below.

Handlebars.registerHelper('json', function(context) {
    return JSON.stringify(context);
});

var myGreatFunction = function(someValue) {
    // Work with that value 
}

The template:

{{#each Something}}
    <button onclick="myGreatFunction({{{json this}}})"></button>
{{/each}}

Now, doing it like this give me Uncaught SyntaxError: missing ) after argument list at the top of the HTML-file.

I noted the answer here, so I tried with onclick="myGreatFunction( '{{{json this}}}' )" which gives me the error Uncaught SyntaxError: Unexpected token ILLEGAL at the end of HTML-file.

With onclick="myGreatFunction( '{{json this}}' )" the button simply disappears on click.

Does anyone see something I've missed, or is there another way of doing this? I thought of adding the object to some div/button in the template, then add a jQuery-listener for the click that fetches the value from the template, but that seems so ugly and unclear.

Any tips? All help is greatly appreciated - thanks in advance.

UPDATE: Seems the problem is, as Hacketo mentioned below, that the outputted JSON is kind of messed up. I inspected an element in my code:

onclick="someFunc('{&quot;id&quot;:5,&quot;publisher&quot;:null,&quot;message&quot;:&quot; asdadsad&quot;,&quot;address&quot;:&quot;asdad&quot;,&quot;published&quot;:&quot
Last Saturday at 12:00 AM&quot;,&quot;createdAt&quot;:&quot;2015-07
23T09:55:35.486Z&quot;,&quot;updatedAt&quot;:&quot;2015-07-23T09:55:35.486Z&quot;}')"

(Broken over multiple lines for your convenience).

Now I just have to find out of to get that JSON to look right.

Community
  • 1
  • 1
Esso
  • 694
  • 4
  • 8
  • 21
  • maybe missing a `"` in `onclick="myGreatFunction()"` ? – Hacketo Jul 24 '15 at 07:29
  • @Hacketo Ah, sorry. That's a typo in my example here, sorry. Fixing now, thanks! =) – Esso Jul 24 '15 at 07:30
  • this typo also throw that same error. – Hacketo Jul 24 '15 at 07:31
  • @Hacketo Hm, I see. I had to double check in my project, and I've remembered it there . Tried all the things mentioned above (it's a new day and all), making sure I didn't miss the `"` and they threw the same errors as before. Thanks for the tip, though! – Esso Jul 24 '15 at 07:41
  • this is exactly the same example I guess : http://stackoverflow.com/questions/26642048/pass-object-as-parameter-to-onclick-method-in-handlebars-template – Hacketo Jul 24 '15 at 07:46
  • Well I know what's happening, it's because `JSON.stringify` return JSON, and JSON contains double quote `"`. so your template become this invalid HTML `` – Hacketo Jul 24 '15 at 07:51
  • @Hacketo Yeah, I saw that question. When I use `onclick=someFunc({{json this}})` and a helper as in my question (the same method as the one above), but then my buttons just disappear on click. ..Which probably makes sense given your second comment. Those strings may be making the HTML invalid completely? – Esso Jul 24 '15 at 07:55
  • Do you want a string parameter or an object ? Your first template `myGreatFunction({{{json this}}})` use an object as parameter, not a JSON string – Hacketo Jul 24 '15 at 08:31
  • I want `myGreatFunction` to get a JSON-object to work with. – Esso Jul 24 '15 at 08:34
  • So you can keep your first template `myGreatFunction({{{json this}}})` and use my answer. If you wrap the parameter with `'` it will give an escaped string representation of the JSON and you don't want this. – Hacketo Jul 24 '15 at 08:36
  • Where exactly is this "myGreatFunction()" defined in your code. For me , the code is never able to find this function and always complains of an undefined function. – Roshan Khandelwal Nov 04 '16 at 08:47

2 Answers2

3

This is because JSON.stringify return a JSON string and contains ".

At the moment, your template may look like this:

<button onclick="myGreatFunction({{{json this}}})"></button>

Compiled :

<button onclick="myGreatFunction({"foo":"bar"})"></button>
                ^                 ^   ^ ^   ^  ^

And this result as

Uncaught SyntaxError: missing ) after argument list


You need to escape those " and you can do this in your helper

Handlebars.registerHelper('json', function(context) {
    return JSON.stringify(context).replace(/"/g, '&quot;');
});

And this will result as

<button onclick="myGreatFunction({&quot;foo&quot;:&quot;bar&quot;})"></button>
Hacketo
  • 4,978
  • 4
  • 19
  • 34
  • Thanks! Changed the helper, but the JSON written to document still looks wrong, and the buttons disappears on click. – Esso Jul 24 '15 at 08:35
  • 1
    Update your answer to mention `myGreatFunction({{{json this}}})`, because others may be as slow as I was (or not, but just to be sure). Thanks! The HTML returned to the document is correct now, but the buttons still just disappear though, but something else might cause' it. – Esso Jul 24 '15 at 08:40
  • Stupidly I had named the function `remove`, which of course removed the button on click. Everything works now, thanks a bunch! – Esso Jul 24 '15 at 09:01
0

Just take out the extra bracket. If you let Handlebars do HTML escaping (which it will automatically on a regular {{json this}} invocation), it will also escape the quotes for you.

Blank
  • 101
  • 1