Automatic multiplication for several row - javascript

I'm new on coding, then any help will greatly appreciated.
I'm trying to make automatic multiplication from 2 value. Basically my table looks like this. Multiplication works perfectly on the first row. If I make another row by simply copying this code:
<tr>
<td><input id="box1" type="text" oninput="calculate()" /></td>
<td><input id="box2" type="text" oninput="calculate()" /></td>
<td><input id="result" /></td>
</tr>
then the second row won't work. This may happen because the id on second row exactly same with the first row. But if I change the id, the script won't work either. Would you please show me how to fix it?
EDIT: I use this scrip for multiplication purpose:
function calculate() {
var myBox1 = document.getElementById('box1').value;
var myBox2 = document.getElementById('box2').value;
var result = document.getElementById('result');
var myResult = myBox1 * myBox2;
result.value = myResult;
}

I would bind a single input event handler to the table, which will catch any input events on any of the table cells' input elements. Within the handler event.target will refer to the input element where the event originated, and you can use DOM navigation properties/methods to find the associated table cells in the same row.
Maybe a little something like this, using class instead of id:
document.getElementById("multiplier").addEventListener("input", function(e) {
var row = e.target.parentNode.parentNode
var val1 = row.querySelector(".valOne").value
var val2 = row.querySelector(".valTwo").value
row.querySelector(".result").value = val1 * val2
})
<table id="multiplier">
<tr>
<td><input class="valOne" type="text" /></td>
<td><input class="valTwo" type="text" /></td>
<td><input class="result" /></td>
</tr>
<tr>
<td><input class="valOne" type="text" /></td>
<td><input class="valTwo" type="text" /></td>
<td><input class="result" /></td>
</tr>
<tr>
<td><input class="valOne" type="text" /></td>
<td><input class="valTwo" type="text" /></td>
<td><input class="result" /></td>
</tr>
</table>
Further reading:
.addEventListener() method
.parentNode property
.querySelector() method
It would be better to use e.target.closest("tr") instead of e.target.parentNode.parentNode, but note that the .closest() method isn't supported in IE so you would need to use a polyfill.
Note that the JS that I've shown would need to be in a script element that is after the table (e.g., at the end of the body right before the closing </body> tag), or you'd need to wrap it in a document load or DOMContentLoaded handler.

Related

JS Function only appends one row

