Sum partial total lines created dynamically with jQuery

Asked

Viewed 105 times

1

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?><!DOCTYPE html>

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
  <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
    <h1 class="h2">Nova Compra:</h1>
    <div class="btn-toolbar mb-2 mb-md-0">
      <div class="btn-group mr-2">
        <?php

        if ($this->session->userdata('perms') == 1 or $this->session->userdata('perms') == 5) { ?>
          <a class="btn btn-sm btn-primary" href="<?php echo base_url().'Compras/inclui'; ?>" role="button">Nova Compra</a>
        <?php } else { ?>
          <a class="btn btn-sm btn-primary" href="#" role="button" disabled>Nova Compra</a>
          <?php
        }
        ?>
      </div>
      
    </div>
  </div>


  <div class="container float-right" id="body">

    <form id="form" action="<?php echo base_url().'Compras/cadastraCompra'; ?>" method="POST">

      <div class="row">
        <div class="col-3">
          <input type="text" class="form-control" name="num_nota" onkeyup="maiuscula(this)" placeholder="Número da Nota" required >
        </div>

        <div class="col-3">
          <input type="date" class="form-control" name="datac" placeholder="Data da Compra" required>
        </div>

        <div class="col-2">
          <input type="number" class="form-control" id = "qt" name="qt" min="1" max="99" placeholder="Qt. Itens Nota" value="1" required>
        </div> 
        <div class="col">
          <a class="btn btn-sm btn-warning" href="#" role="button" onclick="alert('Neste campo, à esquerda, digite a quantidade de itens da nota!');"> &#xe091;</a>
        </div>
        

        <div class="col-3">
          <div class="input-group">
            <input type="text" class="form-control money3" maxlength="15" name="valort" placeholder="Valor Total da Nota (R$)" required>
          </div>
        </div>
        
      </div>

    </br></br>

    


    <div class="row">
      <div class="col">
        <div class="input-group">




         <input type="text" id="autouser" class="form-control" name="fornec" onchange="ApenasLetras(e, t)" placeholder="Qual é o Fornecedor?" required>



         

         <input type="hidden" id="userid" name="idfornec" value="0">

         <script type="text/javascript">
          $(document).ready(function(){

            $('#autouser').autocomplete({
              source: function(request, response) {

                $.ajax({
                  url:'<?php echo base_url().'Compras/fornecList'; ?>',
                  type: 'post',
                  dataType: 'json',
                  data: {
                    search: request.term
                  },
                  success: function(data){
                    response(data);
                  }

                });
              },
              select: function(event, ui){
                $('#autouser').val(ui.item.label);
                $('#userid').val(ui.item.value);

                return false;
              }

            });
          });
        </script>

        
        
      </div>
    </div>

    <div class="col">
      <div class="input-group">

        <input type="text" class="form-control" name="obs" placeholder="Observações...">
      </div>
    </div>


  </div>

</br>
<div class="row">
  <div class="col-5">
    <h5>DADOS DO PRODUTO:</h5>
  </div>
  <div class="col">
    <h5>Unit.:</h5>
  </div>
  <div class="col">
    <h5>R$:</h5>
  </div>
  <div class="col">
    <h5>Qt.: <a class="btn btn-sm btn-warning" href="#" role="button" onclick="alert('Verifique a unidade do Produto! EXEMPLO: Se a unidade do produto for KG e foi comprado meio quilo, lance na nota de compra a quantidade de 0,50.');">&#xe091;</a></h5>
  </div>
  <div class="col">
    <h5>Total R$:</h5>
  </div>
</div>


