Calculating javascript and playing in html table

1

I have a html table of 3 columns, the first 2 are <input type="number"> and the third is text.

I want to play in the third the sum of the values of inputs using onchange , but what I am facing is that if I put "2" in each input , the sum in the third column is 6, since the previous value of input influences final result.

How do I solve this problem ??

Below my code.

<table>
  <tr>
    <td>valor 1</td>
    <td>valor 2</td>
    <td>total</td>
  </tr>
  <tr>
    <td><input type="number" min="0" onchange="calcula(this.value)"></td>
    <td><input type="number" min="0" onchange="calcula(this.value)"></td>
    <td><input type="text" readonly value="0" id="teste"></td>
  </tr>
</table>

<script type="text/javascript">
  function calcula(valor){
    var soma = parseInt(document.getElementById("teste").value);
    soma += parseInt(valor);
    document.getElementById("teste").value = soma;
}
</script>
    
asked by anonymous 09.07.2015 / 20:06

1 answer

3

If the third input is the sum of the others it does not make sense to add including the total which is what this does:

var soma = parseInt(document.getElementById("teste").value);

I suggest removing this and going to the DOM to look for all the elements:

function calcula() {
    var inputs = document.querySelectorAll('input[type="number"]');
    var soma = 0;
    for (var i = 0; i < inputs.length; i++) {
        soma += parseInt(inputs[i].value) || 0;
        document.getElementById("teste").value = soma;
    }
}

jsFiddle: link

Another way, which I prefer by separating JS from HTML, and saving global functions is:

(function () {
    var inputs = [].map.call(document.querySelectorAll('table tr input[type="number"]'), function (input) {
        input.addEventListener('change', calcula);
        return input;
    });

    function calcula() {
        var soma = inputs.reduce(function (soma, input) {
            var nr = parseInt(input.value) || 0;
            return soma + nr;
        }, 0);
        document.getElementById("teste").value = soma;
    }
})();

jsFiddle: link

In this last example the code goes to the DOM to fetch the inputs when the page loads and then works from memory to iterate the elements.

I used [].map.call() to convert the list of inputs into an array and then to use reduce as perfect for this summation case.

Note also that I used var nr = parseInt(input.value) || 0; to count 0 if the input has no value.

    
09.07.2015 / 20:14