I would like my js to add a row every time the user adds their initials. My code works the first time the user enters their initials, a new row is created under the first row, but then does not add anymore. I am not sure what i need to do.
My JS code:
(function(){
var counter = 1;
$("#preformedBy").change(function(){
$('#timeStamp').html(new Date().toLocaleString());
$('#harvestedCannabis > tbody:last-child').append('<tr><td><input type="number" id="toteNum" readonly></td><td><input type="number" step=".1">' +
'</td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td>' +
'<input type="text"></td><td><input type="text" id="preformedBy"></td><td id="timeStamp"><input type="text" readonly></td></tr>');
counter = counter + 1;
$('#toteNum').html(counter)
})
});
My HTML:
<table id="harvestedCannabis">
<tr>
<th>Tote #</th>
<th>Flowers</th>
<th>Trim A</th>
<th>Trim B</th>
<th>Waste</th>
<th>Originating Line(A,B,C)</th>
<th>Preformed By</th>
<th>Time Stamp</th>
</tr>
<tr>
<td id="toteNum"><input type="number" value="1" readonly></td>
<td><input type="number" step=".1"></td>
<td><input type="number" step=".1"></td>
<td><input type="number" step=".1"></td>
<td><input type="number" step=".1"></td>
<td><input type="text"></td>
<td><input type="text" id="preformedBy"></td>
<td id="timeStamp"><input type="text" readonly></td>
</tr>
</table>
I would like the table to keep appending new row as many times as the user requires, automatically after they insert their initials
You have two main issues with your code. I'll explain them, but first take a look at this fiddle I made with your code, this version actually works:
https://jsfiddle.net/49Ln0qcf/#&togetherjs=2hdIlfBaC0
So now lets explore where you went wrong:
1.
You're listening to an ID attribute for your onChange event. It works the first time around because at that point in time you only have one element with id="preformedBy", but after you add your second row you then have TWO elements with the same ID. jQuery is listening to the first instance of the ID in the dom, thus your additional input fields are not being listened to. So, replace your id attribute with a class, then your .preformedBy selector will work past your second iteration.
2.
Taking the step above alone will not fix your code. To get more than the first iteration to work, you'll need to listen to the parent element of your .preformedBy class. In your code, you're listening to preformedBy directly like so:
$("#preformedBy").change(function(){
The problem here is that on page load, jquery is only aware of the dom elements that exist on page load, thus the first and only instance of preformedBy. So jQuery will continue to listen to that element and ONLY that element because it knows nothing of the elements you've added to the dom AFTER page load. In order to get jQuery to listen to ALL instances of preformedBy, you need to listen to a parent selector. Notice in my code, I'm listening to preformedBy like so:
$("#harvestedCannabis").on('change', '.preformedBy', function(){
The key difference is that my code listens to change events on the parent element, but specifically listens to any and all occurrences of '.preformedBy' within that parent element. As where your code is listening to a unique element with the preformedBy selector.
I hope this helps.
Finalized code that works:
html:
<table id="harvestedCannabis">
<tr>
<th>Tote #</th>
<th>Flowers</th>
<th>Trim A</th>
<th>Trim B</th>
<th>Waste</th>
<th>Originating Line(A,B,C)</th>
<th>Preformed By</th>
<th>Time Stamp</th>
</tr>
<tr>
<td id="toteNum1"><input type="number" value="1" readonly></td>
<td><input type="number" step=".1"></td>
<td><input type="number" step=".1"></td>
<td><input type="number" step=".1"></td>
<td><input type="number" step=".1"></td>
<td><input type="text"></td>
<td><input type="text" class="preformedBy"></td>
<td id="timeStamp1"><input type="text" readonly></td>
</tr>
</table>
jQuery:
var counter = 1;
$("#harvestedCannabis").on('change', '.preformedBy', function(){
$('#timeStamp'+counter).html(new Date().toLocaleString());
$('#harvestedCannabis > tbody:last-child').append('<tr><td><input type="number" id="toteNum'+(counter + 1)+'" readonly></td><td><input type="number" step=".1">' +
'</td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td>' +
'<input type="text"></td><td><input type="text" class="preformedBy"></td><td id="timeStamp'+(counter + 1)+'"><input type="text" readonly></td></tr>');
$('#toteNum'+(counter + 1)).val(counter + 1);
counter = counter + 1;
});
Your are changing all this element #toteNum with counter value
<td id="toteNum"><input type="number" value="1" readonly></td>
When you create a new element you need to rebind the listeners.
When your code works, your HTML will have 2 #preformedBy elements, you may have unique ids on the same page.
Try the insertRow() and insertCell() methods.
According to W3Schools example:
https://www.w3schools.com/jsref/met_table_insertrow.asp
Remove the id from your html and js code and use a class selector to trigger the change function, then it should work.

Issue regarding cloneNode in javascript

I am using javascript cloneNode method to clone a table row which is actually hidden. But the row is being cloned with that hidden property. I dont want that. I want that when that row will be cloned it will have visibility on.
That particular table row is:
<tr style="visibility:hidden;">
<td><input size=25 type="text" id="latbox"/></td>
<td><input size=25 type="text" id="latbox"/></td>
<td><input size=25 type="text" id="latbox"/></td>
<td><input size=25 type="text" id="latbox"/></td>
<td><input size=25 type="text" id="latbox"/></td>
<td><img alt="Icon" src="/assets/add-icon.png" id="addmorePOIbutton" onclick="insRow()" /></td>
<td><img alt="Icon" src="/assets/minus-icon.png" id="delPOIbutton" onclick="deleteRow(this)"/></td>
</tr>
And the javascript code where I am cloning this row is:
var x=document.getElementById('POITable');
var new_row = x.rows[1].cloneNode(true);
x.appendChild( new_row );
So, how to set, rather control the style of the new cloned row?
Please give some hints.
Please give me javascript solutions only (no jquery). I need to develop the project using javascript.
First, use 0 instead 1 for the index.
next you can set style visibility to visible before adding the row to the table.
var x=document.getElementById('POITable');
var new_row = x.rows[0].cloneNode(true);
new_row.style.visibility = "visible";
x.appendChild( new_row )
Here is a fiddler

Using javascript to get a value from html input

I am new to this forum and I want to be able to get a value from my html inputs into javascript. Right now i have this code:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PWS</title>
</head>
<body bgcolor="#009933" text="#FFFFFF">
<H1 align="center">PWS Julia en Sophie</H1>
<hr>
<br>
<strong>DOUCHE</strong>
<table>
<tr>
<td>Temperatuur</td>
<td><input type="text" name="dtemp" onClick="calculateTotal()" /></td>
</tr>
<tr>
<td>Tijd</td>
<td><input type="text" name="dtijd" onClick="calculateTotal()" /></td>
</tr>
<tr>
<td>Hoe vaak per week</td>
<td><input type="text" name="dfreq" onClick="calculateTotal()" /></td>
</tr>
</table>
<br>
<strong>BAD</strong>
<table>
<tr>
<td>Temperatuur</td>
<td><input type="text" name="btemp" onClick="calculateTotal()" /></td>
</tr>
</tr>
<tr>
<td>Hoe vaak per week</td>
<td><input type="text" name="bfreq" onClick="calculateTotal()" /></td>
</tr>
</table>
<script type="text/javascript">
var dTemp = document.getElementsByName("dtemp").value;
document.write(dTemp);
</script>
obviously, its not working. Because the dTemp value stays undefined.
Can anyone help me, thanks in advance,
Bob
document.getElementsByName returns an array, so you have to reference the position of the element:
var dTemp = document.getElementsByName("dtemp")[0].value;
I would also recommend giving ID's to your inputs, since it seems that each name is unique in your case, that way you could use document.getElementById
document.getElementsByName("dtemp") will give you array of elements, traverse through one by one and get the value from it.
var elements = document.getElementsByName("dtemp");
var firstValue = elements[0].value;
1) You need to index the result of getElementsByName, as described in other answers; append [0] to document.getElementsByName("dtemp").
2) You can’t use document.write in code that is executed after the page has loaded. It would replace the current document by the written content. Write to an element instead.
3) You have not defined the function calculateTotal at all. Wrap your JavaScript code in a function, e.g.
<div id=result></div>
<script>
function calculateTotal() {
var dTemp = document.getElementsByName("dtemp")[0].value;
document.getElementById('result').innerHTML = dTemp; }
</script>
4) You have a long way to go, since now your code makes no attempt at calculating anything, you should hardly use onclick on an input element to start the calculation (rather, onchange on it, or onclick on a separate button element). You should read a good JavaScript primer, really.

