0

I have appended data and I print each data price in hidden input. Now I want to sum these prices with input numbers as quantity in order to get the total amount but nothing prints.

Code

javascript

success:function(data) {
        //append data to my view
        data.forEach(function(row) {
            var $meto = '';
            $meto += '<div class="col-md-3 mt-2">'+
                '<div class="card">'+
                    '<div class="card-body">'+
                        '<img src="{{url("images")}}/'+row['photo']+'" class="menuimg img-fluid" alt="image">'+
                        '<p>'+row['name']+'</p>'+
                        '<input type="number" name="qty[]" class="qty form-control">'+
                        '<input type="hidden" class="price" value="'+row['price']+'" />'+
                    '</div>'+
                '</div>'+
            '</div>';
            $('.here').append($meto);

            //sum prices
            $('.qty').on('keyup',function(){
                var qty = $('.qty').val();
                var price = $('.price').val();
                $("#total").html(qty*price);
            });
        });
}

html

<div class="col-md-10">
  <div class="row here"></div>
</div>
<p>Total: <span id="total"></span></p>

Explanation

I have filled 2 of my items with quantities 1 & 3 there is hidden input under each of them that holds their prices (as this sample they are 5000 & 16000)

Basically I should have something like this in my total div:

1*5000 = 5000
3*16000 = 48000
Total = 53000

However, it only gets my first input and ignores the rest. Any ideas?

10
  • question/hint: what happens if I run $(".price").val(10); in my console? Can I eat for a Total of 40 at your place, or do we have an issue? Commented Feb 12, 2019 at 8:02
  • @Thomas soory didn't get your point Commented Feb 12, 2019 at 8:04
  • @Thomas ok i got it now :) then you give me idea? my prices are coming in data loop and my sum function is out of that loop, how can I access those prices without printing them in hidden input? Commented Feb 12, 2019 at 8:08
  • I don't know how exactly your site works, but having the price that exposed in the frontend provides way to much attack surface. You have the price in a hidden input, do you send it to the backend? does the backend check the price it got sent or does it just accept it as truth? What if I have a screenshot of your page showing Total = 7500 but you charge me 15000 what's the legally binding price? Do you have to sell xy to me for 7500 because that was the price you showed me? ... and more stuff like that Commented Feb 12, 2019 at 8:09
  • @Thomas I see, I just paid attention to that and saw my sum function is actually inside my data loop, is there anyways I can pass that `row['price'] into my sum function? so i calculate it in there instead of getting it from input? Commented Feb 12, 2019 at 8:14

4 Answers 4

1

You are not adding all items prices. You need to loop through all items and calculate total.

Note: keep this after your forEach statement. Try this:

$('.qty').on('keyup',function() {
    var quantities = $('.qty');
    var prices = $('.price');
    var total = 0;
   $.each(quantities, (index, qty) => {
        total += parseInt($(qty).val() || 0) * parseFloat($(prices[index]).val() || 0) 
    });
    $("#total").html(total);
});
Sign up to request clarification or add additional context in comments.

6 Comments

thanks, it returns TypeError: quantities.forEach is not a function
Updated the answer, check now.
it says TypeError: qty.val is not a function
can you check now.
there is some issues i made you small video i thought it could explain better streamable.com/y1csy
|
0

I think the problem is, that you cant get the value from multiple elements with the function ".val()". You only can get multiple values from one element.

You need another function to do want you want to achieve.

You should have a look here: Stackoverflow Question

Anway - you should not save prices into hidden html elements in production environments.

1 Comment

hi, sorry i didn't get that map function, it only gets the inputs where do I calculate them?
0

Iterate over the parent element to find the exact price and quantity for each element.

$('.qty').on('keyup',function(){
    var total = 0;
    $('.card-body').each(function(){
        var qty = parseFloat($(this).find('.qty').val());
        if (!qty) return;
        var price = parseFloat($(this).find('.price').val());
        total += (qty * price);
    });
    $("#total").html(total);
});

Attaching a Fiddle

3 Comments

it has 2 issues, 1 it can't get if i only fill one item quantity (must be multiple) 2 it sum wrong.
Edited it, hadn't handled the case where the quantity is null.
Check the fiddle attached, I have added dummy data and used the function to demonstrate the total
0

I don't know jQuery, though I can help you with vanilla JS.

The problem here is:

$('.qty').on('keyup',function(){
            var qty = $('.qty').val();
            var price = $('.price').val();

            $("#total").html(qty*price);
         });

This is setting an event listener only for the first .qty, even though there are many of them. So, you should select and iterate over them all, just like you did with the data:

let qtyNodes = document.querySelectorAll('.qty');
let priceNodes = document.querySelectorAll('.price');

let outputNode = document.querySelector('#total');
let sum = 0;

qtyNodes.forEach(function(qtyNode) { // Set event listener to every single qty node 

    qtyNode.addEventListener('keyup', function() {

        qtyNodes.forEach((qtyNode, index) => { // Calculate final price, using each meal price per quantity value.
            sum = qtyNode.value * priceNodes[index].value;
        })

    });

})

outputNode.innerHTML = `${sum}`;

It is important that you keep the arrays-like (qtyNodes and priceNodes) outside the given loop, as it will be accessing the DOM at each iteration and will demand too much performance. Placing it outside, you will access the DOM only one time.

Also, note that: you should be using "input" event, as opposed to "keyup". Input events will fire as soon as the user insert any data, just like a combination of "keyup" and "keydown".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.