Adding contentEditable items together with JavaScript - javascript

Update: Put in more context.
Update 2: The sum isn't adding correctly now, and the initial sum doesn't appear until I edit one of the values.
I am trying to add contentEditable items from a table in JavaScript.
The three rows I'd like to add are named "string1", "string2", and "string3", and "total" is the id of the row that displays the sum of all three strings.
I attempted to use parseInt to add the numerical values of the numbers already in the table, but the total sum is incorrect for some reason. Also, the the sum of the initial set of numbers is blank until I one of the values. How do I get it to appear when I open the file?
Below is the code:
<body>
<table>
<tr>
<td>First:</td>
<td id="string1" oninput="myFunction()">100</td>
</tr>
<tr>
<td>Second:</td>
<td id="string2" oninput="myFunction()">200</td>
</tr>
<tr>
<td>Third:</td>
<td id="string3" oninput="myFunction()">100</td>
</tr>
<tr>
<td>Sum</td>
<td id="total"></td>
</tr>
</table>
</body>
<script type="text/javascript">
document.getElementById("string1").contentEditable = true;
document.getElementById("string2").contentEditable = true;
document.getElementById("string3").contentEditable = true;
var integer1 = document.getElementById("string1").innerText;
var integer2 = document.getElementById("string2").innerText;
var integer3 = document.getElementById("string3").innerText;
var sum = parseInt(integer1) + parseInt(integer2) + parseInt(integer3);
function myFunction() {
document.getElementById("total").innerHTML = sum;
}
</script>
What am I doing wrong?

Its here:
function myFunction() {
document.getElementById("total").innerHTML = sum;
}
Thats an declaration of an function, you just declare it.
You also need to execute that function to make it work with:
myFunction()
Your code looks like this then:
<script type="text/javascript">
document.getElementById("string1").contentEditable = true;
document.getElementById("string2").contentEditable = true;
document.getElementById("string3").contentEditable = true;
function myFunction() {
var integer1 = document.getElementById("string1").innerText;
var integer2 = document.getElementById("string2").innerText;
var integer3 = document.getElementById("string3").innerText;
var sum = parseInt(integer1) + parseInt(integer2) + parseInt(integer3);
}
myFunction();
</script>

You're not calling myFunction() so that code never gets executed.
To make it calculate whatever is in the elements string1, string2, string3 you need to listen for a change and then calculate the sum:
document.getElementById("string1").contentEditable = true;
document.getElementById("string2").contentEditable = true;
document.getElementById("string3").contentEditable = true;
function myFunction() {
// Table cells do not have .value property so we use .innerText
var integer1 = document.getElementById("string1").innerText;
var integer2 = document.getElementById("string2").innerText;
var integer3 = document.getElementById("string3").innerText;
var sum = parseInt(integer1, 10) + parseInt(integer2, 10) + parseInt(integer3, 10);
document.getElementById("total").innerHTML = isNaN(sum) ? 0 : sum;
}
document.getElementById("string1").addEventListener("input", myFunction);
document.getElementById("string2").addEventListener("input", myFunction);
document.getElementById("string3").addEventListener("input", myFunction);
// do initial calculation
myFunction();
Also you should always pass the second parameter (radix) of parseInt.

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)
});

How to multiply 2 td in Javascript?

I have a table where one td gets 1 if a checkbox is checked and I would like to multiple this td with another and display it in a third one.
See the html here:
<div>
<input type="checkbox" id="fut1">check</input>
</div>
<table border="1" cellpadding="10" id="countit">
<tr>
<td id="td1"></td>
<td id="td2">5000</td>
<td id="td3"></td>
</tr>
</table>
And here is the js:
$('#fut1').change(function () {
if ($(this).is(":checked")) {
$('#td1').text('1');
} else {
$('#td1').text('0');
}
});
$('#td1').change(function () {
var me = $('#td1').value;
var ar = $('#td2').value;
var sum = me * ar;
$('#td3').text(sum);
});
$('#td1').change(function () { // <--- td elements don't have a change event listener/handler
var me = $('#td1').value; // <--- td elements don't have a value
var ar = $('#td2').value; // <--- td elements don't have a value
var sum = me * ar;
$('#td3').text(sum);
});
If you want to do it this way:
$('#fut1').change(function () {
if ($(this).is(":checked")) {
$('#td1').text('1');
} else {
$('#td1').text('0');
}
callTdChange();
});
function callTdChange() {
var me = parseInt($('#td1').text());
var ar = parseInt($('#td2').text());
var sum = me * ar;
$('#td3').text(sum);
}
Of course, the better way should be to use form elements (inputs) in the case you want to save your data to a server, or use change behaviors.
#td1 doesn't support the change event, because that's only meant for interactive elements (like input, select, or textarea).
You can either do the calculation in your first event listener in #fut1, or declare an input element inside #td1.

Javascript returns 0 when adding all td values

