using quotes inside innerHTML not working - javascript

I am trying to use JavaScript to have a dynamic list, and I need to use a lot of of quotes to make the <li> line work as it should, but I cannot get innerHTML to output the correct syntax to the html doc.
here is my JS:
function settabnumber() {
alert("set tab number function called");
var settabcount = 3;
var menucode;
var i=0;
for(basetabcount = 0; basetabcount < settabcount; basetabcount++){
i++;
menucode = menucode + "<li>" + tabnames[i] + "</li>";
}
document.getElementById("eetabmenu").innerHTML = menucode;
}
Any ideas?

Try...
menucode = menucode + '<li>' + tabnames[i] + '</li>';
Always use single quotes to hold HTML strings so you can then freely use the obligatory double quotes.

I made a JSFiddle attempting to reproduce your issue, but it wasn't occurring: https://jsfiddle.net/qf19wvr0/
Either way, as the other commenters said, you should use single quotes. OR, if you're working in an ES6 environment (using a transpiler like Babel), you can use template strings:
menucode += `<li>${tabnames[i]}</li>`
Which makes your snippet a lot more readable.
However:
If you're doing complex enough work that you're looping over a collection and building up DOM nodes from strings, you may want to consider using some kind of templating system (like Handlebars, Mustache, React, or anything of the sort) to abstract some of your view creation logic. Having HTML strings in your JavaScript is a pretty big code smell and likely means you're mixing view logic with business logic.

Use single quotes ' inside of your double quotes, or viseversa
menucode = menucode + '<li>' + tabnames[i] + '</li>';
OR
menucode = menucode + "<li><a href='#tabs-" + i + "'>" + tabnames[i] + "</a></li>";
The first one is preferred

Related

Wrapping javascript concatenated html correctly with ",' and \

I'm having a bit of trouble correctly displaying a message in a webpage I am trying to create. The code I have is:
content.innerHTML += "<button 'onclick=\"likeFunction(" + feed.messages[y]._id + ")\">" + "Like(" + feed.messages[y].likesCount + ")" + "</button>"
When I inspect the element on the page source, I get this output:
<button 'onclick="like(idOfObject)">Likes(likeNumber)</button>
What I need it to look like is:
<button 'onclick="like("idOfObject")">Likes(likeNumber)</button>
I'm a bit confused on how I would add more single or double quotes and where to escape them correctly to get this desired output.
I think I see a few typos. Most noticeably with the leading ' in front of onclick. I don't think this needs to be here.
As for formatting the string, consider looking into template literals introduced in ES6.
Might look something like this:
content.innerHTML += `<button onclick="likeFunction(${idOfObjectVariable})">Likes (${likeCountVariable})</button>`
Hope this helps
You're so close! First, you need to remove the ' before onclick. If you want to add double quotes around the idOfObject, then you just need escape one double quote after likeFunction( and one double quote before )\">".
"<button onclick=\"likeFunction(\"" + feed.messages[y]._id + "\")\">"
The only problem is that when the double quotes around your variable idOfObject render, they'll correspond to the opening and closing quotes you already have for onclick. So, your solution should have single quotes inside of double quotes:
"<button onclick=\"likeFunction(\'" + feed.messages[y]._id + "\')\">"
I would have guessed what you wanted in your HTML would be:
<button onclick="like('idOfObject')">7</button>
or
<button onclick='like("idOfObject")'>7</button>
You probably do not want to quote the entire on-click attribute, just the part on the right hand side of the = .
content.innerHTML += "<button onclick=\"like('" + feed.messages[y]._id + "')\">" + ...
I'm guessing you also probably don't want something that gets displayed to the user that looks like a function all, but the result of the function call, but that is not what you were asking about.
You SHOULD NOT concatenate html manually from untrusted input (suppose someone injected malicious html code to your feed.messages[y]._id or another field). Sanitization is one of your options but it's like patching a huge hole.
You can read more about preventing those security attacks named XSS here.
Consider creating your DOM manualy with createElement API and bind your event handlers manually.
function renderButton(content, feed, y) {
function likeFunction() {
alert("LIKE" + feed.messages[y]._id);
};
var button = document.createElement("button");
var text = document.createTextNode("Like(" + feed.messages[y].likesCount + ")");
button.appendChild(text);
button.addEventListener('click', likeFunction)
content.appendChild(button);
}
Then you can just render your button with a simple function call.
renderButton(content, feed, 0)

