js syntax error: missing ) after argument - javascript

I am not sure what is wrong.
cell1.innerHTML = '<a onclick="displaySteps(\'' + temp + '\')" id="testSteps"><i class="fa fa-plus-circle fa-custom fa-clickable"></i></a>' + " N/A";
Executing the above line always gives me the following error
SyntaxError: missing ) after argument list[Learn More]

Since you have missing ) after argument list error and the only function call in the above code is displaySteps, I would assume there is something within the rendered value of the test variable that's causing it. Try logging the value of test to ensure it doesn't contain any stray ) or unescaped characters
Also, a cleaner way to do this would be with Template Literals-
const icon = `<i class="fa fa-plus-circle fa-custom fa-clickable"></i>`
const renderDisplayFn = (arg) => `'displaySteps(${arg})'`
cell1.innerHTML = `<a onclick=${renderDisplayFn(test)} id='testSteps'>${icon}</a> N/A`

There's probably a quote in temp that's causing a syntax error in the function call.
Rather than creating an onclick attribute, it would be safer to add the event listener with code.
cell1.innerHTML = '<a o id="testSteps"><i class="fa fa-plus-circle fa-custom fa-clickable"></i></a>' + " N/A";
document.getElementById("testSteps").addEventListener("click", (function(temp) {
displaySteps(temp);
})(temp));

cell1.innerHTML = `<a onclick="displaySteps('${temp}')" id="testSteps"><i class="fa fa-plus-circle fa-custom fa-clickable"></i></a> N/A`;

Related

Cannot Copy Text With Dynamically Created Button

I have the following function for copying a string of text:
function copyText(str) {
console.log(str);
let tmp = $('<input type="text">').appendTo(document.body);
tmp.val(str.toString() );
tmp.select();
document.execCommand('copy');
tmp.remove();
}
This function works fine, both when called from the console and when called from a button press.
I have a function that copies a color:
function copyColor(elm) {
let hex = $(elm.parentElement).find('span').html();
console.log('copyText("' + hex + '")' );
copyText(hex);
}
This function is called when a button is pressed. The button passes itself as the parameter. I am dynamically creating the buttons (each one represents a new "color item"). Here is the HTML that is dynamically inserted with jQuery:
'<button class="btn copy-btn no-color" title="Copy" data-toggle="popover" onclick="copyColor(this);"><i class="fas fa-copy"></i></button>'
The whole thing is:
$('#' + mode + '-modal .modal-body').prepend(
'<div class="' + mode + '-item color-item">'
+ '<button class="btn open-btn no-color" title="Open Color" data-toggle="popover" onclick="openColor(this, \'' + mode + '\');"><i class="fas fa-external-link-alt"></i></button>'
+ '<input class="form-control color-name" type="text" placeholder="Name your color (optional)" value="' + name + '">'
+ '<br class="mobile-only">'
+ '<div class="color-preview" style="background-color:' + hex + ';"></div>'
+ '<span>' + hex + '</span>'
+ '<button class="btn copy-btn no-color" title="Copy" data-toggle="popover" onclick="copyColor(this);"><i class="fas fa-copy"></i></button>'
+ '<button class="btn link-btn no-color" title="Get Link" data-toggle="popover" onclick="copyColorLink(this);"><i class="fas fa-link"></i></button>'
+ '<button class="btn delete-btn no-color" title="Remove" data-toggle="popover" onclick="removeColor(this);"><i class="fas fa-trash"></i></button>'
+ '<i class="fas fa-arrows-alt" style="cursor:move;" title="Drag to Change Order" data-toggle="popover"></i>'
// + '<button onclick="copyText(\'hi\')">hi</button>'
+ '</div>'
);
where mode, hex, and name are all parameters in this function.
Every time I click to copy the color, it calls the copyColor() function, gets the correct string, calls the copyText() function, gets the correct string, and runs with no errors, however it fails to edit my clipboard. When calling this function from the console, with the exact same string, it works, and when creating a static button to copy the color, for example:
<button onclick="copyText('hi')">hi</button>
then it works fine as well. I have also tried dynamically adding one of these buttons:
+ '<button onclick="copyText(\'hi\')">hi</button>' to my code that injects HTML, and it does not work.
Other dynamically created buttons seen above also call functions and pass themselves as a parameter and work fine, for example the delete button, calling the removeColor() function with this as the parameter.
Lastly, I've tried giving the buttons dynamic IDs, by way of:
'<button id="copy-btn-'+ nextID +'" etc...
Where nextID is a value I increment, and I add the onclick listener for that specific button immedatly after creating it:
$('#copy-btn-'+nextID).click(function() {
copyText('hello');
});
nextID++;
I've tried creating a new copy function that only takes in the string, and instead of passing an element I just pass the string to be copied:
function copyColorNew(hex) {
console.log('copyText("' + hex + '")' );
copyText(hex);
}
and here is the relevant part of the inserted button code:
onclick="copyColorNew(\''+hex+'\');">
and it calls the function correctly, passes the correct arguments, and fails to copy the string.
I don't have any duplicate function names, all files are included correctly, I've hard refreshed the page, all variables are in their respective scope, and I've never got any errors. I've also omitted dozens of other rather inconclusive experiments I've done.
I am completely out of ideas, and I've spent several hours a day for several days on this problem. I am well aware how to copy a string in javascript, I'm well aware of how to create a button and append it dynamically, and I'm well aware of how to give the button an onclick listener that passes itself as a parameter. I've had no problems with these things in the past and I still do not everywhere else in this code as I've detailed above.
The only thing I can think of is it's a security problem to allow dynamically created DOM elements to call functions that access the clipboard, but I'm not even pasting the data.
Once again, buttons in the static HTML page can correctly copy 'hello world', dynamically inserted ones cannot copy 'hello world'.
By using the clipboard API (suggested by u/elmstfreddie on Reddit):
navigator.clipboard.writeText(hex);
I got it to work. I replaced copyText(hex); with navigator.clipboard.writeText(hex); in my copyColor() function.
Here is the link to the docs.