I have a table and I want to add and display the SUM of a td value in a div when a user access the page.
<table>
<thead>
<tr>
<th>Value</td>
</tr>
</thead>
<tbody>
<tr>
<td class="d">PHP <?php echo number_format($l['target_daily'], 2) ?></td>
</tr>
</tbody>
</table>
And Some javascript to get sum duning page load
<script>
$(calculateSumm);
function calculateSumm() {
var sum = 0;
$(".d").each(function() {
if(!isNaN(this.value) && this.value.length!=0) {
sum += parseFloat(this.value);
}
});
$('#result').html(sum);
};
</script>
<div id="result>//This will display sum values but returns 0</div>
What I am lacking here?
The issues are that you're using this.value, which td elements don't have (value is just on input elements and similar), and you have PHP at the beginning of the text of the cells.
See code comments:
$(calculateSumm);
function calculateSumm() {
var sum = 0;
$(".d").each(function() {
// Get the text of the cell
var val = $(this).text()
// Remove the PHP at the beginning
val = val.replace(/^\s*PHP\s*/, '');
if (val.length) {
// Parse it
val = parseFloat(val);
if (!isNaN(val)) {
// Add it
sum += val;
}
}
});
$('#result').html(sum);
};
The bit where we're replacing the "PHP" could use some extra explanation:
val = val.replace(/^\s*PHP\s*/, '');
That means: "Match optional whitespace followed by PHP followed by optional whitespace at the beginning of the string, and replace it with an empty string".
Side note: There's no reason to wonder what's going wrong with your code. Your browser has a JavaScript debugger built into it, which lets you set breakpoints in your code to pause it, inspect variables, single-step through the code to watch it run, etc. Look in the menus for the "Dev Tools" (F12 and/or Ctrl+Shift+I on most browsers).
Try this:
<script>
$(calculateSumm);
function calculateSumm() {
var sum = 0;
$(".d").each(function() {
sum += parseFloat($(this).text());
});
$('#result').html(sum);
};
</script>
The value property is not available for TD elements. So I replaced the this.value with $(this).text() which uses jquery to get the textual value from the inner part of the td element.
As suggested by #T.J Crowder
<script>
$(calculateSumm);
function calculateSumm() {
var sum = 0;
$(".d").each(function() {
// Get the text of the cell
var val = $(this).text()
// Remove the PHP at the beginning
val = val.replace(/^\s*PHP\s*/, '');
if (val.length) {
// Parse it
val = parseFloat(val);
if (!isNaN(val)) {
// Add it
sum += val;
}
}
});
//$('#result').html(sum);
$("#result").html(sum.toFixed(2).replace(/(^\d{1,3}|\d{3})(?=(?:\d{3})+(?:$|\.))/g, '$1,'));
};
Now it works.Perfect

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).

Javascript increment variable to update table cells onclick

I have a page where the user inputs a color and I call the onClick method to change the color of the individual cells of the table. However, when I click any cell, only the last cell (cell3 in this case) will change color. What am I doing wrong?
I get the error:
Message: 'document.getElementById(...)' is null or not an object
Line: 24
Char: 4
Code: 0
My code is:
<html>
<body>
<input type='text' id='userInput' value='yellow' />
<table border="1">
<tr>
<td id="1">cell1
</td>
</tr>
<tr>
<td id="2">cell2
</td>
</tr>
<tr>
<td id="3">cell3
</td>
</tr>
</table>
<script type="text/javascript">
for(var i = 1; i <= 3; i++){
document.getElementById(i).onclick = function(){
var newColor = document.getElementById('userInput').value;
document.getElementById(i).style.backgroundColor = newColor;
}
}
</script>
</body>
</html>
Change your HTML to this: An ID must start with an an alpha character. It is not valid to start with a number.
<table border="1">
<tr>
<td id="td1">cell1
</td>
</tr>
<tr>
<td id="td2">cell2
</td>
</tr>
<tr>
<td id="td3">cell3
</td>
</tr>
</table>
This is a very common Javascript issue: All the code shares the value of i which is 3 at the end of the loop. You can solve it by using another helper function like this:
function changeIt(i) {
// This inner function now has its own private copy of 'i'
return function() {
var newColor = document.getElementById('userInput').value;
document.getElementById("td" + i).style.backgroundColor = newColor;
}
}
for(var i = 1; i <= 3; i++){
document.getElementById(i).onclick = changeIt(i);
}
It can also be written using an anonymous function, but those are harder to read.
First of all, your for loop is wrong. Try:
for(var i = 1; i <= 3; i++) {
//code
}
Second, instead of retrieving the element each time in your loop, you could use this:
this.style.backgroundColor = document.getElementById('userInput').value;
Jeremy's answer is close but there is still a problem in that changeIt is not being called until the element is clicked, by which time the value of i is still three. Using Jeremy's update to the HTML the correct script can be written as...
function createChangeColorHandler(n) {
return function() {
var newColor = document.getElementById('userInput').value;
document.getElementById("td" + n).style.backgroundColor = newColor;
}
}
for(var i = 1; i <= 3; i++) {
// We pass i to the function createChangeColorHandler by value
// at the time of this pass of the loop rather than referencing
// the variable directly after the loop has finished
document.getElementById(i).onclick = createChangeColorHandler(i);
}
As an anonymous function...
for(var i = 1; i <= 3; i++) {
// We pass i to the function createChangeColorHandler by value
// at the time of this pass of the loop rather than referencing
// the variable directly after the loop has finished
document.getElementById(i).onclick = (function(n) {
return function() {
var newColor = document.getElementById('userInput').value;
document.getElementById("td" + n).style.backgroundColor = newColor;
}
})(i);
}
EDIT Jeremy's answer is now correct

Categories

Resources