Jquery Appended Button Not Displaying Correctly

I am working with Jquery/javascript/html. I am trying to display a button inside of tags in my table. I am appending the information into/onto a section on my html page. Code is as follows:
<html>
<body>
<p id="report_area"></p>
</body>
</html>
Javascript file below
$('#report_area').append('<table>');
$('#report_area').append('<tr>');
$('#report_area').append('<th>' + view + '</th><th>' + col_1 + '</th><th>' + col_2 + '</th><th>' + col_3 + '</th>');
$('#report_area').append('</tr>');
var btn=$('<button/>');
btn.text('View');
btn.val=item.SURVEY_JOB_ID;
btn.id=item.SURVEY_JOB_ID;
// recently added code - start
btn.click(function()
{
window.localStorage.setItem("MyFirstItem", 10);
window.location = 'GoToThisOtherPage.htm'
}
// recently added code - end
$('#report_area').append('<tr><td>'+ btn +'</td><td>' + item.JOB_NUMBER +
'</td><td>' + item.TITLE + '</td><td>' + item.MODIFICATION_NUMBER + '</td></tr>');
$('#report_area').append('</table>');
THis seems to work correctly however, the button is not showing up correctly. It shows up as an object. All the other data displays correctlyMy table row is displayed as :
[object Object] 12 New Job Title 0
[object Object} 30 Title Help Me 1
I'm not sure why it is displaying as [object Object]. When I do something as simple as:
$('#report_area').append(btn);
the button shows up on the page correctly. Any help on this would be greatly appreciated. Thanks in advance.
To understand why this does not work, you have to look at the documentation for append.
Type: htmlString or Element or Array or jQuery
append is able to except any of those types, and handle each of them differently, so when you pass it an element (actually jQuery collection), it is able to intelligently convert it into the desired html.
However, in your case, you are passing it a string, so it will naively treat the string as html. The reason that this produces [object Object], is because it is relying on native JavaScript to convert the element into a string. You'll produce the same output with console.log(btn).
// append recieves a jQuery collection, calls appropriate methods to obtain html
$('#report_area').append(btn);
// append receives a string, blindly assumes that it is already the desired html
$('#report_area').append(btn + '');
Solution 1 - Append separately
From your comments on other answers, it doesn't seem like this solution works. I think this is because append will automatically add the close tags for the tr and td when appending, causing the button to be added afterwards. You could check if this was the case by looking at the html produced in the developer tools of your browser.
$('#report_area').append('<tr><td>', [btn, '</tr></td>'])
Solution 2 - Convert to string properly
$('#report_area').append('<tr><td>'+ btn[0].outerHTML +'</td><td>')
Solution 3 - Constructing everything as jQuery collections
I think the main problem you have been having is to do with mixing elements and strings. I've written a working jsfiddle solution that constructs everything as jQuery collections.
var table = $('<table>');
var btnRow = $('<tr>');
var btnCell = $('<td>');
var btn=$('<button>');
btn.text('View');
btn.val('val');
btn.attr('id', 'id');
btn.on('click', function()
{
window.alert('Click');
});
btnCell.append(btn);
btnRow.append(btnCell);
table.append(btnRow);
btnRow.append('<td>1</td><td>2</td><td>3</td>');
$('#report_area').append(table);
JavaScript is converting btn to a string because you're concatenating several strings to it.
It should work if you do this.
$('#report_area').append('<tr><td>');
$('#report_area').append(btn);
$('#report_area').append('</td><td>' + item.JOB_NUMBER +
'</td><td>' + item.TITLE + '</td><td>' + item.MODIFICATION_NUMBER + '</td></tr>');
$('#report_area').append('</table>');
You're attempting to set native DOM properties on a jQuery object. Remember, a jQuery object is a superset of a native DOM object. Alter your code to use the .val() and .attr() jQuery methods like so:
var btn=$('<button/>');
btn.text('View');
btn.val(item.SURVEY_JOB_ID);
btn.attr('id', item.SURVEY_JOB_ID);
Alternately, you can chain these methods together for convenience:
var btn= $('<button/>')
.text('View')
.attr('id', item.SURVEY_JOB_ID)
.val(item.SURVEY_JOB_ID);
Finally, alter your use of the .append() method to append the content like so:
$('#report_area').append(
'<tr><td>',
[
btn,
'</td><td>' + item.JOB_NUMBER + '</td><td>' + item.TITLE + '</td><td>' + item.MODIFICATION_NUMBER + '</td></tr></table>'
]);

how to embed value with an apostrophe in querystring

I have the following javascript:
tr.append("<a href='add_widget.html?id=" + data[i].id + "&pg=" + data[i].page_number + "&dest=" + data[i].dest + "&name=" + data[i].name.replace("'","\\'") + "'</a><button class='btn btn-xs btn-primary'>Edit</button> </td>");
The code in question has to do with the name field.
If I have a name like "John Doe" when I click on the hyperlink created by the above javascript, the new page's querystring has the full name.
However, if I try to pass a name like "John's stuff", the above logic creates a query string variable that looks like this:
&name=John\
How can I change the above code so that the entire string "John's stuff" is passed to the add_widget.html page?
Thanks.
replace("'","%27")
try http://meyerweb.com/eric/tools/dencoder/ it's an online URL encoder/decoder.
When you're trying to "protect" characters, you have to keep in mind what you're protecting them from. In this case, there are two interpreters you have to worry about:
You're building HTML, so you have to worry about the HTML parser;
You're building a URL, so you have to worry about how the browser and the server will parse the URL.
To deal with the first problem, you can replace the quotes with the HTML entity equivalent ('). To deal with the second, you can use encodeURIComponent().
I think you'd want to do the encodeURIComponent() call first, to avoid having the HTML entity notation get messed up. The entity notation will be gone after the HTML parser is finished with the string anyway:
function qEncode(str) {
return encodeURIComponent(str).replace(/'/g, "'");
}
To use that:
tr.append("<a href='add_widget.html?id=" +
qEncode(data[i].id) + "&pg=" +
qEncode(data[i].page_number) + "&dest=" +
qEncode(data[i].dest) + "&name=" +
qEncode(data[i].name) +
"'</a><button class='btn btn-xs btn-primary'>Edit</button> </td>"
);
Note that you could also encode double-quote characters too.
A totally different way of working around this problem would be to build the DOM content with DOM APIs. By doing that, you'd completely avoid the HTML parser, and you'd just need encodeURIComponent().
You need to think, what will be interpreting my code, so what do I need to escape for?
Your code will be interpreted by the HTML Interpreter in the browser
Your code will be interpreted as a URI
This means you need to escape/encode them in reverse order. Luckily JavaScript provides a URI encoder as encodeURIComponent, but it doesn't provide a HTML one (probably as we have DOM Methods) but it isn't too hard to implement for important characters, e.g.
function html_encode(str) {
var re_chars = /[<>'"]/g;
function replacer($0) {
return '&#' + $0.charCodeAt(0) + ';'
}
return str.replace(re_chars, replacer);
}
// example follows
html_encode('<foo bar="baz">'); // "<foo bar="baz">"
So for you,
attrib_value = html_encode(/* ... + */ encodeURIComponent(data[i].name) /* + ... */ );
For completeness,
function html_decode(str) {
var re = /&(?:#\d{1,3}|amp|quot|lt|gt|nbsp);/g, // notice extra entities
d = document.createElement('div');
function replacer($0) {
d.innerHTML = $0;
return d.textContent;
}
return str.replace(re, replacer);
}
// and an example
html_decode('<foo bar="baz">'); // "<foo bar="baz">"
Using escape(data[i].name) instead of data[i].name.replace("'","\\'"), will solve your problem.

using an array to check a series of javascript buttons

I am trying to check a series of buttons to see if they have been selected in order to generate a query string. So far as I can tell, the logic looks something like this:
if ($("input[name='ovr']")[0].checked)
{
...
}
This works, but since I don't want to use a series of if statements to generate the string (because more buttons might be added later, it's inefficient, etc), I generated an array representing the names associated with the buttons (I printed the array; it definitely contains the proper names). When I made a loop to run through each name in the array, however, the console suggested that 'input' was an unrecognized expression. Here is the loop:
for (i = 0; i < myList.length; i = i + 1) {
if ($("/"input[name='" + myList[i] + "']/"")[0].checked) {
string += myList[i] + "=" + myList[i] + "&";
}
}
string is a variable that appends the proper signature(?) onto itself if the button check should return true. myList is the array containing the names.
Unfortunately, I am new to all of this and don't really know where to begin. I did try to google the answer (really a novice here) but I wasn't even quite sure what to search for. I also messed around with the phrasing of the input expression, used different escape characters, etc., to no avail. Neither the HTML nor most of the javascript is mine (it's my supervisor's), so I am doubly lost. Any suggestions you could give would be sincerely appreciated.
Thanks!
Something like this would work (I don't really understand why you tried to add those backslashes, so I only show you the right way):
for (i = 0; i < myList.length; i = i + 1) {
if ($("input[name='" + myList[i] + "']")[0].checked) {
string += myList[i] + "=" + myList[i] + "&";
}
}
One note: if you are generating a query string, don't forget to use encodeURIComponent()!
something like this?
var query = "?";
$('input:checked').each(function(index) {
query += this.name + "=" + this.value + "&";
});
you can modify the selector to get only the checkboxes you need.

changing links doesnt work with jquery

I have got this link:
Visit imLive.com
I want to use this code to add/change different url parameters:
$("a.sitelink_external.imlive").each(function(){
$params=getUrlVars(document.URL);
var promocode_addition='';
if('INFO'==$params['ref']){
promocode_addition='LCI';
}
$(this).attr("href", 'http://im.com/wmaster.ashx?WID=124904080515&cbname=limdeaive&LinkID=701&queryid=138&promocode=LCDIMLRV" + i + promocode_addition+"&"FRefID=" + FRefID + "&FRefP=" + FRefP + "&FRefQS=" + FRefQS');
});
The problem is that that jquery code doesnt work..I tried to move it to document ready..but it doesnt work there too..
The thing that jumps out at me is that you're mixing your double and single quotes on this line:
$(this).attr("href", 'http://im.com/wmaster.ashx?WID=124904080515&cbname=limdeaive&LinkID=701&queryid=138&promocode=LCDIMLRV" + i + promocode_addition+"&FRefID=" + FRefID + "&FRefP=" + FRefP + "&FRefQS=" + FRefQS');
Try changing them all to double quotes, and remove the extra " from after the ampersand in "&"FRefID=" - like this:
$(this).attr("href", "http://im.com/wmaster.ashx?WID=124904080515&cbname=limdeaive&LinkID=701&queryid=138&promocode=LCDIMLRV" + i + promocode_addition+"&FRefID=" + FRefID + "&FRefP=" + FRefP + "&FRefQS=" + FRefQS);
The way you had it was a single string containing stuff that looked like code. The way I've changed it is several strings and variables being concatenated together... (Note the difference with StackOverflow's syntax highlighting.)
Note also that the following code:
$params=getUrlVars(document.URL);
var promocode_addition='';
if('INFO'==$params['ref']){
promocode_addition='LCI';
}
...can be moved to before the .each() loop, since it operates only on the document and thus will produce the same results on every iteration.
(Of course there could be other problems since you reference several variables that aren't shown.)

Categories

Resources