Calculation of table with Jquery

0

I have a table which I can use to add products to a sale:

     <table class="table" id="tablaDetalle">
            {{ detalleformset.management_form }}
            <thead class="thead-dark">
                <th>Producto</th>
                <th width="100px">Cantidad</th>
                <th width="115px">Prec.Unit.</th>
                <th width="115px">Subtotal</th>
                <th>Acción</th>
            </thead>
            <tbody>
            {% for form in detalleformset.forms %}
                <tr class="formset_row">
                    {% for field in form.visible_fields %}
                        <td>
                            {# Include the hidden fields in the form #}
                            {% if forloop.first %}
                                {% for hidden in form.hidden_fields %}
                                    {{ hidden }}
                                {% endfor %}
                            {% endif %}
                            {{ field.errors.as_ul }}
                            {{ field }}
                        </td>
                    {% endfor %}
                </tr>
            {% endfor %}
            </tbody>
        </table>

This does not have much to do since this does django perfectly since I am currently using this for such a project.

and this is my jquery:

   $('.formset_row').formset({
        addText: 'Agregar Producto',
        deleteText: 'remover',
        prefix: 'detalleventa'
    });
    $(function() {    
        $("#tablaDetalle").on("change", "input", function(){
          var row = $(this).closest("tr");
          var cantidad = parseFloat(row.find("input:eq(2)").val());
          var precio = parseFloat(row.find("input:eq(3)").val());
          var subtotal = parseInt(cantidad, 10) * parseFloat(precio);
          row.find("input:eq(4)").val(isNaN(subtotal) ? "" : subtotal.toFixed(2));

          var total = 0;
            $(".subtotal").each(function () {
                var stval = parseFloat($(this).val());
                total += isNaN(stval) ? 0 : stval;
            });
            $('.total').val(total.toFixed(2));

            $('.delete-row').click(function(){
                var $fila = $(this).parents('tr');
                var valsub = parseFloat($fila.find('input:eq(4)').val());
                new Promise(function(done){
                    total -= isNaN(valsub) ? 0 : valsub;
                    $('.total').val(total.toFixed(2));
                    done();
                })
                .then(function(){
                    var id0 = parseFloat($fila.find('#id_detalleventa-0-subtotal').val(0));
                })
            });
        });  
      });
</script>

In which my problem arises when wanting to edit a sale ... why? because when I register I make changes in the fields (input) for example the input amount and when it makes that change it just calculates and it works until the element is removed from the table everything is perfect! but when I go to edit a sale and I give it to remove that element ... the total does not change since there are no changes in the input ... I am simply removing an element. Is there another way to do it?

    
asked by 09.02.2018 в 23:07
source

1 answer

0

The problem is that you are associating the delete driver within the change handler with input , then the deletion will only work after making a change in input and not before (the behavior you describe).

The solution would be to move the association of the event for .delete-row out of the change handler in input (out of $("#tablaDetalle").on("change", "input", function(){ ) and I think you also have to do it in a delegated way (to avoid problems if the button is added dynamically).

Something like this (read the comments for details):

$(function() {    
    $("#tablaDetalle").on("change", "input", function(){
      var row = $(this).closest("tr");
      var cantidad = parseFloat(row.find("input:eq(2)").val());
      var precio = parseFloat(row.find("input:eq(3)").val());
      var subtotal = parseInt(cantidad, 10) * parseFloat(precio);
      row.find("input:eq(4)").val(isNaN(subtotal) ? "" : subtotal.toFixed(2));

      var total = 0;
        $(".subtotal").each(function () {
            var stval = parseFloat($(this).val());
            total += isNaN(stval) ? 0 : stval;
        });
        $('.total').val(total.toFixed(2));
    });  

    // mueve el código del .delete-row fuera del controlador del input
    // y hazlo delegado (esto creo que es necesario, aunque no estoy seguro)
    $("#tablaDetalle").on("click", '.delete-row', function(){
        // aquí tendrás que volver a leer los valores de las variables usadas (p.e. total)
        var total = $('.total').val();
        var $fila = $(this).parents('tr');
        var valsub = parseFloat($fila.find('input:eq(4)').val());
        new Promise(function(done){
            total -= isNaN(valsub) ? 0 : valsub;
            $('.total').val(total.toFixed(2));
            done();
        })
        .then(function(){
            var id0 = parseFloat($fila.find('#id_detalleventa-0-subtotal').val(0));
        })
    });
});
    
answered by 10.02.2018 в 02:29