<div id="origem">

  <div class="row">
    <div class="col col-md-3">
      <div class="input-group">

        <input type="text" class="auto form-control" id="autoprod" name="prod[]" placeholder="Produto..." required>

        <input type="hidden" id="prodid" name="prodid[]" value="0">

        <script type="text/javascript">


          $(document).ready(function(){

            var i = 0;

            $('#autoprod').eq(i).autocomplete({
              source: function(request, response) {

                $.ajax({
                  url:'<?php echo base_url().'Compras/prodList'; ?>',
                  type: 'post',
                  dataType: 'json',
                  data: {
                    search: request.term
                  },
                  success: function(data){
                    response(data);
                  }

                });
              },
              select: function(event, ui){
                $('#autoprod').eq(i).val(ui.item.label);
                $('#prodid').val(ui.item.value);
                $('#marca').val(ui.item.marc);
                $('#unit').val(ui.item.uni);

                return false;
              }

            });
          });





        </script>


      </div>


    </div>
    <div class="col col-md-2">
      <div class="input-group">

        <input type="text" class="form-control" id="marca" name="marca[]" placeholder="Marca..." readonly>

      </div>
    </div>


    <div class="col">
      <div class="input-group">



        <input type="hidden" class="form-control" id="unit" name="unit[]" placeholder="Unidade..." readonly>
        <input type="text" class="form-control" id="lugar" name="unit2[]" placeholder="Unidade..." readonly> 

        <script type="text/javascript">

         $(document).ready(function(){

          $("#autoprod").on('blur', function() {
            var txt = $('#unit').val();

            var jtxt = {
              'valor1': txt
            };

            $.ajax({    
              url: '<?php echo base_url()."Compras/ajax"; ?>',  
              type: 'post',       
              data: jtxt,  
              dataType:'json',
              success:function(resultado) {

                $("#lugar").val(resultado[0].nome_unit);


              },
              error:function(){
                alert("Este produto não existe... Preencha corretamente o formulário!");

              },



            });

          });
        });




      </script>




    </div>
  </div>



  <div class="col">
    <div class="input-group">

      <input type="text" class="form-control money3" maxlength="15" id="valorunit" name="valorunit[]" placeholder="Preço Unit. (R$)" required>

    </div>


  </div>
  <div class="col">
    <div class="input-group">

      <input type="text" class="form-control quantt" id="quant" name="quant[]" min="0" max="999" placeholder="Quantidade" href="#" value="0,00" required>

    </div>


  </div>
  <div class="col">
    <div class="input-group">

      <input type="text" class="form-control totalt" maxlength="15" id="totalp" name="totalp[]" placeholder="Total (R$)" required readonly>

    </div>

    

  </div>
</div>
</br>
</div>

<div id="destino">

</div>

<div class="row">

  <div class="container text-right col-md-9 ">

   <h5>TOTAL NOTA: </h5> 
   
   
 </div>


 <div class="container col-md-3 justify-content-end">
  <input type="text" class="form-control" maxlength="15" id="totalgeral" name="totalgeral" value="0.00" required readonly>

</div>
</div>

