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('{"id":5,"publisher":null,"message":" asdadsad","address":"asdad","published":"
Last Saturday at 12:00 AM","createdAt":"2015-07
23T09:55:35.486Z","updatedAt":"2015-07-23T09:55:35.486Z"}')"
(Broken over multiple lines for your convenience).
Now I just have to find out of to get that JSON to look right.
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, '"');
});
And this will result as
<button onclick="myGreatFunction({"foo":"bar"})"></button>
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.
Related
Im trying to add data to a JSON object, stored in session. I do this with a js function:
<section class="products">
#foreach (var prod in Model) {
string path = "~/images/" + prod.ImgURL;
<article>
<a href="#Url.Action("InspectProduct","Products", new {productID = prod.Id})">
<img src="#Url.Content(path)" style="max-width: 75%"></a>
<h3>#prod.Name</h3>
<h4>#prod.Price,-</h4>
<a class="btn-add" style="cursor: pointer;" onclick="addToJSONObject(#prod.Id, #prod.Name, #prod.Price, #prod.Info)">Tilføj til kurv</a>
</article>
}
</section>
Im using MVC hence the "#" from the Viewbag.
When i click the "button" it throws: "Uncaught SyntaxError: missing ) after argument list" on almost every products tag.
It worked fine until i started adding more parameters to the function. Any ideas what could be wrong? I dont seem to be missing any ")" or escapes.
You found a very basic concept called "context switch".
If you look at this line:
"#Url.Action("InspectProduct","Products")"
You'll find the the first " initiates your html attribute context. It should be ended by another ". However there are four " in between serving other purposes. Namely, they start/end a parameter value context.
There is no way for the interpreter to differentiate those ". Thus, the syntax error.
Please read about the problem and how you would fix it in your programming language. Sometimes it is escaping (e.g. \"), sometimes it is using different string literals (e.g. ').
When using Razorviews in ASP.NET MVC, the # will allow you to write c# code directly into HTML. The call to the view-bag data in the foreach-loop is done with:
addToJSONObject(#prod.Id, #prod.Name, #prod.Price, #prod.Info)
However, this will not insert " or '
Therefore the correct way to use model data as a parameter (if string is required):
addToJSONObject('#prod.Id', '#prod.Name', '#prod.Price', '#prod.Info')
I'm trying to pass a PHP json_encoded object to a function which accepts 2 parameters. But when it's rendered on the browser it kept saying that there's
On Firefox's Inspector:
SyntaxError: missing ) after argument list
On Chrome's Inspector:
Uncaught SyntaxError: Unexpected end of input
Code:
<td>
Edit
</td>
Source Code On Browser:
<td>
Edit
</td>
I tried adding \'' but didn't help. Maybe I'm doing it wrong. I've been on this since last night so I think I need to ask now.
I clear the browser's cache everytime I test but I get the same result. There are similar questions but I tried them but won't fix my problem.
I'd appreciate any help.
All you gotta do is change the quote. from " to ' for the onclick function.
browser read your HTML as
Edit
when you want to read it as
<a href="#" onclick='showEditModal({"id":2,"title":"Announcement 1","content":"Announcement 1 Content","dateAdded":"2018-04-24 14:44:27"})'>Edit</a>
Check the difference in syntax highlight.
Hence why you got the
SyntaxError: missing ) after argument list
But like #CertainPerformance mentioned. It is better to not write it as inline functions. set the value as a JS object and use it while executing the function. Avoid inline-functions as much as possible.
Inline event handlers are essentially eval inside HTML markup - they're bad practice and result in poorly factored, hard-to-manage code, especially if you're trying to write into them on the fly with PHP like that. Seriously consider attaching your events with JavaScript, instead, eg: https://developer.mozilla.org/en/DOM/element.addEventListener
To send data from the server to the client, you should either use data- attributes, application/json, or a network request. For example, taking the application/json route, you would do something like the following:
<td>
Edit
<script type="application/json">
<?= json_encode($value, JSON_HEX_APOS) ?>
</script>
</td>
Javascript:
// (select the `a` referenced above)
a.addEventListener('click', () => {
const parsedObj = JSON.parse(a.nextElementSibling.textContent);
showEditModal(parsedObj);
});
I am getting some really weird syntax errors [Uncaught SyntaxError: Unexpected identifier] for seemingly normal code.
Getting an error if I write anything after the 1st line in the else block..
if (classlist.length == 0) {
lastClickCatID = -1;
}
else {
lastClickCatID = +classlist.value.split('-')[1];
// **Getting error if I write anything here, even for comments like this**
}
Getting the error if I just use two words in the comment (with a space between them). And of course getting error for any JS statements, even basic console logs.
Also, getting an error for a console.log line in the following code which has been commented out (the 4th line: console.log-"UNDO"):
// Push this data into the undo array
undo.push([lastClickDivID, lastClickCol, lastClickRow, lastClickCatID, nextClickCatID]);
//console.log("UNDO", undo[0][0], undo[0][1], undo[0][2], undo[0][3], undo[0][4]); // *Getting error if I include this line*
console.log(undo.pop());
Getting an error with or without the comment tag. But if I remove the entire line, it works fine.
I have another line:
nextClickCatID = +id2;
Again getting errors for doing a console.log of the variable. But it works fine if I remove the '+' and just use next 'nextClickCatID = id2; '.
Also getting many other weird errors like that within this function (it will get too long if I include them). Any idea why I am getting errors like these for seemingly normal code?
I have solved it. It strangely worked when I removed the space between the () and the curly brackets in the jquery document ready function. Changed from...
$(function() {
to:
$(function(){ // with no space between the parentheses and the curly brackets
I want to add that - it was working fine before with the same structure (with space in between brackets) all this while. But suddenly decided to give an error today in a particular function. If somebody can clarify why this happened, it will still be very relevant.
I have a very specific problem concerning a regular expression matching in Javascript. I'm trying to match a piece of source code, more specifically a portion here:
<TD WIDTH=100% ALIGN=right>World Boards | Olympa - Trade | <b>Bump when Yasir...</b></TD>
The part I'm trying to match is boardid=106121">Olympa - Trade</a>, the part I actually need is "Olympa". So I use the following line of JS code to get a match and have "Olympa" returned:
var world = document.documentElement.innerHTML.match('/boardid=[0-9]+">([A-Z][a-z]+)( - Trade){0,1}<\/a>/i')[1];
the ( - Trade) part is optional in my problem, hence the {0,1} in the regex.
There's also no easier way to narrow down the code by e.g. getElementsByTagName, so searching the complete source code is my only option.
Now here's the funny thing. I have used two online regex matchers (of which one was for JS-regex specifically) to test my regex against the complete source code. Both times, it had a match and returned "Olympa" exactly as it should have. However, when I have Chrome include the script on the actual page, it gives the following error:
Error in event handler for 'undefined': Cannot read property '1' of null TypeError: Cannot read property '1' of null
Obviously, the first part of my line returns "null" because it does not find a match, and taking [1] of "null" doesn't work.
I figured I might not be doing the match on the source code, but when I let the script output document.documentElement.innerHTML to the console, it outputs the complete source code.
I see no reason why this regex fails, so I must be overlooking something very silly. Does anyone else see the problem?
All help appreciated,
Kenneth
You're putting your regular expression inside a string. It should not be inside a string.
var world = document.documentElement.innerHTML.match(/boardid=[0-9]+">([A-Z][a-z]+)( - Trade){0,1}<\/a>/i)[1];
Another thing — it appears you have a document object, in which case all this HTML is already parsed for you, and you can take advantage of that instead of reinventing a fragile wheel.
var element = document.querySelector('a[href*="boardid="]');
var world = element.textContent;
(This assumes that you don't need <=IE8 support. If you do, there remains a better way, though.)
(P.S. ? is shorthand for {0,1}.)
First of all, I've done my research and I did find a bunch of simialr questions. However, I didn't find an answer that applies to my problem. All the examples I found were related to unescaped characters, single/double quote mishaps and the like. I on the other hand am getting this error on the following function:
$('.seq_input').blur(function(){
//var id = $(this).data('id');
//var index = parseInt($(this).val()),
//element = $("#test-list li").eq(id).remove();
//$("#test-list li").eq(index - 1).before(element); // -1 because users like 1 based indices
alert('what?');
});
As you see I commented out everything and just left an alert, and I'm still getting the error, pointing to the last line of the function. It couldn't have anything to do with other functions because I just added this one alone at the end of my current Javascript.
Can someone please tell me what's going on here? Why on Earth would a function that just alerts something (or even if it doesn't do anything) give an error?
NOTE: error is shown as soon as the page is loaded
There are invisible characters between the trailing semicolon and the parenthesis. I concatenated your code, put it in a string, and called a non-existent function in order to trigger a error (using this method).
'});'.l()
>>> TypeError: "})\u200B\u200B\u200B;".l is not a function
$('.seq_input') may used on the other functions, try using new id to do that function.