Javascript element name change reverting back to original - javascript

JavaScript name change of cloned input element "terminal0" isn't saving and/or reverting back to original name after function ends. All other name/id changes work but first element name change reverts back after function completes. Even the first element "terminal0" id change works successfully. I've tested and confirmed name change does work before function exits by placing an alert(cTerm.name) at the end of it. Anyone know reason why name change isn't working for first input element?
<tr id="tr1">
<td id="tr1Td0">
Terminal <input type="checkbox" name="terminal0" id="terminal0" value="0" onClick="cbUpdate()">
<br>
Imager <input type="checkbox" name="imager0" id="imager0" value="0" onClick="cbUpdate()">
</td>
</tr>
</tbody>
</table>
function addTable()
{
var gssTable = document.getElementById("gssTable");
var currTables = gssTable.rows[0].cells.length;
var selNum = document.getElementById("sNum").value;
var tr0 = document.getElementById("tr0");
var tr1 = document.getElementById("tr1");
var br = document.createElement('br');
for(x=currTables; x < selNum; x++)
{
var tr0Td0 = tr0.insertCell(-1);
var setID0 = document.getElementById("setID0");
var cSetID = setID0.cloneNode(true);
cSetID.id = "setID" + x;
cSetID.name = "setID" + x;
tr0Td0.appendChild(cSetID);
var tr1Td0 = tr1.insertCell(-1);
tr1Td0.innerHTML="Terminal";
var terminal0 = document.getElementById("terminal0");
var cTerm = terminal0.cloneNode(true);
cTerm.id = "test" + x;
cTerm.name = "test" + x;
tr1Td0.appendChild(cTerm);
tr1Td0.appendChild(br);
tr1Td0.innerHTML = tr1Td0.innerHTML + "Imager"
var imager0 = document.getElementById("imager0");
var cImager = imager0.cloneNode(true);
cImager.id = "imager" + x;
cImager.name = "imager" + x;
tr1Td0.appendChild(cImager);
}
while (currTables > selNum)
{
tr1.deleteCell(-1);
tr0.deleteCell(-1);
currTables = currTables - 1;
}

Setting the innerHTML makes the browser re-render that element and its contents. Since you are doing it each iteration of the loop, you are probably causing a race condition where innerHTML hasn't been updated to the latest effects of the appendChild calls above it.
So instead of setting innerHTML each time you can just create a Text node, with createTextNode, and append it.
tr1Td0.appendChild(document.createTextNode("Imager"));

Related

Sum values from dynamic inputs created in another function

I have this function (it works) to create a number of dynamic inputs:
<script type='text/javascript'>
var arr = [];
function espacioArreglos() {
// Number of inputs to create
var number = document.getElementById("cantidadArreglos").value;
// Container <div> where dynamic content will be placed
var container = document.getElementById("container");
// Clear previous contents of the container
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=0;i<number;i++){
// Append a node with a random text
container.appendChild(document.createTextNode("Arreglo #" + (i+1)));
// Create an <input> element, set its type and name attributes
var input = document.createElement("input");
input.type = "number";
input.name = "arreglo" + i;
//set ID to each input to calculate summatory
var inputId = 'input-' + i;
input.setAttribute('id', inputId);
arr.push(inputId);
input.setAttribute('onchange', function() {
var sum = 0;
arr.forEach(function(val) {
var inputVal = document.getElementById(val).value;
if (inputVal) sum += inputVal;
});
document.getElementById('totalPlacas').value = sum;
});
container.appendChild(input);
// Append a line break
container.appendChild(document.createElement("br"));
}
}
</script>
And now I want to display the sum of the input values. Here is the HTML:
<tr>
<td align="center" bgcolor="#D4D4D4">Cantidad de arreglos:</td>
<td align="center" bgcolor="#D4D4D4"><input type="number" id="cantidadArreglos" onchange="espacioArreglos();" size="1"></td>
</tr>
<tr>
<td align="center" bgcolor="#D4D4D4">Cantidad de placas:</td>
<td bgcolor="#FFFF00"><div id="container"/></td>
</tr>
<tr>
<td align="center" bgcolor="#D4D4D4">Total de placas:</td>
<td align="center" bgcolor="#D4D4D4"><div id="totalPlacas"></div></td>
</tr>
So, you enter a number in "Cantidad de arreglos", it calls the function "espacioArreglos" and then I want to use the values that I will enter on the generated inputs to calculate its summatory, which should be displayed at the div "totalPlacas". However, nothing appears... Whats the problem with my code?
There are some changes that need to be done:
First, change the
<div id="container"/> to <div id="container"></div> as the shortcut on a div breaks the HTML causing that totalPlacas doesn't exists.
Second, add the onchange event using
input.onchange = function() {...}
Now the result should be added to the 'totalPlacas' div using .innerText = sum instead using the .value = sum.
Now you can check that the result displayed is a concatenation of strings instead adding the numbers, this can be solved replacing
if (inputVal) sum += inputVal;
with
if (inputVal) sum += parseInt(inputVal);
You should add some kind of validation to avoid an error when the user types a letter or symbol instead a number.
Hope it works!
You will need to assign a unique ID to the input elements, so you can reference them using document.getElementById().
Something like:
input.setAttribute("id", 'input' + i);
How about assigning id's to the dynamic inputs and storing them in an array. First, outside of the function (global scope) define an empty array:
var arr = [];
In your for loop:
var inputId = 'input-' + i;
input.setAttribute('id', inputId);
arr.push(inputId);
input.setAttribute('onchange', function() {
var sum = 0;
arr.forEach(function(val) {
var inputVal = document.getElementById(val).value;
if (inputVal) sum += inputVal;
});
// do something with the sum
console.log(sum)
});