<script type="text/javascript">


  $(document).ready(function(){


    $("#qt").on('blur', function(e) {
      e.preventDefault(); 
      document.getElementById("qt").readOnly = true;
      document.getElementById("destino").innerHTML=""; 

      var qtr = $("#qt").val();

      var i = 1;


      // WHILE

      while (i < qtr) {

        var z = i - 1;


        var t = '<div class="row" ng-app="">\<div class="col-3">\<div class="input-group">\<input type="text" class="autot form-control" name="prod[]" placeholder="Produto..." required>\<input type="hidden" class="idr" name="prodid[]" value="0">\</div></div>\<div class="col-2">\<div class="input-group">\<input type="text" class="nname form-control" name="marca[]" placeholder="Marca..." readonly>\</div></div>\<div class="col">\<div class="input-group">\<input type="hidden" class="uunit form-control" name="unit[]" placeholder="Unidade..." readonly>\<input type="text" class="llugar form-control" name="unit2[]" placeholder="Unidade..." readonly>\</div></div>\<div class="col">\<div class="input-group">\<input type="text" class="form-control money3" maxlength="15" name="valorunit[]" placeholder="Preço Unit. (R$)" required ng-model="pu">\</div></div>\<div class="col">\<div class="input-group">\<input type="text" class="form-control quantt" name="quant[]" min="0" max="999" placeholder="Quantidade" value="0,00" href="#" required ng-model="qtt">\</div></div>\<div class="col">\<div class="input-group">\<input type="text" class="form-control totalt" maxlength="15" name="totalp[]" placeholder="Total (R$)" required readonly>\</div></div></div></br>';

        $("#destino").append(t);

        i = i + 1;


      }

      // WHILE


   $(document).on("focus", ".autot", function(){ //PARENTESES E CHAVE

   // este "if" evita que se aplique novamente ao que já foi aplicado
   if( !$(this).hasClass("ui-autocomplete-input") ){

    // AUTOCOMPLETE
    $(this).autocomplete({
     source: function(request, response) { //CHAVE

      $.ajax({ //AJAX
       url:'<?php echo base_url().'Compras/prodList'; ?>',
       type: 'post',
       dataType: 'json',

       data: { //CHAVE
        search: request.term
      }, //FECHA CHAVE

      success: function(data){ // CHAVE
        response(data);
      } //FECHA CHAVE

    }); //AJAX

    }, //CHAVE

    // ABRE CHAVE
    select: function(event, ui){
      $(this).val(ui.item.label);

      $(this).closest('.row').find('.idr').val(ui.item.value);

      $(this).closest('.row').find('.nname').val(ui.item.marc);

      $(this).closest('.row').find('.uunit').val(ui.item.uni);


      return false;
    } // FECHA CHAVE

  }); // AUTOCOMPLETE
}// IF
}); //PARENTESES E CHAVE

 });
  });




  $(document).ready(function(){

   $(document).on("blur", ".autot", function(){

    var $this = $(this);

    var txt = $this.closest('.row').find('.uunit').val();


    var jtxt = {
      'valor1': txt
    };

    $.ajax({    
      url: '<?php echo base_url()."Compras/ajax"; ?>',  
      type: 'post',       
      data: jtxt,  
      dataType:'json',
      success:function(resultado) {

        res = resultado[0].nome_unit;


        $this.closest('.row').find(".llugar").val(res);


      },
      error:function(){
        alert("Este produto não existe... Preencha corretamente o formulário!");

      },



    });

  });
 });



  $(document).ready(function($){
   $(document).on("focus", ".money3", function(){
    $(this).mask("#.##0,00", {reverse: true});
  });
 });

   $(document).ready(function($){
   $(document).on("focus", ".quantt", function(){
    $(this).mask("000.000.000.000.000,00", {reverse: true});
  });
 });



  $(document).ready(function(){
   $(document).on("blur", ".quantt", function(){

    var $this = $(this);

    var valor1 = $this.closest('.row').find('.money3').val().replace('.','');
    valor1 = valor1.replace(',','.');
    valor1 = parseFloat(valor1);

    var valor2 = $this.val().replace('.','');
    valor2 = valor2.replace(',','.');
    valor2 = parseFloat(valor2);

    var total = valor1 * valor2;

    $this.closest('.row').find('.totalt').val(total.toFixed(2));


  });
 });

  $(document).ready(function(){
   $(document).on("blur", ".quantt", function(){

    var $this = $(this);

    var total = 0;

    $this.closest('.row').find('input[name="totalp[]"]').each(function () {

        var soma = $this.closest('.row').find('input[name="totalp[]"]').val();
        if (!isNaN(soma)) total += soma;
                        
    });

    
     $('#totalgeral').val(total);

    });
 });




</script>


<div class="row">
  <div class="container col-md-1">

    <button type="submit" class="btn btn-success">INCLUIR</button>
    
  </div>

  <div class="container col-md-2">

    <a class="btn btn-warning" href="<?php echo base_url().'Compras/inclui'; ?>" role="button">LIMPAR FORMULÁRIO</a>
    
    
  </div>





  <div class="container col-md-8">
    <a class="btn btn-danger" href="<?php echo base_url().'Compras/index'; ?>" role="button">CANCELAR</a>
    
  </div>

  
</div>



</form>

</div>
</main>

<script type="text/javascript">
// INICIO FUNÇÃO DE MASCARA MAIUSCULA
function maiuscula(z){
  v = z.value.toUpperCase();
  z.value = v;
}
//FIM DA FUNÇÃO MASCARA MAIUSCULA
</script>

It is a purchase note, dynamic line has a subtotal and at the end an input that will stick to the overall total of the note...

The lines are created dynamically, so to calculate the total I used the each(), but with each subtotal calculation it changes the total value to equal to this subtotal instead of accumulating...

see the code:

$(document).ready(function(){
   $(document).on("blur", ".quantt", function(){

    var $this = $(this);

    var total = 0;

    $this.closest('.row').find('input[name="totalp[]"]').each(function () {

        var soma = $this.closest('.row').find('input[name="totalp[]"]').val();
        if (!isNaN(soma)) total += soma;
                        
    });

    
     $('#totalgeral').val(total);

    });
 });

