Variable in the middle of a string - javascript

$('#attachments').append("<tr><td><b>Attachment " + next + "</b><input id='upload" + next + "'name='files'" + "onchange='showUpload('" + next + "') type='file' value='System.Collections.Generic.List`1[System.Web.HttpPostedFileBase]'></td></tr>");
The above code is printing the following in the browser. What am I doing wrong?
<input id="upload1" name="files" onchange="showUpload(" 1') type="file" value="System.Collections.Generic.List`1[System.Web.HttpPostedFileBase]" class="valid" aria-invalid="false">
onchange="showUpload(" 1') needs to be onchange="showUpload('1')

I recommend using string interpolation (template literals) instead. To find out if your browser supports template literals, check Can I Use.
It's far easier to get this right. I've added newlines so it's readable. Making your HTML on one line like that is just impossible to read:
var content = `<tr><td>
<b>Attachment ${next}</b>
<input id="upload${next}"
name="files"
onchange="showUpload('${next}')"
type="file"
value="snipped for brevity">
</td></tr>`;
$('#attachments').append(content);
What this does is fairly intuitive: the template literal, delineated by backticks, will replace each instance of ${next} with the value in the next variable.
I have also taken the liberty to change all of your attributes to use double quotes for consistency. Hopefully I didn't make any typos.

Superficially "onchange='showUpload('" closes the onchange value before the function's parameter, which leads to malformed HTML.
What am I doing wrong?
What you're really doing wrong is that you're adding inline event handlers with jQuery, which leads to problems exactly like that.
var tr = $("<tr><td><b>Attachment " + next + "</b></td></tr>").appendTo("#attachments");
$('<input>', {
id: "upload" + next,
name: "files",
type: "file",
value: "System.Collections.Generic.List`1[System.Web.HttpPostedFileBase]"
}).on( 'change', function() { showUpload(next); } )
.appendTo(tr.find('td'));

You can simply escape a character
$('#attachments')
.append("<tr><td><b>Attachment " + next + "</b><input id='upload" + next + "' name='files' onchange='showUpload(\"" + next + "\")' type='file' value='System.Collections.Generic.List`1[System.Web.HttpPostedFileBase]'></td></tr>");

Related

jquery function adding html form with returns

