How do I add up the vals of inputs using jquery?

314
November 22, 2016, at 09:02 AM

I'm working on a GPA calculator, but I've hit a road block.

Here's how the calculator looks like: http://codepen.io/m6cheung/pen/KdWGxa.

Here is the JS part of it:

var $units = $('.units');
var $grade = $('.grade-select');
var $gpa = $('#gpa');
var sum = 0;
$('.btn').click(function() {
  $('.block').last().clone().children().val("").parent().appendTo($('.inner-box'));
});
$('.result').hide();
$units.keyup(function() {
  $gpa.text((($grade.val() * $(this).val()) / $(this).val()).toFixed(2));  
});
$grade.change(function() {
    $gpa.text((($units.val() * $(this).val()) / $units.val()).toFixed(2));
    $('.result').show();
});

What I want to know: is there any other way, so I can use jQuery to manipulate further $units and $grade values when I press the Add Course button? For now, it only works for the first set of input values.

Answer 1

Since the inputs are added dynamically, you need to bind events to the closest static parent, such as .outer-box. Binding it to document is bad/costly due to event bubbling. Adding up the inputs is as easy as writing a function that would be called on keyup and change which also eliminates code duplication.

 var $oBox = $('.outer-box'),
    $gpa = $('#gpa'),
    $result = $('.result').hide();
$('.btn').click(function() {
    $('.block').last().clone().children().val("").parent().appendTo($('.inner-box'));
});
$oBox.on("keyup", ".units", function() {
    $gpa.text(getTotal());
});
$oBox.on("change", ".grade-select", function() {
    $gpa.text(getTotal());
    //Show $result only if it's  hidden
    $result.is(":hidden") && $result.show();
});
//The function I stated above
function getTotal() {
    var sum = 0;  
    //Loop thru the units
    $('.units').each(function() {
        var $this = $(this);
        //You must also check if the entered unit is a number
        //to avoid operating on non-number inputs
        //https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/isNaN
        if ( !isNaN($this.val()) ) {
            //Input vals are always of type string, so, convert them to numbers
            //Multiply the pairs
            sum += parseFloat($this.val()||0) * parseFloat($this.parent().find('.grade-select').val()||0);
        }
    });
    //Format the number
    return sum.toFixed(2);
}

Your updated pen

Answer 2

after adding a new row the keyup and change events are not bind to them.

try using:-

$(document).on('keyup','.units', function() {

and

$(document).on('change','.grade-select', function() {

EDIT from comment

to add them up, create a new function:

function sumScores(){
   var score = 0;
   $('.block').each(function(i, element){
      var unit = $(element).find('.units').val();
      var grade = $(element).find('.grade-select').val();
      // do calculation and add to score
   });
   $gpa.text(score.toFixed(2); 
}

then set that function to the keyup/change handler.

$(document).on('keyup','.units', sumScores);
$(document).on('change','.grade-select', sumScores);
Answer 3

I noticed the beginning of your code starts with: var $units = $('.units');

And your inputs are dynamically generated by cloning.

One reason why your computation only works at first input is because $input only points to the fist input, same with $grade.

Maybe you are expecting that $input will automatically take other input as they are cloned. It is not the case. It does not work like CSS rules. You need to re-execute the line for every clone like this:

$('.btn').click(function() {
  $('.block').last().clone().children().val("").parent().appendTo($('.inner-box'));
  $units = $('.units');
  $grade = $('.grade-select');
});

To manipulate all values you need to loop all elements like this:

var sum = 0;
for (var n = 0; n < $units.length; n++) {
    sum += 1 * $($units[n]).val();//1 * -> is for assurance it adding not concat
    //to retreive $grade use $($grade[n]).val()
}
READ ALSO
Input types in textarea

Input types in textarea

HTML has various input types like text,date,email,url,etc. which is recognized by many browsers and thus almost every browser does validation by itself.

410
Ignore hidden elements in a table cell using DataTables button Print

Ignore hidden elements in a table cell using DataTables button Print

I'm using jQuery DataTables with Buttons extension. I have Print button as could be seen in this example.

358
Can&#39;t access dynamically generated element with Jquery and Jsoup

Can't access dynamically generated element with Jquery and Jsoup

lets explain whats happening, i am parsing a html page to show its content in my android application. firstly i load the html with android webview and then i get html code by code below :.

284
JQuery - Label .text() not correct

JQuery - Label .text() not correct

I am having an issue that I just can't figure out!.

369