I am using onclick event to perform some acction, but for som reason the second ID is not being passed what am I doing wrong here:
row += '<td>' + data[staff].Naame + '(' + data[staff].place1 + 'fID="' + data[staff].id+ '"' +')</td>'
$(document).on("click", ".name", function (e) {
var code = ($(this).attr("code"))
var fID = ($(this).attr("fID"))
function(code, fID);
});
For some reason fID is not being passed from 'fID="' + data[staff].id+ '"' to function(code, fID); why is that?
Avoid using loads of string concatenation in jQuery, to create elements, as it is generally unreadable and leads to typing mistakes (like not putting the fId inside the tag attributes):
Instead build the element with jQuery. I am not 100% sure of what your link should look like from the code, but something like this (tweak to suit):
var $td = $('<td>').html(data[staff].Naame);
$td.append($('<a>', {class: 'name', code: data[staff].place, fId: data[staff].id}).html(data[staff].place1));
row.append($td);
I think you need to define fID within the <a ... > tag - like you are doing for code.
ie:
...
Try this.
row += '<td>' + data[staff].Naame + ''+data[staff].place1+'</td>'
Related
I have a list of elements. However, the length of this list varies between trials. For example, sometimes there are 6 elements and sometimes there are 8. The exact number is detailed in an external metadata.
To display this variable list, I've written:
var html = '';
html += '<div id="button' + ind + '" class="buttons">';
html += '<p>' + name + '</p></div>';
display_element.innerHTML = html;
If I were to 'inspect' the elements in my browser, they would appear to have IDs of button0.buttons, button1.buttons, etc.
Now I am trying to attach event listeners to each element but my code is not working so far. Different forms of broken code below:
document.getElementById("button' + ind + '").addEventListener("click", foo);
$("#button' + ind + '").click(foo);
document.getElementById("button").addEventListener("click", foo);
$("#button").click(foo);
Any help would be very appreciated! Thanks.
You wrong at concat string update it as
document.getElementById("button" + ind).addEventListener("click", foo);
var html = '';
var ind = 1;
var display_element = document.getElementById("test");
html += '<div id="button' + ind + '" class="buttons">';
html += '<p>' + name + '</p></div>';
display_element.innerHTML = html;
document.getElementById("button" + ind).addEventListener("click", foo);
function foo(){
alert('click');
}
<div id="test"></div>
Use "document.getElementsByClassName" get all botton elements then foreach to add click function.
document.getElementsByClassName('buttons').map( element => { element.addEventListener("click", foo) })
To answer the question of why neither of those uses of document.getElementById() are working for you, you are mixing your quotes incorrectly. "button' + ind '" evaluates to exactly that, rather than evaluating to "button0", "button1", etc. To make your code more readable, and to avoid similar quote mixing issues, I would recommend looking into template literals https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
With modern JS if you want to execute the same function you won't require to add an id to each button.
Just use the class added to the buttons like this:
document.querySelectorAll('.buttons').forEach(button => {
button.addEventListener('click',foo);
});
Then use the event parameter in that function to get the target node & execute whatever you want. You can also add data attributes in those buttons to use while executing that function.
My code generates a table with a button at the end of each row. When the user clicks a button how can I pass a property u.userEmail to the controller via the button? Will the value being sent to the controller be a string?
My (non-working) attempt:
<script>
$(document.body).append("waiting on async table to load<br>");
$(document).ready(function () {
$.getJSON("/Account/LoadClaimsTable", function (crewResponse) {
//returns a List<UserClaims>
$(document.body).append("<table>")
crewResponse.forEach(function (u) {
var s = "";
s+="<tr><td>" + u.userEmail + "</td>";
u.userClaims.forEach(function (k) {
console.log("added claim"+k.value);
s += ("<td>" + k.type + "</td><td>" + k.value + "</td><td>" +
"<input type=\"hidden\" name=\"userEmail\" value=\"`${u.userEmail}`\" />"+
"<input type=\"button\" value=\"Create\" onclick=\"location.href='#Url.Action("EditClaims", "Account")'" />
+"</td>");
});
s += "</tr>";
$(document.body).append(s);
s = "";
});
$(document.body).append("</table>")
});
});
</script>
AccountController.cs contains:
public ActionResult EditClaims(string userEmail)
{
return View("StringView", userEmail);
}
You have to pass it on the url of the action. Not sure if you want to pass u.userEmail, but it could looks like this:
crewResponse.forEach(function (u) {
var s = "<tr><td>" + u.userEmail + "</td>";
u.userClaims.forEach(function (k) {
console.log("added claim"+k.value);
s += ("<td>" + k.type + "</td><td>" + k.value + "</td><td>" +
"<input type=\"hidden\" name=\"userEmail\" value=\"`${u.userEmail}`\" />"+
"<input type=\"button\" value=\"Create\" onclick=\"location.href='#Url.Action("EditClaims", "Account")?userEmail=" + u.userEmail + "'\"/></td>");
});
s += "</tr>";
$(document.body).append(s);
});
There are multiple ways to do it. One is mentioned in the answer above by Felipe. Here is another alternate approach using unobtrusive js
Add the email as html5 data attributes to the button along with another attribute which we will use bind the click behavior.
u.userClaims.forEach(function (k) {
// Add quotes as needed if you want multiline ( i just removed those)
s += "<td>" + k.type + "</td><td>" + k.value + "</td><td>
<input type='button'
clickablebutton data-email='" + u.email + "' value='Create'/></td>";
});
Now, in your document ready, bind a click event handler to those elements (with our custom attribute) and read the data attribute and build the url you need.
$(document).on("click", "input[clickablebutton]", function (e){
var url = '#Url.Action("EditClaims", "Accounts")?useremail=' + $(this).data("email");
window.location.href = url;
});
Some other suggestions
Use the appropriate element. Button is better than input (Consider accessibility)
If it is for navigation, Use an anchor tag instead of a button.
Inline javascript is not great. Let the browser parses your markup without any interruptions and you can add the behavior scripts later (that is the whole point of uobutrisive js approach)
The approach you appear to be taking would be Ajax, response, render a template. With that being said, you may want to rethink your approach.
Step 1.
Build a template
<template id="...">
<button type="button" value="[action]" onclick="[url]">[text]</button>
</template>
Step 2.
Create your request.
axios.get('...').then((response) => {
// Retrieve template.
// Replace bracket with response object model data.
html += template.replace('[action]', response.action);
});
Step 3.
Have the JavaScript render your template.
The above can create a clear concise codebase that is easier to maintain and scale as the scope changes, rather than an individual request performing a change with embedded markup. This approach has worked quite well for me, also I feel it'll make you troubleshooting and definition easier, as the controller is handing an object back to your JavaScript instead of a markup / view data. Which will be a better finite control for the frontend and clear modifications in future.
I have a "fault-counter" that stores a value of all incorrect answers. It starts at 0 and goes up one for every wrong answer.
I'm looking to have the results screen show the amount of faults you've made. So if the div #fault-counter has a value of 3, the end text will say "Sorry, you've made 3 faults!"
This is the code I've tried, but it doesn't seem to work. Any ideas on how to do this?
var faultcounter = $('#fault-counter');
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter') + ' faults!</h1>');
EDIT:
The HTML for the 'fault-counter' looks like this:
<div id="fault-display">
<div id="fault-counter">0</div>
<h3>FAULTS</h3>
</div>
And the jQuery being used to increase the value for every wrong answer is this:
$(".failQuestion").click(function(){
$('#fault-counter').html(function(i, val) { return val*1+1 });
});
Try this, as your fault-counter is a div than .text() should suffice.
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter').text() + ' faults!</h1>');
var faultcounter = $('#fault-counter').val();
$('#slickQuiz').prepend('<h1>Sorry, you have ' + faultcounter + ' faults!</h1>');
You'll have to grab the value from #fault-counter using .val() and then append the variable, instead of the jQuery selector to the #slickQuiz.
That being said, i'm assuming you're using an input or select for #fault-counter. Otherwise .text() would be sufficient
i think there is a problem :
var faultcounter = $('#fault-counter');
if $('#fault-counter') is a input control then use "VAL()" :
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter').val() + ' faults!</h1>');
OR
if $('#fault-counter') is a DIV control then use "html()" :
$('#slickQuiz').prepend('<h1>Sorry, you have ' + $('#fault-counter').html() + ' faults!</h1>');
var faultcounter = $('#fault-counter').text();
$('#slickQuiz').prepend('<h1>Sorry, you have ' + faultcounter + ' faults!</h1>');
This is what you want to use because you mentioned that #fault-counter is a div. If that's so then you'll want to use the .text method. If it's an input or textarea then use the .val method.
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.
I have the following code snipet:
document.getElementById('PS_FORM/SUBJECT_PROPERTY/Business_Comments').value = com_textcl + "\n" ;
document.getElementById('PS_FORM/SUBJECT_PROPERTY/Business_Comments').value = com_text;
I want each of the values to be in their own line. Is there a way to get this done??
Thanks
Assuming that element (PS_FORM/SUBJECT_PROPERTY/Business_Comments) is a textarea, then the JS should be:
document.getElementById('PS_FORM/SUBJECT_PROPERTY/Business_Comments').value=
com_textcl + "\n" + com_text;
If it's a SELECT the code would be different (update your question).
If it's a div or some other HTML element (rather than a FORM element) then the code would be more like:
document.getElementById('PS_FORM/SUBJECT_PROPERTY/Business_Comments').innerHTML=
com_textcl + "<br />\n" + com_text;