Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update totals in a table

I have:

$('#createStockOrder').click(function () {
    modal('create-stock-order', {}, function () {
        var $modal = $(this);
        var submitted = false;
        var model = [];

        $('.glyphicon-plus').click(function () {
            var product_id = $('#productSelect option:selected').text(),
                size_id = $('#sizeSelect option:selected').text(),
                colour_id = $('#colourSelect option:selected').text(),
                quantity = $('#quantity').val();

            // Get index of the element where all the fields matches
            var index = getObjectIndex(model, product_id, size_id, colour_id);

            // If object found in the array
            if (index !== false) {
                // Update the quantity in the same element
                model[index].quantity = quantity;
            } else {
                // Add the element in the array
                model.push({
                    product_id: product_id,
                    size_id: size_id,
                    colour_id: colour_id,
                    quantity: quantity
                });
            }
            printStock(model);
        });

        var form = document.getElementById('create_sale');
        var $form = $(form);

        $form.on('submit', function (e) {
            e.preventDefault();
            if (!submitted) {
                submitted = true;
                $('#create_sale .btn-primary').addClass('disabled');
                var formData = new FormData(form);
                qwest.post(form.action, formData)
                    .then(function (resp) {
                        $modal.modal('hide');
                    })
                    .catch(function (xhr, response, e) {
                        var html = '';
                        $.each(response, function (i, v) {
                            html += '<p>' + v + '</p>';
                        });
                        $('#create_sale .alert').html(html).removeClass('hide');
                        $('#create_sale .btn-primary').removeClass('disabled');
                        submitted = false;
                    });
            }
        })

    }, {width: 1000});
});

// Currently the function is Static, but it can be changed to dynamic
// by using nested loop and a flag to store the match status
function getObjectIndex(arr, product_id, size_id, colour_id) {
    // Loop over array to find the matching element/object
    for (var i = 0; i < arr.length; i++) {
        var obj = arr[i];
        if (obj.product_id === product_id && obj.size_id === size_id && obj.colour_id === colour_id) {
            // When all key-value matches return the array index
            return i;
        }
    }

    // When no match found, return false
    return false;
}

function printStock(model) {
    var html = '';
    var total_row_quantity = 0;
    var total_row_value = 0;
    $.each(model, function (i1, v1) {
        html += '<tr>';
        $.each(v1, function (i2, v2) {
            html += '<td>' + v2 + '</td>';
            $('#product_totals tr').each(function(i3, v3){
                var product_code = $('td', v3).eq(0).html();
                if(product_code == v2) {
                    total_row_quantity += parseInt(model[i1].quantity);
                    total_row_value += parseFloat($('td', v3).eq(2).html()*model[i1].quantity);
                    $('td', v3).eq(1).html(total_row_quantity);
                    $('td', v3).eq(3).html(accounting.formatMoney(total_row_value, ''));
                } else {
                    total_row_quantity = 0;
                    total_row_value = 0;
                }
            })
        });
        html += '</tr>';
    });
    $('#stock_order tbody').html(html);
}

The HTML is:

<tbody id="product_totals">
  <tr data-id="1">
    <td>JW1501</td>
    <td class="code-quantity-total">0</td>
    <td>79.00</td>
    <td class="code-cost-total">0</td>
  </tr>
  <tr data-id="2">
    <td>JW1502</td>
    <td class="code-quantity-total">0</td>
    <td>99.00</td>
    <td class="code-cost-total">0</td>
  </tr>
  <tr data-id="3">
    <td>JW1501-1</td>
    <td class="code-quantity-total">0</td>
    <td>20.00</td>
    <td class="code-cost-total">0</td>
  </tr>
  <tr data-id="4">
    <td>JW1502-2</td>
    <td class="code-quantity-total">0</td>
    <td>25.00</td>
    <td class="code-cost-total">0</td>
  </tr>
</tbody>

The list of rows (JW1501, JW1502) is dynamic.

The problem I am having is that if a variant of e.g. JW1502 is added, only the total quantity and value is calculated for that one. Any previous different variants of JW1502 are ignored.

How can I fix this?


Example content of var model:

[
 {"product_id":"JW1501","size_id":"70A","colour_id":"小豹纹","quantity":"1"},    
 {"product_id":"JW1501","size_id":"75B","colour_id":"小豹纹","quantity":"2"},
 {"product_id":"JW1502","size_id":"85A","colour_id":"黑色","quantity":"1"}
]

The above for JW1501 would show the incorrect quantity of 2, not 3.


...
$('#product_totals tr').each(function (i3, v3) {
            console.log(v1, v2, v3)
...

Outputs:

Object {product_id: "JW1501", size_id: "70A", colour_id: "小豹纹", quantity: "2"}
"JW1501"
<tr data-id=​"1">​<td>​JW1501​</td>​<td class=​"code-quantity-total">​2​</td>​<td>​79.00​</td>​<td class=​"code-cost-total">​158.00​</td>​</tr>​
like image 524
imperium2335 Avatar asked Oct 30 '22 12:10

imperium2335


1 Answers

I have completely changed your printStock function to achieve your goal:

function printStock(model) {

    $("#product_totals tr").each(function(){

        var id = $("td:eq(0)", this).text().trim();
        var price = parseFloat($("td:eq(2)", this).text());
        var count = 0;

        $.each(model, function(i, item){
            if (item.product_id == id) count += (+item.quantity);
        });

        $("td:eq(1)", this).text(count);
        $("td:eq(3)", this).text((count * price).toFixed(2));

    });

    var rows = $.map(model, function(item){
        return [
            "<td>" + item.product_id + "</td>",
            "<td>" + item.size_id + "</td>",
            "<td>" + item.colour_id + "</td>",
            "<td>" + item.quantity + "</td>"
        ].join("");
    });

    var html = "<tr>" + rows.join("</tr><tr>") + "</tr>";
    $('#stock_order tbody').html(html);
}

The main difference is that my code groups items in model by product_id for further counting.

Also refer my fiddle.

like image 70
Rango Avatar answered Nov 11 '22 04:11

Rango