Create a table with several <tr> with different classes - javascript

I put them in context:
I need to create a table that has several , whose class I want to be different. It should be clarified that I am using javascript for this and I use the append function for this.
This is the code I currently have :
function my_function() {
$(document).ready(function() {
var number = 0;
var num = ++number;
$("#my_table> tbody").append("<tr class='tr" + num + "'><td class='center'>" + "HELLO WORLD" + "</td></tr>");
}
})
}
When I run it the result is 1, but when I call the function again it is still 1 instead of increasing the value back to 2.
The function is being called frequently so it should increase the value again but it doesn't. Now, I need you to increase the value multiple times without only doing it once. So that the second has class tr2. Thank you if you answer or give a solution.

You're declaring the variable inside the function so it will be reassigned var number = 0; every time you call it, declare it outside of it and it should work as you expect it to do.

Related

JS Function calling displaying odd text & not working more than once

I have a problem, when I run my function "addMoney(amount)" (shown below) it works and shows the following: 100[object HTMLButtonElement]
My question is this, is there a way to get rid of the [object HTMLButtonElement] while keeping the number from moneyAmount when the function is called? And additionally, is there a way to call the function multiple times and add the money accordingly? As it only works the first time I call it, calling it more than once with the same or different amounts of moneyAmount displays no more or no less than what displays the first time.
My HTML:
<li class="item_shown" id="money">Shrill: <button class="moneyButton" id="moneyAmount">0</button></li>
Calling the function in HTML:
<a class="button" onclick="javascript:addMoney('100');">Add 100 Money</a>
My JS Function:
function addMoney(amount) {
document.getElementById('moneyAmount')
var newBalance = amount + moneyAmount;
document.getElementById('moneyAmount').innerHTML = newBalance;
}
The text inside an element is considered to be a text node and since the button node has no other children, is the button node's first child. The text node's value (in this case "0") is the value of its nodeValue property. Assigning a new value to the nodeValue will change the text displayed. So in your case the following code should work:
function addMoney(amount) {
var node = document.getElementById('moneyAmount');
var textNode = node.childNodes[0];
var moneyAmount = parseInt(textNode.nodeValue, 10);
textNode.nodeValue = amount + moneyAmount;}
In your JavaScript, + moneyAmount; does not do anything. It returns what you see: [object HTMLButtonElement].
I think you want to add some numbers but it's not yet completely clear to me what you're trying to achieve. Could you elaborate?
Chris
EDIT:
Thank you for clarifying your question.
Try updating your function like this:
function addMoney(amount) {
var oldBalance = document.getElementById('moneyAmount').value;
var newBalance = amount + oldBalance;
document.getElementById('moneyAmount').innerHTML = newBalance;
}
Try to find value by document.getElementById('moneyAmount').innerHTML and use some global variable say total_value to store retrieved value and then for each function call try to add the retrieved value to the previously stored value.

dynamically generated js buttons with closures to assign onclick function parameters