Can i call another function inside the GetElement in Javascript

I am trying to call another function inside the getElement but it is not working everything when i change my selection. When i select Car, in the textbox my varxumb should populate. Any idea...
document.getElementById("mycall1").insertRow(-1).innerHTML = '<td><select id = "forcx" onchange="fillgap()"><option>Select</option><option>Force</option><option>Angle</option><option>Area</option></select></td>';
function fillgap() {
var xnumb = 20;
var forcxlist = document.getElementById("forcx");
if (forcxlist == "Force") {
document.getElementById("result1").value = xnumb;
}
}
I don't know how this "Force" value is coming to check.
you can try these solutions.
if (forcxlist == "Force")
instead use
var forcxlistText = forcxlist.options[forcxlist.selectedIndex].text;
if (forcxlistText == "Force")
or use value technique
<div id ="mycall1">
</div>
<div id ="result1">
</div>
<script>
document.getElementById("mycall1").innerHTML = '<td><select id = "forcx" onchange="fillgap(this.value)"><option value="1">Select</option><option value="2">Force</option><option value="3">Angle</option><option value="4">Area</option></select></td>';
function fillgap(value){
var xnumb = 20;
if (value == "2"){
document.getElementById("result1").innerHTML = xnumb;
}
}
</script>
or use
<div id ="mycall1">
</div>
<input type="text" id="result1" value=""/>
<script>
document.getElementById("mycall1").innerHTML = '<td><select id = "forcx"><option value="1">Select</option><option value="2">Force</option><option value="3">Angle</option><option value="4">Area</option></select></td>';
document.getElementById("forcx").onchange = function (){
var xnumb = 20;
var forcxlist = document.getElementById("forcx");
var forcxlistValue = forcxlist.options[forcxlist.selectedIndex].value;
if (forcxlistValue == "2"){
document.getElementById("result1").value = xnumb;
}
}
</script>
The forcxlist variable is an element object, returned by the document.getElementById method. Afterwards, you are checking if this element object is equal to "Force", which is a string (meaning the contents of your if block will never be executed). Did you mean to check if the contents of that object are equal to Force?
Instead of
if (forcxlist == "Force"){
use
if (forcxlist.innerHTML == "Force"){
I hope this helps!
Can't use innerHTML so i changed it to .value
document.getElementById("result1").value = xnumb;
There are a couple issues here.
First, you are expecting forcxlist to be a string, not an element, so you need to use .value to get the selected value of the dropdown.
Second, you should do your comparison with === not ==, as this ensures type equality as well, and is best practice.
I would also recommend building your select using HTML elements. It keeps things cleaner, is more readable, and is easier to maintain.
Since you are using the same id for the select, you would have to change the selector in your fillgap handler to var forcxlist = e.target.value;, this way the event will fire based on only the select that you are interacting with, regardless of how many rows you have in the table.
Updated code is below, and an updated working fiddle here. As per your comment about adding additional rows, the fiddle has this working as well.
<input type="button" value="Add Row" onclick="addDropDown()">
<table id="mycall1"></table>
<script>
function addDropDown() {
var tbl = document.getElementById("mycall1");
var newRow = tbl.insertRow(-1);
var newCell = newRow.insertCell(0);
newCell.appendChild(createDropDown("forcx", fillgap));
}
function createDropDown(id, onchange) {
var dd = document.createElement('select');
dd.id = id;
dd.onchange = onchange;
createOption("Select", dd);
createOption("Force", dd);
createOption("Angle", dd);
createOption("Area", dd);
return dd;
}
function createOption(text, dropdown) {
var opt = document.createElement("option");
opt.text = text;
dropdown.add(opt);
}
function fillgap() {
var xnumb = 20;
var forcxlist = e.target.value;
if (forcxlist === "Force") {
document.getElementById("result1").value = xnumb;
}
}
</script>
<input type="text" id="result1">

Passing array -- scope

I want to pass an array from one external .js file to another.
Each of these files works fine by themselves, but I am having a problem passing the array from pickClass.js to displayStudent.js, and getting the names and "remaining" value to display in the html file. I know it has something to do with how the arrays are declared, but I can't seem to get it to work properly.
The first file declares the array choice:
(masterStudentList.js):
var class1 = ['Brown, Abe','Drifter, Charlie','Freed, Eve'];
var class2 = ['Vole, Ug','Xylo, William','Zyzzyx, Yakob'];
The second picks which array to use based on the radio buttons (pickClass.js):
var classPicked = array(1);
function randomize(){
return (Math.round(Math.random())-0.5); }
function radioResult(){
var chooseClass = document.getElementsByName("chooseClass");
for (i = 0; i < chooseClass.length; i++){currentButton = chooseClass[i];
if (currentButton.checked){
var selectedButton = currentButton.value;
} // end if
} // end for
var output = document.getElementById("output");
var response = "You chose ";
response += selectedButton + "\n";
output.innerHTML = response;
chosenClass = new Array();
if (selectedButton == "class1")
{chosenClass = class1;}
else
{chosenClass = class2;}
var text = "";
var nametext = "";
var i;
for (i = 0; i < chosenClass.length; i++) {
text += chosenClass[i]+ ' / ';
}
var showText = "";
l = chosenClass.length;
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
//return = classPicked;
document.getElementById("classList").innerHTML = classPicked;
} // end function
This works properly.
I then want to pass "classPicked" to another .js file (displayStudent.js) which will randomize the student list, loop and display the students for a few seconds, and then end with one student name.
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5); }
function showBasket(){
mixedBasket = basket.sort( randOrd ); //randomize the array
var i = 0; // the index of the current item to show
document.getElementById("remaining").innerHTML = basket.length;
fruitDisplay = setInterval(function() {
document.getElementById('showStud')
.innerHTML = mixedBasket[i++]; // get the item and increment
if (i == mixedBasket.length) i = 0; // reset to first element if you've reached the end
}, 100); //speed to display items
var endFruitDisplay = setTimeout(function()
{ clearInterval(fruitDisplay);
var index = mixedBasket.indexOf(document.getElementById('showStud').innerHTML);
mixedBasket.splice(index,1);
}, 3500); //stop display after x milliseconds
}
Here is the html (master.html). It's just rough -- I'll be working on the layout later:
<html>
<head>
<script src="masterStudentList.js" type="text/javascript"></script>
<script src="pickClass.js" type="text/javascript"></script>
<script src="displayStudent.js" type="text/javascript"></script>
</head>
<body>
<h2>Choose Class</h2>
<form action = "">
<fieldset>
<input type = "radio"
name = "chooseClass"
id = "radSpoon"
value = "class1"
checked = "checked" />
<label for = "radSpoon">Class 1</label>
<input type = "radio"
name = "chooseClass"
id = "radFlower"
value = "class2" />
<label for = "radFlower">Class 2</label>
<button type = "button"
onclick = "radioResult()"> Choose Class
</button>
<div id = "output">
</fieldset>
</form>
</div>
<center>
<h1> <span id="chooseStud"></span><p></h1>
<script> var fruitSound = new Audio();
fruitSound.src = "boardfill.mp3";
function showFruitwithSound()
{
fruitSound.play(); // Play button sound now
showBasket()
}
</script>
Remaining: <span id = "remaining" ></span>
<p>
<button onclick="showFruitwithSound()">Choose Student</button>
</center>
pickedClassList = <p id = classList> </p>
</body>
</html>
You shouldn't use global variable like this (I encourage you to read more on this theme) and I'm not sure I understand what you're trying to do... but the solution of your issue should be to move the basket = classPicked; line into your showBasket method :
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
// whatever
}
should be :
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
basket = classPicked; //This is where the array should be passed
// whatever
}
This way, each time you call showBasket, this method will use the last value of classPicked.
Otherwise, basket will always keep the reference on the first value of classPicked.
Why ? because each time you assign a new Array to the basket variable (classPicked = Array(l);) instead of changing directly it's content by :
emptying it : while (classPicked.length > 0) { classPicked.pop(); }
and then adding new data : classPicked.concat(chosenClass)
You can't pass things to files; you could call a function defined in displayStudent.js, pass it classPicked, and have it assign it to basket.
I noticed this at the end of your second chunk of code ...
} // end function
This could indicate the classPicked is declared inside a function (I don't see one on the code). Because it is inside function scope, your set of code that is trying to use it cannot.
Push the declaraction of classPicked outside of the function.
var classPicked = Array(1);
function thisusesclasspicked() {
...
Also, please start indenting your code properly, it will become much easier to maintain and read.
UPDATE FROM COMMENTS:
I see the declaration now ...
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
... however, you are re-assigning the array with an element of one just before you attempt to make modifications to it ... You are emptying it there: classPicked = Array(l);

Keeps returning [object HTMLSpanElement]? (Javascript)

Ok so im trying to add two (or more) variables and make it appear in a table cell.
I get the variables from lets say the 1st and 2nd cells and i want to display them on the 7th cell, so this is what i have for now.
This is the basic code for the cell that gets the info.
function prompta1()
{
var a1=prompt("Unesi broj","")
var spana1 = document.getElementById ("spana1");
spana1.innerHTML = a1;
function prompta2()
{
var a2=prompt("Unesi broj","")
var spana2 = document.getElementById ("spana2");
spana2.innerHTML = a2;
And this is the code for the cell that needs to show them.
function functiona7()
{
var a7= spana1+spana2;
var spana7 = document.getElementById ("spana7");
spana7.innerHTML = a7;
}
Now , when i try this it only gives.
[object HTMLSpanElement][object HTMLSpanElement]
Please help!
HTML for getting the values
enter code here <tr>
<td><h1>1</h1></td>
<td><input type="button" onclick="prompta1()" value="Izmeni"> <br> <span id='spana1'></span></td>
<td><input type="button" onclick="prompta2()" value="Izmeni"> <br> <span id='spana2'></span></td>
</tr>
<tr>
HTML for showing the value
<td> <input type="button" onclick="functiona7()" value="Izracunaj"> <br> <span id='spana7'></span> </td>
Try something like this:
function prompta1() {
var a1 = prompt("Unesi broj", "");
var spana1 = document.getElementById("spana1");
spana1.innerHTML = a1;
}
function prompta2() {
var a2 = prompt("Unesi broj", "");
var spana2 = document.getElementById("spana2");
spana2.innerHTML = a2;
}
function functiona7() {
var spana1 = document.getElementById("spana1").innerHTML;
var spana2 = document.getElementById("spana2").innerHTML;
var spana7 = document.getElementById("spana7");
if (!(spana1 && spana2 && spana7)) return;
var a7 = spana1 + spana2;
spana7.innerHTML = a7;
}
Fiddle
In your current example the values for spana1/2 are not pulling from the DOM, so first they need to be populated using getElementById, after that a simple combination of the Inner Html is all that is needed (although you may want to add a space in between too).

How to get the html element from jquery object

I have a html like follows.
<tr class="meta-info" id="${page.id}">
<td>
<div class="pull-left">
<font size="1">
Like
</font>
</div>
<div class="pull-right" style="font-size:1">
<span class="badge"><i class="icon-thumbs-up"></i>1</span>
</div>
</td>
</tr>
I am trying to increase the number of likes when ever the user cliks on Like hyperlink.
Here is my jquery code. I want to know how i can get the html element from the jquery object.
$(".like").click(function(event){
var parentTr = $(event.target).closest("tr");
if(parentTr.length){
var pageId = parentTr.attr("id");
var spanEle = parentTr.get(0)+" div span:first-child"; ------(1)
var lastNumber = parseInt(spanEle.text());
spanEle.text(lastNumber+1);
}
});
I don't know if i am doing right on line which is marked 1.
I think you need to add an extra <span> tag so that you can replace the count without touching the adjacent icon
<span class="badge"><i class="icon-thumbs-up"></i>
<span class="like-count">1</span>
</span>
then you can address it
$(".like").click(function() {
var spanEle = $(this).closest('tr').find('.like-count').first();
if (spanEle.length) {
var newCount = parseInt(spanEle.text());
spanEle.text(newCount + 1);
}
});
In an event handler, the this reference is event.target. You may be able to handle the element doesn't exist case neater than that too but that way's safe.
JSFiddle demo: http://jsfiddle.net/rupw/VfCvK/
Try this...
$(".like").click(function(event) {
var parentTr = $(event.target).closest("tr");
if (parentTr.length) {
var pageId = parentTr.attr("id");
var spanEle = parentTr.first('.badge');
var lastNumber = parseInt(spanEle.text(), 10);
spanEle.text(lastNumber + 1);
}
});
If the span element always has that classname then it will find the first (only?) one and return an int value of the text within.
Try: Fiddle
var lastNumber = parseInt(parentTr.find('.pull-right span').text(), 10);
You code will look like:
$(".like").click(function(event) {
var parentTr = $(event.target).closest("tr");
if (parentTr.length) {
var pageId = parentTr.attr("id");
var spanEle = parentTr.find('.pull-right span');
var lastNumber = parseInt(spanEle.text(), 10);
spanEle.text(lastNumber + 1);
}
});
Update: If you wish to keep the <i> tag then use:
spanEle.html(spanEle.html().replace(lastNumber, lastNumber + 1));
insteadof : spanEle.text(lastNumber + 1);
Sample

Categories

Resources