Sum dynamic line values automatically

Asked

Viewed 660 times

2

As the example below, I am trying to add the value of the lines Qtde Transferir, that are generated dynamically as the result of the database, subtract from the value entered in the field Quantidade a Transferir and display the difference in the field Falta:

inserir a descrição da imagem aqui

I built the code below, using some examples I found, he added the dynamic lines, but first I need to type the values in the lines and finally the Quantidade a Transferir to calculate the Falta:

$(document).ready(function() {
    $("#qtde_entrada").on('change', function() {
    if($(this).val().length > 0) {
     var total = 0;
     $('.input').each(function(){
       var valor = Number($(this).val());
       if (!isNaN(valor)) total += valor;
     });
     var final = $("#qtde_entrada").val() - total;
     $("#qtde_falta").val(final);
    }
    });
});

Inputs are set this way:

Qtde to Transfer and Missing:

      <tr>
          <td colspan='2'>Quantidade a Transferir:
          <input type = "number" id="qtde_entrada" name = "qtde_entrada"  min="1" max="99999" style="width: 10em;"> -
          <b>Falta: <input type = "number" id="qtde_falta" name = "qtde_falta" class="resultado" style="width: 10em;" readonly></b></td>
      </tr>

Qtde Transfer (dynamic):

HTML += "<td><input type = 'text' size = '5' name = 'qtde_trans[]' id = 'qtde_trans[]' class='input' ></td></tr>";

Any suggestion of how to first type the total value to transfer and as it is typed in the lines it will display in the missing?

2 answers

3


You can separate the calculation into a function:

function calc() {
    if($(this).val().length > 0) {
      var total = 0;
      $('.input').each(function(){
        var valor = Number($(this).val());
        if (!isNaN(valor)) total += valor;
      });
      var final = $("#qtde_entrada").val() - total;
      $("#qtde_falta").val(final);
    }
}

And use it in the event change so much of #qtde_entrada how much of the dynamic fields:

$('#qtde_entrada').on('change', calc);
$('table').on('change', '.input', calc);

Note the second line of the code above, the construction of the on is different. Since the fields are dynamic, you need to use something called delegation. This is necessary because when you listen to an event in Javascript, it associates the response function to the elements present in GIFT; so if we have the following code:

`$('.input').on('change', calc);

The function calc will be associated with the event change of the elements .input present at the time of the call. Which would not solve your problem, since these fields are dynamic and can be inserted on the page after executing the above code.

When using the construction:

$('table').on('change', '.input', calc);

The jQuery library will associate the event change to the element table, but will perform the function calc only when the change occur in the elements .input. This is due to Event Bubbling, which causes an event to occur in an element, it (the event) is propagated to the highest parent from the element where the event was initiated, or until propagation is canceled (returning false or calling the method stopPropagation of the event).

As shown in the image below, the event started in element number 3 and propagated up to element number 1:

inserir a descrição da imagem aqui

Thus the event is no longer associated only with the elements that existed at the time of the association. The new elements will also propagate the event and function calc will be called correctly.

See working: https://jsfiddle.net/bdsb70rh/

  • Thanks for the reply. I’m looking at Jsfiddle and it really worked. In my case not yet, but I’m reviewing again.

  • @Diego Como applied the modifications?

  • 1

    It worked, I missed a # in the part I changed in var table. Thank you for the excellent explanation and reply. Thank you very much.

2

The code almost does what you want, but does not recalculate while typing on the lines. To do this just add them to the change event.

$(document).ready(function()
{
    $("#qtde_falta").val("? - 0.0"); // Definimos um texto inicial
});
function alteracaoValores() // Quando houver alterações, não importando qual dos campos for (das linhas ou da qtd transferir)
{
    var total = 0.0;
    $('.somatorio').each(function() // Tanto para alteração na linha superior como nas editadas...
    {
        var valor = Number($(this).val());
            if (!isNaN(valor)) total += valor;
    }
    var quant_entr = parseFloat($("#qtde_entrada").val());
    if(!isNaN(quant_entr))
    {
        var final = quant_entr - total;
            $("#qtde_falta").val(final);
    }
    else
    $("#qtde_falta").val("? - " + total); // Colocar texto quando não tiver campo quantidade a transferir preenchido.
}

HTML:

<tr>
      <td colspan='2'>Quantidade a Transferir:
      <input type = "number" id="qtde_entrada" name = "qtde_entrada"  min="1" max="99999" style="width: 10em;" onchange='alteracaoValores();'> -
      <b>Falta: <input type = "number" id="qtde_falta" name = "qtde_falta" class="resultado" style="width: 10em;" readonly></b></td>
</tr>

Dynamically generated HTML:

HTML += "<td><input type = 'text' size = '5' name = 'qtde_trans[]' id = 'qtde_trans[]' class='input somatorio' onchange='alteracaoValores();' ></td></tr>";
  • Thank you for the reply, but you are giving an error that I did not identify because: Syntaxerror: Missing ) after argument list var quant_entr = parseFloat($("#qtde_input").val());

Browser other questions tagged

You are not signed in. Login or sign up in order to post.