I have a US map and when someone clicks on a state it displays a form. For example like below... this is a sample. The problem is a few of the forms have over 15 form elements. Adding those without returns is not manageable and very tedious to add without getting errors.
Is there anyway I can add a form to the code below and add the form with returns instead of without returns like the code below?
No Returns = I mean adding each form element on one line without pressing enter on your keyboard ...
Returns = Adding form element then pressing enter to go to the next line.
function myCallback(event, data)
{
if ('CA' == data.name)
{
$('#notif').html('<form>First name: <input type=\"text\" name=\"name\" value=\" "+ data.name +" \"><br>Email: <input type=\"text\" name=\"email\" value=\" "+ data.email +" \"></form>');
}
Your question is a bit unclear but you can use basically two ways
1. String manipulation
In javascript there are two ways to break a long string, concatenation and using the \ character.
Example
Concatenation:
$('#notif').html(
'<form>First name: ' +
'<input type="text" name="name" value="' + data.name + '"\>' +
'<br>Email:' +
'<input type="text" name="email" value="'+ data.email +'"\>'+
'</form>');
Basically you organize your strings to be more readable. Mind the use of ' and " they can be used indistinctly but is better if you are consistent in which sign you use to enclose your strings and which to use for your attributes.
Breaking long strings
The docs says that you can break a long string with a \ sign
Example
$('#notif').html(
'<form>First name: \
<input type="text" name="name" value="' + data.name + '"\>\
<br>Email:\
<input type="text" name="email" value="'+ data.email +'"\>\
</form>');
Is a bit harder to read but basically is the same using only one string.
2. Using native elements
You can also use jquery to create your form elements in a variable and attach them to the form using the append function
Example
Using JQuery
var container = $('#notif');
container.append('<form></form>')
var form = container.children('form');
form.append('First name: ')
.append('<input type="text" name="name" value="' + data.name + '"\>')
.append('<br>Email:')
.append('<input type="text" name="email" value="' + data.email + '"\>');
This function is chainable so you can have one element per line
Here's the answer to "MY" question that's so hard to understand.
Use .load( "form.php" )
$('#notif').load("form.php");

Dynamically changing innerText's start without eval()

I have some code (several batches) that look like this:
1 <div id="backgrounds" class="centery">Backgrounds
2 <div id="bk1" class="attr">Background 1
3 <div class="container">
4 <!-- Lots more HTML here /-->
5 </div>
6 </div>
7 </div>
I have a JS function I wrote (changefirstCharacters) that will return the script to change line 2 to read:
2 <div id="bk1" class="attr">Some text I specify
But because I want this to only execute when an event listener fires, it only outputs the code, rather than evaluating it. As a result, my event listener contains a line like this:
eval(changeFirstCharacters('bk1', "'" + document.getElementById('background1').value + "'"));
Where background1 is a select box.
How can I re-write changeFirstCharacters to not need eval, but still work only when called?
changeFirstCharacters() code
function changeFirstCharacters(id, newText) {
return 'document.getElementById(\"' + id + '\").innerHTML = ' + newText + ' \+ document.getElementById(\"' + id + '\").innerHTML.substr(' + document.getElementById(id).innerText.length + ', document.getElementById(\"' + id + '\").innerHTML.length \-' + document.getElementById(id).innerText.length + ')';
}
I don't see what's so dynamic about that statement. The only reason we need eval is when code is dynamically generated, but neither newText nor id changes the produced code. Therefore, the following ought to work:
document.getElementById(id).innerHTML = newText +
document.getElementById(id).innerHTML.substr(document.getElementById(id).innerText.length,
document.getElementById(id).innerHTML.length - document.getElementById(id).innerText.length);
Called by (without adding quotes around the second argument):
changeFirstCharacters('bk1', document.getElementById('background1').value)
Also that first code calls getElementById(id) five times, which is not only a performance hit, it's rather ugly. You might want to rewrite it as:
var el = document.getElementById(id);
el.innerHTML = newText + el.innerHTML.substr(el.innerText.length,
el.innerHTML.length - el.innerText.length);

jQuery: trying hook a function to the onclick when page loads

I have seen a similar question, HERE and have tried that, but I can't seem to get it working.
Here is my code for dynamically generating table rows.
for (var contribution = 0; contribution < candidate.contributions.length - 1; contribution++) {
var id = candidate.contributions[contribution].donor_id;
var uid = candidate.contributions[contribution].user_id;
$("#history-table").append(
"<tr onclick='" + parent.viewEngine.pageChange('public-profile', 1, id, uid) + ";>" +
"<td class='img-cell'>" +
"<img class='profile-avatar-small' src='/uploads/profile-pictures/" +
candidate.contributions[contribution].image + "' alt='' /></td><td class=''>" +
"<h2>" + candidate.contributions[contribution].firstname +
" " + candidate.contributions[contribution].lastname + "</h2></a><br/><br/>" +
"<span class='contribution-description'>" + candidate.contributions[contribution].contribution_description + "</span></td>" +
"<td><h3>$" + formatCurrency(candidate.contributions[contribution].contribution_amount) + "</h3></td></tr>");
}
This still executes the click event as soon as the page loads, which is not the desired behavior. I need to be able to click the tr to execute the click event.
Pass the whole thing as a string:
"<tr onclick='parent.viewEngine.pageChange(\'public-profile\', 1, " + id + ", " + uid + ");>" // + (...)
But, as you are using jQuery, you should be attaching the click handler with .on().
(I really don't recommend using inline event handlers like that, especially when you're already using jQuery, but anyway...)
The problem is that you need the name of the function to end up in the string that you are passing to .append(), but you are simply calling the function and appending the result. Try this:
...
"<tr onclick='parent.viewEngine.pageChange(\"public-profile\", 1, " + id + "," + uid + ");'>" +
...
This creates a string that includes the name of the function and the first couple of parameters, but then adds the values of the id and uid variables from the current loop iteration such that the full string includes the appropriately formatted function name and parameters.
Note that the quotation marks around "public-profile" were single quotes but that wouldn't work because you've also used single quotes for your onclick='...', so you should use double-quotes but they need to be escaped because the entire string is in double-quotes.
I'm wondering if you might be better simplifying things a bit.
If your rows are being dynamically added, then try putting some kind of meta-data in the <tr> tag, e.g. something like this:
<tr id="id" name="uid">
Then try the following with your jQuery (v.1.7 required):
$('#history-table tr').on('click', function(){
parent.viewEngine.pageChange('public-profile', 1, this.id, this.name);
});
This will likely require modification depending on how your page rendering works but it's a lot cleaner and easier to read having been removed from your main table markup.
Well that's because you're executing the function, not concatenating it. Try:
onclick='parent.viewEngine.pageChange("public-profile", 1, id, uid);'
Take this ->
$("#contribution-" + uid).click(function(){
parent.viewEngine.pageChange('public-profile',1, id, uid);
});
And do two things:
1) Move it outside of the 'for' statement
As soon as the for statement is executed, the click function will be executed as well. The click function is not being supplied as a callback function in this for statement.
2) Change it to ->
$("tr[id^='contribution-'").on('click', function(){
var idString = $(this).attr("id").split("-"); //split the ID string on every hyphen
var uid = idString[1]; //our UID sits on the otherside of the hyphen, so we use [1] to selec it
//our UID will now be what we need. we also apply our click function to every anchor element that has an id beginning with 'contribution-'. should do the trick.
parent.viewEngine.pageChange('public-profile',1, id, uid);
});
This is my solution.

