How do I sum up several columns with javascript and jQuery? - javascript

I have a table with two different columns that I would like to add up to their respective sums. Right now I just add up one of the columns, I could add up the second column by just making the same JS again but with different names for the values but that is not so pretty.
How would I do to change it so it counts the ue column as well as the egen and spit out two results, sum and sum2.
<table>
<tr>
<td><asp:TextBox ID="TextBox1" runat="server">Number</asp:TextBox></td>
<td class="egen"><asp:TextBox ID="TextBox56" runat="server" Columns="1">56</asp:TextBox></td>
<td class="ue"><asp:TextBox ID="TextBox57" runat="server" Columns="1">57</asp:TextBox></td>
</tr>
<tr>
<td><asp:TextBox ID="TextBox2" runat="server">Worker</asp:TextBox></td>
<td class="egen"><asp:TextBox ID="TextBox58" runat="server" Columns="1">58</asp:TextBox></td>
<td class="ue"><asp:TextBox ID="TextBox59" runat="server" Columns="1">59</asp:TextBox></td>
</tr>
<tr>
<td align="right">Sum:</td>
<td align="center"><span id="sum"></span></td>
<td align="center"><span id="sum2"></span></td
</tr>
</table>
This is my javascript that I use to add up the values in the column egen.
$(document).ready(function () {
//iterate through each td based on class / input and add keyup
//handler to trigger sum event
$(".egen :input").each(function () {
$(this).keyup(function () {
calculateSum();
});
});
});
function calculateSum() {
var sum = 0;
// iterate through each td based on class and add the values from the input
$(".egen :input").each(function () {
var value = $(this).val();
// add only if the value is number
if (!isNaN(value) && value.length != 0) {
sum += parseFloat(value);
}
});
$('#sum').text(sum);
};

You can target all elements in .egen or .ue by the following selector:
$('.egen :input, .ue :input')
Or if you prefer:
$('.egen, .ue').find(':input')
By the way you don't need to iterate over the collection of elements to bind keyup listeners to them, you can bind to the entire collection immediately:
$('.egen :input, .ue :input').keyup(calculateSum);
EDIT
I note from the presence of #sum and #sum2 that you may want to sum up the columns separately. You could do something like this:
$('.egen :input').keyup(function() { calculateSum('.egen'); });
$('.ue :input').keyup(function() { calculateSum('.ue'); });
function calculateSum(container) {
var sum = 0;
$(container).find(':input').each(function() {
...
});
}
And then of course set the value of #sum or #sum2, respectively. That could be acheived in a number of ways. Either you pass the id, just as we're passing the class above, or you use a class named sum, and have the respective td's reuse the egen and ue classes. That way you could access the correct sum with $(container+'.sum').val(). Another solution would be to just return the sum, and setting it in your keyup listener:
$('.ue :input').keyup(function() {
$('#sum2').val( calculateSum('.ue') );
});
Note also that your parsing could be simplified. parseFloat will yield NaN for a lot of invalid values, including empty strings and null, so you do not need to check your values closely before calling it. NaN will evaluate to false, so you could always sum by (parsedResult || 0), as the result would be 0, leaving the sum unaffected, if parsedResult is NaN.
Thus:
var sum = 0;
$(container).find(':input').each(function() {
sum += (parseFloat( $(this).val() ) || 0);
});

changed your sum <span> id to its respective class_sum like
<span id="egen_sum"></span>
<span id="ui_sum"></span>
...
so that we can get this working with one function
try this
$('.egen :input, .ue :input').keyup(function(){
var keyupClass= $(this).parent().hasClass('egen') ? 'egen' : 'ue';
calculateSum(keyupClass);
});
function calculateSum(keyupClass) {
var sum = 0;
$("."+ keyupClass+" :input").each(function () {
var value = $(this).val();
// add only if the value is number
if (!isNaN(value) && value.length != 0) {
sum += parseFloat(value);
}
});
$('#'+keyupClass+"_sum").text(sum);
};
this will work for any number of input ... just need to make sure the corresponding sum span is given the right id...

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.

In Jquery take a different values from single text box id

