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

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

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.

js syntax error: missing ) after argument

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`;

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>`

How to construct a new HTML element in jQuery?

I have some code similar to this:
var glyph = isApple ? '<span class="glyphicon glyphicon-apple"></span>' : '<span class="glyphicon glyphicon-banana"></span>';
var newFruit = '<li class="list-group-item">' + glyph + '<span class="badge">' + score + '</span>' + name + '</li>'
$('#fruitList').append(newFruit);
Just a lot of gross concatenation that is hard to read and follow. Is there a way to functionally create these elements, and if so, how? Also, I'm curious of the speed of doing so, because if it is much slower than what I'm doing then I just won't bother.
I'm looking for something like this, for example:
var newElement = li().class("list-group-item").value(name);
newElement.span().class(isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user");
newElement.span().class('badge').value(score);
$('#fruitList').append(newElement);
Now obviously the above is not good or probably even right but hopefully it gets the idea across. Basically a way of chaining functions to create new elements that avoids the mess of concatentations for creating custom HTML to insert.
Something like this?
$('<li>', {
html: $('<a>', {
href: item.href,
text: item.title
})
});
This puts an a tag within an li tag. You can modify this as per your needs
This structure should help, the trick is making sure the parent element is appended before the child:
var newElement = document.createElement('li');
$(newElement).addClass('list-group-item');
$(newElement).html(name);
$('#fruitList').append(newElement);
var newSpan = document.createElement('span');
var apple = isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user";
$(newSpan).addClass(apple);
$(newSpan).addClass('badge');
$(newSpan).html(score)
$(newElement).append(newSpan);
var $li = $("<li/>",{title:"woot"}).addClass("list-group-item").value(name);
$li.append( $("<span/>").addClass(isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user") );
$("<span/>").addClass('badge').value(score).appendTo( $li );
$('#fruitList').append($li);
Generally speaking, arrays are faster than string concatenation which is faster than DOM manipulation.
function getNewItemString(glyph,score,name){
return [
'<li class="list-group-item">',
'<span class="glyphicon ',
glyph,
'"></span>',
'<span class="badge">',
score,
'</span>',
name,
'</li>'
].join('');
}
$('#fruitList').append(getNewItemString('glyphicon-apple', 20, 'player1'));
$('#fruitList').append(getNewItemString('glyphicon-banana', 0, 'player2'));
There is an overload of the jQuery function that allows you to do create an element and specify its properties. The following would replicate your example:
$('<li>', {
class: "list-group-item",
html: $('<span>', {
class: isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user"
})
.after($('<span>', {
class: "badge",
text: score
}))
.after(name)
});

Error while passing parameter to javascript function dynamically

I am creating list dynamically. When user click on that li element setCollege method will be called.
Code to generate li is:
$('#dropDown ul').append("
<li onclick=setCollege("+ data[i].id +",'"+ data[i].college_name +"')><i class='fa fa-university'></i>" + data[i].college_name + "</li>");
but javascript dynamically add " after space in college name like
<li onclick="setCollege(3,'Nirma" university')"> <i class="fa fa-university"></i>Nirma University</li>
due to ", it produces error while calling js function
onclick is a html attribute, thus it needs to be put in quotes itself.
Try this instead:
var tpl = '<li onclick="setCollege(' + data[i].id + ', ' + data[i].college_name + ' );"><i class="fa fa-university"></i>' + data[i].college_name + '</li>';
$('#dropDown ul').append( tpl );
Pay attention to single vs. double quote usage.
But since your question is flagged as jquery, I'd suggest:
var listItem = $( '<li></li>' ).text( data[i].college_name );
$( '<i class="fa fa-university"></i>' ).prependTo( listItem );
listItem.on( 'click', function() {
setCollege( data[i].id, data[i].college_name);
});
listItem.appendTo( '#dropDown ul' );
Try using like:
$('#dropDown ul').append("
<li onclick=setCollege("+ data[i].id +",""+ data[i].college_name +"")><i class='fa fa-university'></i>" + data[i].college_name + "</li>");
Your concatenation starts with double quotes("). So you need to follow till the end of the statement.
Try this,
"'+ data[i].college_name +'"
instead of
'"+ data[i].college_name +"'
Also add double quotes(" ") surround by the onclick event, and escape them,
onclick=\"setcollege(.......)\"
Because you don't add the surrounding " to your onclick attribute:
$('#dropDown ul').append("
<li onclick=\"setCollege("+ data[i].id +",'"+ data[i].college_name +"')\"><i class='fa fa-university'></i>" + data[i].college_name + "</li>");
but why don't you use jQuery to attach the event to the list items? This would be the better solution:
$('#dropDown').on('click', 'li', function() {
setCollege(...);
});

Categories