Anonymous function in dynamically generated list producing SyntaxError

I want to place an onclick event inside a dynamically generated list. I can't use it as it is, like updateRoomID(arg), because it would fire immediately. So I placed it inside an anonymous function, as advised by various sources online: function (){updateRoomID(arg)}. But this results in: "Uncaught SyntaxError: Unexpected token (". Developer tools says the problem is at function().
The section of code it's in:
socket.onmessage = function(event) {
var msg = JSON.parse(event.data);
for (let i = 0; i < msg.length; i++) {
if (msg[i].beingserved == false) {
listRooms.innerHTML += '<li id=' + msg[i].roomid +
// Problem on following line.
' onclick=' + function () { updateRoomID(msg[i].roomid) } +
'>' +
'<a href="#">' +
msg[i].roomid +
'</a></li>';
} else {
document.getElementById(msg[i].roomid).remove();
};
};
};
I've tried it with the function as a string inside quotations marks: <li id=' + msg[i].roomid +' onclick="function(){updateRoomID(msg[i].roomid)}">'. I've tried placing the onclick handler in href link instead, and also replaced it with addEventListener. But I got the same error with these attempts.
If I try function(){updateRoomID(arg)}() with the parentheses behind, it fires immediately as expected.
I've been looking through it all day and can't figure out where the syntax error is. I'm quite unfamiliar with JavaScript. What am I doing wrong?
You can't put a function in the onclick attribute. It contains JavaScript source code that should be executed.
What you should do in this case is put the function call as a string, but substitute in the value of the argument.
Using a template literal makes this easier.
listRooms.innerHTML += `
<li id="${msg[i].roomid}" onclick="updateRoomId(${msg[i].roomid})">
${msg[i].roomid}
</li>`;

<i class="fa fa-trash"> is not working in <span></span>

I was going through the solutions of Uncaught SyntaxError: missing ) after argument list, and tried every other way to sort it out but I am still getting this error with this code
$("input").on("keypress",function(event){
if(event.which === 13)
{
var ToDotext=($(this).val());
$("ul").append("<li><span><i class="fa fa-trash"></span> " + ToDotext + "</li>");
$(this).val("");
}
}
);
whenever I put <i class="fa fa-trash" in <span></span> I am getting this error, without <i class="fa fa-trash"> things are working fine.
Change the appending line to this.
$("ul").append("<li><span><i class='fa fa-trash'></i></span> " + ToDotext + "</li>");
Changes:
fa fa-trash is in single quotes as you are using double quotes outside.
close the i tag
Suggestions:
Instead of using <i> inside <span>, apply the class on span or remove span altogether and keep i tag.
Use jQuery element creation methods. like this.
$('ul li ').html($('<i>', {class: 'fa fa-trash'}));
Use this code
$("input").on("keypress",function(event){
if(event.which === 13)
{
var ToDotext=($(this).val());
$("ul").append("<li><span><i class='fa fa-trash'></i></span>"+ ToDotext + "</li>");
$(this).val("");
}
});
I found the error in your script.
$("ul").append("<li><span><i class="fa fa-trash"></span>"+ToDotext+"</li>");
If you add component, with this code, the actual components are added as follows.
<li><span><i class=fa fa-trash></span>ToDoText</li>
As you see above, the class names of the <i> tag must be quoted with " or ' but it is not like that.
It is because you used the same quotes adding the components.
If you change "fa fa-trash" -> 'fa fa-trash', the problem will be solved.
You can't have double quotations inside double quotations, simple example:
open your console:
var newElem = "<h1 class="rock">Hello There !!</h1>";
newElem // Uncaught SyntaxError: Unexpected identifier
You will have to enclose you class and other html attributes inside a single quotations, like so:
var newElem = "<h1 class='rock'>Hello There !!</h1>";
The below line:
$("ul").append("<li><span><i class='fa fa-trash'></span> " + ToDotext + "</li>");
Would have to change to:
$("ul").append("<li><span><i class="fa fa-trash"></span> " + ToDotext + "</li>");
Additional ::- if you writing long concatenations you probably want to SPLIT IT UP INTO ADDITIONAL LINK