Variable within quote within quote?

Im trying to use inner html and dynamically set an onclick statement that contains a variable:
cell5.innerHTML="<input type='button' value='Remove' onclick='removerow('manual_" + (num) + "')' />"
So lets say the num variable was set to 4. The output should be onclick="removerow('manual_4')"
Any help?
The best thing would be to avoid all this:
var input = document.createElement('input');
input.type = 'button';
input.value = 'Remove';
input.onclick = function() {
removerow('manual_' + num);
};
cell5.appendChild(input);
Depending on the relationship between the button, the cell and the row to be removed, you could also do DOM traversal inside the handler to get a reference to the row.
You can escaped nested quotes using \:
"...onclick=\"removerow('manual_" + (num) + "')\"..."
cell5.innerHTML='<input type="button" value="Remove" onclick="removerow(\'manual_' + (num) + '\')" />'
You can escape the quotes using \
So
onclick=\"removerow('manual_" + (num) + "')\"
Consider using a click event instead. It makes that sort of thing clearer:
$(".cell5") // whatever selector you want
.html('<input type="button" value="Remove"/>')
.click(function(){
removerow('manual_' + row);
});
Also consider using the row number as the input instead of a string. If they all have the same form you can simplify things with just:
removerow(row);
Clearly that is an API design decision, but it would simplify this expression if it makes sense.

javascript Firebug error: Identifier starts immediately after numeric literal

I've got this error being reported in firebug, but I have no idea what it means:
Identifier starts immediately after numeric literal
Here is my webpage:
http://www.austintreeexperts.com/maps/optionUpdateMap.cfm?zoom=15
When the page and map loads, click on one of the blue or green markers. Then click on one of the check boxes to get the error. I have an onclick= for the input checkboxes.
Your string concatenation is broken. You need to wrap your method parameters in quotes
var statusForm = '<input id="tU'+Aid+'" type="checkbox" onclick="optionAUpdate(tU'+Aid+', '+color+', '+optionB+')"/> option A | <input id="iU'+Aid+'" onclick="optionBUpdate(iU'+Aid+', '+color+', '+optionA+')" type="checkbox"/> options B';
From here ----------------------------------------------------------------------------^
Corrected version
var statusForm = '<input id="tU' + Aid + '" type="checkbox" onclick="optionAUpdate(\'tU' + Aid + '\', \'' + color + '\', \'' + optionB + '\')"/> option A'
Note : I've treated all your params as strings
Your onclick needs to be:
optionAUpdate('tU20238', '75AB5F', 0)
Note that I wrapped the params in quotes as they are strings.
This message also appears if you've tried to name a variable starting with a numeral. eg.
var 2ndString = 'abc';
<input
id="is-ib-checkbox"
value='+accWidgetData[count]["userAccountNumber"]+'
onchange="addaUserAccount(\'' + accWidgetData[count]["userAccountNumber"] + '\' );"
value="true"
checked="checked"
type="checkbox"
/>
For this case, in my code:
html.input()
.onclick("selectItem(" +"'"+cons.getIdentificacion().toString()+"'" + ");")
.type("radio")
.name("selectedItem")
.style("vertical-align: text-bottom")
.close();
works Fine.

Categories

Resources