I am running into a problem people have posted before: JavaScript dynamic parameters
But my code uses nodes rather than innerHTML assignments, so the existing SO post doesn't seem to apply to my code.
I want to dynamically generate HTML buttons in a table. For each button, I want to call a function with parameters that depend on the button's index/position in the table. First I tried just using lambda functions with the variable over which I was incrementing. This didn't work, so I also tried dynamically named variables, meaning each button should be passing a differently named variable to deal with lazy-loading effects. But this didn't work either. You can see both versions of what I tried in the code below:
This code I paste below is in a for-loop. In the following, I increase i by 1 each time. offset and jj are unchanged within the loop.
var variableDynamic = i.toString();
window['variableName' + variableDynamic] = i + offset;
upvote.onclick = function() {
upVoteA(i + offset, jj);
//upVoteA(window['variableName' + variableDynamic] , jj);
};
upvote.innerHTML = "Upvote"
Someone told me to look into closures, so following this recommendation: http://www.usepatterns.com/blog/javascript-closures I rewrote the onclick function declaration as:
upvote.onclick = function() {
var a = i + offset;
var b = kk;
function closeIt(){
upVoteA(a,b);
}
closeIt();
};
This still has the same effect that every button calls upVoteA with the same parameter, namely the last/highest value.
I realize I could refactor my code to turn these into .innerHTML set statements and then I'd print the variable and it would be set as a printed statement instead of a lazily-loaded variable. But I'd like not to do that if possible. (apologies that it's not technically lazy loading, the name seems reasonably apt)
Is there a way to make my code work? And why are the closures failing? I thought closures should preserve the environment they were created in, but that is not the case with my code. Which portion of the "environment" are preserved with closures?
This is a very bad answer, but it works
var funcStr = "function dummy() { upVoteA(" + (i + offset) + "," + jj + "); }";
eval(funcStr);
upvote.onclick = dummy;
But if you have something better, please let me know.

Javascript passing elementid in variable

I need to pass a variable to a javascript function which will then perform calculations and return the answer to another edit box on a form. I need to pass as I have 10 lines of edit boxes and dont want to have 10 seperate javascript functions.
function calc_totalcost(line)
{
$line_qty=line+"_qty";
$line_totcost=line+"_totcost";
$line_unitcost=line+"_unitcost";
$totcost=$line_qty.value*$line_unitcost.value;
document.getElementById('$line_totcost').value = $totcost;
}
on the html:
onchange="calc_totalcost('L1')"
So, on editbox 1 for L1_edit1 I need to send L1 to the function, which will then convert to 'L1_qty' which is an editbox (input) name where it will perform calculations using its contents. Hope that makes sense?
Thanks
You have a few issues, including the last line in the function which does not need the document.getElementById whereas all the others do need it.
function calc_totalcost(line) {
var $line_qty = document.getElementById(line+"_qty");
var $line_totcost = document.getElementById(line+"_totcost");
var $line_unitcost= document.getElementById(line+"_unitcost");
var $totcost=$line_qty.value*$line_unitcost.value;
$line_totcost.value = $totcost;
}

About a loop that creates dynamic buttons, but cannot give proper values [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript infamous Loop problem?
I am having a small issue, and it would be very nice if some of you could realize about what kind of logic is missing here, since I cannot seem to find it:
I have an array with the results of some previous operation. Let's say that the array is:
var results = [0, 1];
And then I have a bunch of code where I create some buttons, and inside a for loop I assign a different function to those buttons, depending on the position of the array. The problem is that for some reason, all the buttons created (two in this case) come out with the function assigned to the last value of the array (in this case, both would come out as one, instead of the first with 0 and the second with 1)
This is the code:
for (var i = 0; i < results.length; i++) {
var br2 = b.document.createElement("br");
var reslabel = b.document.createTextNode(Nom[results[i]].toString());
var card = document.createElement("input");
card.type = "button";
id = results[i]; // this is the problematic value.
card.onclick = newcard; // this function will use the above value.
card.value = "Show card";
divcontainer.appendChild(br2);
divcontainer.appendChild(reslabel);
divcontainer.appendChild(card);
}
As it is, this code produces as many buttons as elements in the array, each with its proper label (it retrieves labels from another array). Everything is totally fine. Then, I click the button. All the buttons should run the newcard function. That function needs the id variable, so in this case it should be:
First button: runs newcard using variable id with value 0
Second button: runs newcard using variable id with value 1
But both buttons run using id as 1... why is that?
It might be very simple, or maybe is just that in my timezone is pretty late already :-) Anyways, I would appreciate any comment. I am learning a lot around here...
Thanks!
Edit to add the definition of newcard:
function newcard() {
id = id;
var toerase = window.document.getElementById("oldcard");
toerase.innerHTML = "";
generate();
}
the function generate will generate some content using id. Nothing wrong with it, it generates the content fine, is just that id is always set to the last item in the array.
Your id is a global variable, and when the loop ends it is set to the last value on the array. When the event handler code runs and asks for the value of id, it will get that last value.
You need to create a closure to capture the current results[i] and pass it along (this is a very common pitfal, see Javascript infamous Loop problem?). Since newcard is very simple, and id is actually used in generate, you could modify generate to take the id as a parameter. Then you won't need newcard anymore, you can do this instead:
card.onclick = (function(id) {
return function() {
window.document.getElementById("oldcard").innerHTML = "";
generate(id);
};
}(results[i]));
What this does is define and immediately invoke a function that is passed the current results[i]. It returns another function, which will be your actual onclick handler. That function has access to the id parameter of the outer function (that's called a closure). On each iteration of the loop, a new closure will be created, trapping each separate id for its own use.
Before going on, a HUGE thank you to bfavaretto for explaining some scoping subtelties that totally escaped me. It seems that in addition to the problems you had, you were also suffering from scoping, which bit me while I was trying to craft an answer.
Anyway, here's an example that works. I'm using forEach, which may not be supported on some browsers. However it does get around some of the scoping nastiness that was giving you grief:
<html>
<body>
<script>
var results = [0,1];
results.forEach( function(result) {
var card = document.createElement("input");
card.type = "button";
card.onclick = function() {
newcard( result );
}
card.value = "Show card";
document.body.appendChild(card);
});
function newcard(x) {
alert(x);
}
</script>
</body>
</html>
If you decide to stick with a traditional loop, please see bfavaretto's answer.

Hooking into the change() event on jQuery .toChecklist

I'm experiencing a problem when I attempt to use the .change() event on select lists, using the jQuery .toChecklist plugin.
My page contains a number of select lists, which are changed to CheckLists, using jQuery.
Consider the following Javascript snippet:
for (var i=0;i<5;i++)
{
var selectListId = 'selectList' + i;
// Assume this line represents the outputting on a
// standard select list
// Convert to Checklist
$("#" + selectListId).toChecklist();
$("#" + selectListId).change
(
function ()
{
alert("SelectListId: " + selectListId);
}
);
}
For each iteration of this loop, I output a multi-select list, convert it to Checklist, and then add the .change() handler.
However, when the page renders (visually, everything is fine), choosing an option from ANY of the lists gives the alert text of "SelectListId: selectList4" (ie. the last list id of the loop). Thus it appears that each invocation of .change() globally replaces the change handler.
Does anyone know how to change the code so that each checklist has its own change handler (so that the first change handler would output "SelectListId: selectList0", etc).
Thanks,
Try pulling the change function out of the loop. I also added a line that adds a class to each list. The new change function references the lists by the class and will know which is actively being changed via this.
for (var i = 0; i < 5; i++) {
var selectListId = 'selectList' + i;
$("#" + selectListId).toChecklist();
$("#" + selectListId).addClass('newChecklist');
}
$('.newChecklist').change(function() {
alert( $(this).attr('id') );
});
So, after a lot of head scratching, I've found a work-around for this issue.
While concatenating strings together in the anonymous function behaves in an unexpected manner, quoting the whole line of code and wrapping it in an eval statement produces the required results.
Thus, instead of writing, as above:
$("#" + selectListId).change
(
function ()
{
alert("SelectListId: " + selectListId);
}
)
You would need to write this instead:
eval('$("#' + selectListId + '").change(function (){alert("SelectListId: ' + selectListId + '");});');
This may not be the best approach, but it works, and for now that's good enough! :-)

Categories

Resources