inserir a descrição da imagem aqui

  • 1

    It would be interesting to [Dit] the question by adding an excerpt of HTML that may be useful to those who answer.

  • Post table snippet in HTML/PHP

  • 1

    Place a.log(total) console after the if (!isNaN(soma)) total += soma; to see the value that is set in it in each loop

  • I posted the html...

  • Edward Ramos the total always equals the partial total of each line...

  • 1

    @Sam Help, please!

  • Here I didn’t understand $this.closest('.row').find('input[name="totalp[]"]').each(... proque is not something similar to $(document).find('input[name="totalp[]"]').each(... ? And why not use the available parameters for callback?

  • 1

    Augusto Vasques, I don’t know how to use the callback parameters... Can you give me a light?

Show 3 more comments

3 answers

1

It works, but not in the right way... It’s not good... Every time the user makes a change in a dynamic field that has already been added up, he adds this new chalk, after the "Blur" event in the sum... I do not know how to make him recalculate everything again; or in the last case, prevent him from considering a field that has already been added again... Someone can solve the riddle??

  $(document).ready(function(){
    var total = 0;
    $(document).on("blur", ".quantt", function(){

      var $this = $(this);


      $this.closest('.row').find('input[name="totalp[]"]').each(function () {

        var soma = $this.closest('.row').find('input[name="totalp[]"]').val();
        if (!isNaN(soma)) total += parseFloat(soma);


        $('#totalgeral').val(total.toFixed(2));

      });


    });

  });

  • Are you sure the total value is being calculated correctly? This query inside your loop seems to result in an error, because you are searching all inputs again instead of iterating over the inputs already found.

  • User140828 vc is right, the way it is, it is even calculating right, but any onblur (event) that repeats itself in a field that has already passed, at the time of recalculating it instead of disregarding the previous value of the field, it only aggregates the values... In other words, the sum always increases... I don’t know how to do it properly...

0

despite this code running on Document ready.... and n having isolated functions which would be much better. to know that the input has changed you can use this:

    $("input").bind("input", function () {
            $(this).val();
        });

        $("input").on("input", function () {
            $(this).val();
            // chama aqui a soma;            
        });

the best would be to recreate all this(is a mess), example:

    if (!isNaN(soma)) --> para quê? é o mesmo que --> if(soma)
soma == 0 false; soma == null false etc...

the correct would be:

  var soma = 0;
  soma += soma mais coisa ;)

0

Alexandre, your code is full of PHP and AJAX that can not be simulated, unless you create a verifiable example of your problem can not offer you a good help, but I will try to clarify the code error you posted. There may be more errors.

In the following loop:

$this.closest('.row').find('input[name="totalp[]"]').each(function () {

    var soma = $this.closest('.row').find('input[name="totalp[]"]').val();
    if (!isNaN(soma)) total += soma;

});

What you’re doing here is basically looking for all the input with the name totalp[], and for each of them, you do another query to find all these same inputs again.

When you use the method val() jQuery, jQuery returns the value of the first element it found. How are you finding the same list in all loop iterations, all calls from val() will return the value of the first element found.

To capture the value of the current input, you could be declaring this input as an argument in the each(). The first argument of each() is the iteration index, and the second is the value itself, in this case the input.

Then you would have:

$this.closest('.row').find('input[name="totalp[]"]').each(function(i, input) {

    if (!isNaN(input.value)) total += parseFloat(input.value);

});

Of course, with jQuery you can also use this as long as its callback function is not a arrow function, and remember to reassign 0 for total every time the loop rotates.

Following this idea, and with some changes in code syntax, I believe the following is what you need:

$(() => {
    $('.quantt').on('input', (evt) => {
        var total = 0;

        $(evt.currentTarget)
            .closest('.row')
            .find('input[name="totalp[]"]')
            .each((i, input) => total += Number(input.value) || 0);

        $('#totalgeral').val(total);
    });
});
  • user140828, not wanting to abuse, but already abusing, could you tell me what I would put according to what is there, instead of "i" and "input"? What is every thing there in my code... I can’t visualize... Excuse my ignorance...

  • @Alexandre, i and input are only arguments, they can have any name. Their value is defined by jQuery, as explained, the each will go through its list of elements, the argument i shall have the value of the indices (0, 1, 2...) while input is the element itself (in the first loop iteration input is the element in index 0, in the second iteration is the element in index 1, and so on).

  • @Alexander, and I’m sorry my mistake, I ended up assuming that the jQuery should have the method input as a shortcut for capturing input type events, but it seems that this is not the case. It is necessary to use .on('input') even.

Browser other questions tagged

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