I am using Data Table in jquery. So i passed one input type text box and passed the single id. This data table will take a multiple text box. i will enter values manually and pass it into the controller. I want to take one or more text box values as an array..
The following image is the exact view of my data table.
I have marked red color in one place. the three text boxes are in same id but different values. how to bind that?
function UpdateAmount() {debugger;
var id = "";
var count = 0;
$("input:checkbox[name=che]:checked").each(function () {
if (count == 0) {
id = $(this).val();
var amount= $('#Amount').val();
}
else {
id += "," + $(this).val();
amount+="," + $(this).val(); // if i give this i am getting the first text box value only.
}
count = count + 1;
});
if (count == 0) {
alert("Please select atleast one record to update");
return false;
}
Really stuck to find out the solution... I want to get the all text box values ?
An Id can only be used once; use a class, then when you reference the class(es), you can loop through them.
<input class="getValues" />
<input class="getValues" />
<input class="getValues" />
Then, reference as ...
$(".getValues")
Loop through as ...
var allValues = [];
var obs = $(".getValues");
for (var i=0,len=obs.length; i<len; i++) {
allValues.push($(obs[i]).val());
}
... and you now have an array of the values.
You could also use the jQuery .each functionality.
var allValues = [];
var obs = $(".getValues");
obs.each(function(index, value) {
allValues.push(value);
}
So, the fundamental rule is that you must not have duplicate IDs. Hence, use classes. So, in your example, replace the IDs of those text boxes with classes, something like:
<input class="amount" type="text" />
Then, try the below code.
function UpdateAmount() {
debugger;
var amount = [];
$("input:checkbox[name=che]:checked").each(function () {
var $row = $(this).closest("tr");
var inputVal = $row.find(".amount").val();
amount.push(inputVal);
});
console.log (amount); // an array of values
console.log (amount.join(", ")); // a comma separated string of values
if (!amount.length) {
alert("Please select atleast one record to update");
return false;
}
}
See if that works and I will then add some details as to what the code does.
First if you have all the textbox in a div then you get all the textbox value using children function like this
function GetTextBoxValueOne() {
$("#divAllTextBox").children("input:text").each(function () {
alert($(this).val());
});
}
Now another way is you can give a class name to those textboxes which value you need and get that control with class name like this,
function GetTextBoxValueTwo() {
$(".text-box").each(function () {
alert($(this).val());
});
}

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

If <td> has the largest int, in its <tr> add css class to <td> - jquery

Ive got a table of data, and I'm trying to at a glance look over it and find the highest number on each row.
To do this I'm adding a css class called highest to the highest <td> like this
<tr>
<td>4.2</td>
<td class="highest">5.0</td>
<td>2.9</td>
</tr>
with this css
td.highest {font-weight:bold;}
But this is all hardcoded, I'm trying to work out how to write this using jquery, but I'm pretty new to js and not really sure were to start, I was looking at using Math.max but as I can tell thats to be used on arrays, rather that reading html, any ideas ?
I've made a jsfiddle here - http://jsfiddle.net/pudle/vEUUQ/
First bash - shorter (and potentially more efficient) answers may be available...
$('tr').each(function() {
var $td = $(this).children();
// find all the values
var vals = $td.map(function() {
return +$(this).text();
}).get();
// then find their maximum
var max = Math.max.apply(Math, vals);
// tag any cell matching the max value
$td.filter(function() {
return +$(this).text() === max;
}).addClass('highest');
});
demo at http://jsfiddle.net/alnitak/DggUN/
Based upon this structure:
<table>
<tr>
<td>4.2</td>
<td>5.0</td>
<td>2.9</td>
</tr>
</table>
You can use JS/jQuery and do:
var highest = 0;
$("table tr td").each(function() {
var current = $(this).text();
if (current > highest) {
highest = current;
$(".highest").removeClass();
$(this).addClass('highest');
}
});
http://jsfiddle.net/syU82/
The easiest thing I can think of is to use http://underscorejs.org/#max or http://lodash.com/docs#max and pass in a function that filters for this.
var result = _.max($("td"),function(td){ return parseFloat($(td).text()); });
result.addClass("highest");
Otherwise you can do it the long way:
var result,max 0;
$("td").filter(function(){
var myval = parseFloat($(this).text());
if(myval > max){
result = this;
max = myval;
}
});
result.addClass("highest");
Yet another solution, not as good as some of the others though.
$('tr').each(function() {
var $highest_el;
var highest_num;
$('td', this).each(function() {
if ( $highest_el === undefined || parseFloat($(this).text()) > highest_num ) {
$highest_el = $(this);
highest_num = $(this).text();
}
});
$highest_el.addClass('highest');
});
jsFiddle: http://jsfiddle.net/hRJLQ/2/

Categories

Resources