Calling a method while setting innerHTML of an element

I am struggling with calling a method while setting innerHTML.
I apologize if there is a straightforward answer I have overlooked, but at the moment I am stuck.
Se the code below:
"<a href='#' onclick='removeEntry('" + element.id + "')'><span class='fa fa-times'></span></a>"
You can see that there's a mess regarding the quotes.
Is there a third way to type quotes or something of the kind that can allow me to call "removeEntry(element.id)"? I need quotes around element.id in order to call removeEntry. Any suggestions on how to solve this in a different way?
You should replace
"<a href='#' onclick='removeEntry('" + element.id + "')'><span class='fa fa-times'></span></a>"
with
"<a href='#' onclick='removeEntry(\"" + element.id + "\")'><span class='fa fa-times'></span></a>"
In fact, the problem is with you current code, the a tag onclick property will be looking like onclick='removeEntry('myId')'
Note there's imbricated simple quotes, breaking your function call. Replace the id simple quotes by escaped double quotes , and it'll give you onclick='removeEntry("myId")' that is fine :)
Edit : Anyway, if you're targeting recent browser, you could try ES6 template literals, that will give you the following line :
var html = `<span class="fa fa-times"></span>`;
This helps to avoid struggling with your quotes. Note that the variable inclusion in the template literal looks like PHP do.
This:
"<a href='#' onclick='removeEntry('" + element.id + "')'><span class='fa fa-times'></span></a>"
will create an element like this:
<a href='#' onclick='removeEntry('someId')'><span class='fa fa-times'></span></a>
Which is not correct. What you need to do is to either:
Use the other quotes " (but you have to escape them):
like this:
"<a href='#' onclick='removeEntry(\"" + element.id + "\")'><span class='fa fa-times'></span></a>"
to create an element like this:
<a href='#' onclick='removeEntry("someId")'><span class='fa fa-times'></span></a>
Or Add a backslash \ to the ' quotes (you have to escape the backslashes as well):
like this:
"<a href='#' onclick='removeEntry(\\'" + element.id + "\\')'><span class='fa fa-times'></span></a>"
to create an element like this:
<a href='#' onclick='removeEntry(\'someId\')'><span class='fa fa-times'></span></a>
'<a href="#" onclick="removeEntry(' + element.id + ')">
<span class="fa fa-times"></span>
</a>'
This should work out. You can encode double quotes in single quotes and you want this whole expression as a string.so a string with variable can be written as
string1 = string2 + variable +string3;
Or for a multi lines string in JavaScript you can use back ticks.
`<a href="#" onclick="removeEntry(' + element.id + ')">
<span class="fa fa-times"></span>
</a>`

Undetermined String Literal Error with DIV-Tag

I have a Javascript / JQuery problem.
I get unterminated string literal when I use this code:
var newInfo = '<div><span class="testClass"><a title="edit" href="'+link+'">'+oldVal+'</a></span></div>';
If I delete the </div>
tag, it works... But I need this.
I am totally out of ideas.
Maybe you can help, thanks.
Escape your slashes.
var newInfo = '<div><span class="testClass"><a title="edit" href="' + link + '">' + oldVal + '<\/a><\/span><\/div>';
You could also just build your html as actual DOM elements instead of a string (which avoids a lot of pitfalls, including this one).
var div = $('<div />'),
span = $('<span />').addClass('testClass'),
a = $('<a />').text(oldVal).attr({
"href": link,
"title": "edit"
}),
newInfo = div.append(span.append(a));
Try to use
var newInfo = '<di'+'v><span class="testClass"><a title="edit" href="'+link+'">'+oldVal+'</a></span></di'+'v>';
Seperating the div tags helped me on a similar problem

Categories