JavaScript: how to access the textbox in the second row of the table

I have an html code like this -
<table border="0" cellspacing="2" cellpadding="2" width="99%" id="subAccTable">
<tr>
<h2>Sub Accounts</h2>
</tr>
<tr>
<th>action </th>
<th>account</th>
<th>homeDir</th>
<th>primaryGroup</th>
</tr>
<tr>
<td><input type="hidden" name="vtierId" value="" /></td>
<td><input type="text" name="subAcc"
value=""/></td>
<td><input type="text" name="subHomeDir"
value=""/></td>
<td><input type="text" name="subPriGroup"
value=""/></td>
</tr>
</table>
Now i want to fill the values of textboxes named subAcc, subHomeDir, subPriGroup using javascript. How can i do it ?
There are multiple ways to get the proper DOMElement; including:
Giving each element an id and getting it using document.getElementById
Using document.getElementsByName. This is not preferred since there can be multiple elements with the same name, however there can be only one with the same id.
Using the form directly. For example if your form's name is form1: form1.subAcc
Using document.getElementsByTagName('input') and then getting the proper index.
I'd recommend using the id to retrieve the proper element.
The easiest way would be to give these textboxes a unique id, then reference them like this:
<input type="text" id="subHomeDir" name="subHomeDir" value=""/>
var tb = document.getElementById("subHomeDir");
tb.value = "foo";
If you're stuck with the names only, then you can use document.getElementsByName, just remember, this will return a collection of elements (since names are not necessarily unique), which you'll have to index:
var tb = document.getElementsByName("subHomeDir")[0];
tb.value = "foo";

Alternative to Jeditable for editable table cells

I have been trying to use Jeditable to make my html table editable. However upon much research I found that it is very difficult (if not impossible without a backend) to validate the input.
I really would prefer NOT to use any sort of plugin and simply write/use a bit of Javascript that would make cells editable and allow me to attach jQuery Validator to the input. The data will never get submitted to a backend (will return to default on page refresh) so the solution doesn't need to be complex...will only be using html and Javascript.
The problem with most code snippets I have found using Google is that they seem to get stuck when you click inside a cell and clicking outside the cell doesn't save/submit the change.
Does anyone have a snippet they have used successfully and/or experience using a snippet with Validator?
Well, according to information I got in your another question, you can change that function to:
function appendTable(id)
{
var tbody = document.getElementById(id).getElementsByTagName("tbody")[0];
var i = 0;
var rows = tbody.rows;
for (var r = 0; r < 4; r++) {
var row = rows[r];
for (var c = 0; c < 4; c++) {
var cell = row.cells[c];
cell.firstChild.value = subset[i++]; // the only part changed
}
}
}
when your html looks like:
<table id="alphabetTable" border="1">
<thead>
<tr>
<th>Header1</th>
<th>Header2</th>
<th>Header3</th>
<th>Header4</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
</tr>
<tr>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
</tr>
<tr>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
<td><input type = "text" size="1" /></td>
</tr>
</tbody>
</table>
As you could see, I rely on firstChild property, however it can be dangerous, e.g. when your html looks like:
<td> <input type = "text" size=1 /> </td>
then at least FF returns <TextNode textContent=" "> as firstChild. Not to depend on this issue you can go with:
cell.getElementsByTagName("input")[0].value = subset[i++];
PS. All I wrote was based on info I got from another question, if something wrong - comment and I will try to change ;)

Categories