0

I have following HTML code:

<table>
   <th>Items</th><th>Rate</th><th>Quantity</th>
   <tr><td>Item A</td><td>20</td><td><input type="text" id="txtItemA"/></td></tr>
   <tr><td>Item B</td><td>10</td><td><input type="text" id="txtItemB"/></td></tr>
   <tr><td>Item C</td><td>30</td><td><input type="text" id="txtItemC"/></td></tr>
   <tr><td>Total Price</td><td><input type="text" id="txtPrice"/></td></tr>
</table>

On the onblur event of textboxes, I want to call a javascript function which will multiply the quantity added by the user to the rate and display it in txtPrice textbox. But I am stuck in the logic that how should I pick the rate corresponding to the quantity entered.

For example: When I enter 2 in txtItemA textbox, 40 should get displayed in txtPrice textbox. Javascript function is simple it will just multiply rate with quantity entered and display it in txtPrice.

What should I do to get to fetch the associated rate against the quantity and pass it to javascript function?

Javascript function

function DisplayTotal(rate, quantity)
{
  document.getElementById('txtPrice').innerText = rate * quantity;
}
6
  • How is rate determined in the first place? Depending on whether there are a few set rates or infinite changes how you would go about solving this. Commented Dec 20, 2013 at 11:33
  • 5
    like jsfiddle.net/arunpjohny/5jGep/1 Commented Dec 20, 2013 at 11:35
  • @DBS - For the time being, I am considering these as constants. Commented Dec 20, 2013 at 11:35
  • as an addition to Arun P Johny' solution, you can make it more performant by saving the result for each row in a special array, and then you need to recalculate only one particular row each time. But this is useful only for really big tables like that Commented Dec 20, 2013 at 11:37
  • 2
    or jsfiddle.net/arunpjohny/5jGep/2 Commented Dec 20, 2013 at 11:37

7 Answers 7

3

Give the elements in question a common class, say class="quantity", so that they can easily be selected without listing out the ids or having too general a selector that also picks up the total price field, and then you can do this:

var $qtyFields = $('input.quantity').change(function() {
    var price = 0;
    $qtyFields.each(function() {
        price += this.value * $(this).closest("tr").find("td:eq(1)").text();
    });
    $("#txtPrice").val(price);
});

Demo: http://jsfiddle.net/95hje/

That is, loop through each field and multiply its value by the rate column in the same row. Finding a related element by using .closest() to get a common ancestor and then .find() to traverse back down is a common pattern.

Note that the * operator will coerce its operands to be numeric, but the code I've shown doesn't actually do any validation so if the user enters non-numeric data the total will be NaN...

Sign up to request clarification or add additional context in comments.

Comments

2

A pure javascript solution (no JQuery) which will work even if you change the number of rows in your table and which handles the problem of invalid user input:

<html>
<head>
<script type="text/javascript">
function DisplayTotal(){
var num = document.getElementById("myTable").rows.length-2;
var tds = document.getElementsByTagName("td"), total = 0, rate, quant;
    for(var i = 0; i < num; i++){
    rate = parseInt(tds[3*i+1].innerHTML);
    quant = parseInt(tds[3*i+2].firstChild.value);
        if(isNaN(quant)){
        continue;
        }
    total += rate*quant;
    }
document.getElementById("txtPrice").value = total;
}
</script>
</head>
<body>
<table id="myTable">
    <tr><th>Items</th><th>Rate</th><th>Quantity</th></tr>
    <tr><td>Item A</td><td>20</td><td><input type="text" id="txtItemA" onkeyup="DisplayTotal();"></td></tr>
    <tr><td>Item B</td><td>10</td><td><input type="text" id="txtItemB" onkeyup="DisplayTotal();"></td></tr>
    <tr><td>Item C</td><td>30</td><td><input type="text" id="txtItemC" onkeyup="DisplayTotal();"></td></tr>
    <tr><td>Item D</td><td>50</td><td><input type="text" id="txtItemD" onkeyup="DisplayTotal();"></td></tr>
    <tr><td>Total Price</td><td><input type="text" id="txtPrice"></td></tr>
</table>
<button type="button" onclick="DisplayTotal();">Get Total Price</button>
</body>
</html>

See demo here.

Comments

1

jsfiddle : http://jsfiddle.net/FeLKx/4/

HTML :

<table class="items">
    <thead>
        <th>Items</th>
        <th>Rate</th>
        <th>Quantity</th>
    </thead>
    <tbody>
        <tr class="item">
            <td>Item A</td>
            <td class="rate">20</td>
            <td class="quantity">
                <input type="text" id="txtItemA" />
            </td>
        </tr>
        <tr class="item">
            <td>Item B</td>
            <td class="rate">10</td>
            <td class="quantity">
                <input type="text" id="txtItemB" />
            </td>
        </tr>
        <tr class="item">
            <td>Item C</td>
            <td class="rate">30</td>
            <td class="quantity">
                <input type="text" id="txtItemC" />
            </td>
        </tr>
        <tr>
            <td>Total Price</td>
            <td>
                <input type="text" id="txtPrice" />
            </td>
        </tr>
    </tbody>
</table>

JS :

$(document).ready(function () {
    $('.items .item .quantity input').blur(function () {
        var total = 0;

        $('.items .item').each(function(index, value) {
            var rate = $(this).find('.rate').text();
            var quantity = $(this).find('.quantity input').val();

            total += rate * quantity;
        });

        $('#txtPrice').val(total);
    });
});

Comments

1

Change your markup to add some classes to the input elements for easy selection

<table>
    <th>Items</th>
    <th>Rate</th>
    <th>Quantity</th>
    <tr>
        <td>Item A</td>
        <td>20</td>
        <td>
            <input type="text" class="txtItem" id="txtItemA" />
        </td>
    </tr>
    <tr>
        <td>Item B</td>
        <td>10</td>
        <td>
            <input type="text" class="txtItem" id="txtItemB" />
        </td>
    </tr>
    <tr>
        <td>Item C</td>
        <td>30</td>
        <td>
            <input type="text" class="txtItem" id="txtItemC" />
        </td>
    </tr>
    <tr>
        <td>Total Price</td>
        <td>
            <input type="text" id="txtPrice" />
        </td>
    </tr>
</table>

then

jQuery(function () {
    var $items = $('.txtItem').change(function () {
        var total = 0;
        $items.each(function () {
            total += ($(this).data('price') * parseInt(this.value)) || 0;
        })
        $('#txtPrice').val(total)
    }).each(function () {
        //store the price of the item in data for easy access later
        $(this).data('price', parseInt($(this).parent().prev().text(), 10) || 0);
    })
})

Demo: Fiddle

Comments

1

This is your html

<table>
   <th>Items</th><th>Rate</th><th>Quantity</th>
   <tr><td>Item A</td><td>20</td><td><input type="text" id="txtItemA"/></td></tr>
   <tr><td>Item B</td><td>10</td><td><input type="text" id="txtItemB"/></td></tr>
   <tr><td>Item C</td><td>30</td><td><input type="text" id="txtItemC"/></td></tr>
   <tr><td>Total Price</td><td><input type="text" id="txtPrice"/></td></tr>
</table>

This will be your script

$(document).ready(function(){
    $('table').on('blur','td input[id^=txtItem]',function(){
        var fields = $('td input[id^=txtItem]');
        var total = 0;

        $.each(fields,function(index,value){
            var quantity = $(this).val();
            var rate = $(this).parent('td').prev('td').text();
            total += (quantity * rate);            
        });       
        $('#txtPrice').val(total);
    });
});

JSFIDDLE DEMO

On a note I strongly recommend you don't rely on javascript to finally charge the visitor as this can be easily changed to 0 using javascript

2 Comments

Thanks for advice, I will also calculate all these values on server side.
Cool hope this answers your query
1

I have simpliest solution I guess (without jQuery):

<html lang="en">
<head>
    <title><!-- Insert your title here --></title>
    <script language="javascript" type="text/javascript">
         function DisplayTotal()
         {
            var quantity = 0, rate = 0, total=0;
            var i=0;
            do {
                var c = document.getElementById("txtItem" + i++);
                if (c) {
                    var r = c.parentNode.previousSibling;
                    if (c.value) {
                        quantity = parseFloat(c.value);
                        rate = parseFloat(r.innerHTML);
                        total += quantity * rate;
                    }
                }
            } while(c);
            document.getElementById('txtPrice').value = total.toFixed(2);
         }
    </script>
</head>
<body>
   <table>
   <th>Items</th><th>Rate</th><th>Quantity</th>
   <tr><td>Item A</td><td>20</td><td><input type="text" id="txtItem0"  onblur="DisplayTotal()"/></td></tr>
   <tr><td>Item B</td><td>10</td><td><input type="text" id="txtItem1" onblur="DisplayTotal()"/></td></tr>
   <tr><td>Item C</td><td>30</td><td><input type="text" id="txtItem2" onblur="DisplayTotal()"/></td></tr>
   <tr><td>Total Price</td><td><input type="text" id="txtPrice"/></td></tr>
   </table>
</body>

4 Comments

what if I have random items?
what do you mean ? random rows or colons ?
you have made an array containing txtItemA...txtItemC. I could have more or less number of items in actual website.
change the id with a prefix like "txtItem" and a number (row). In the code use innerHTML than innerText.
0

See demo here http://jsfiddle.net/UFS97/1/

HTML

<table id="invoice_tbl">
        <th>Items</th>
        <th>Rate</th>
        <th>Quantity</th>
        <tr class="item">
            <td>Item A</td>
            <td>20</td>
            <td>
                <input type="text" class="item_price" id="txtItemA" value=""/>
            </td>
        </tr>
        <tr class="item">
            <td>Item B</td>
            <td>10</td>
            <td>
                <input type="text" class="item_price" id="txtItemB"/>
            </td>
        </tr>
        <tr class="item">
            <td>Item C</td>
            <td>30</td>
            <td>
                <input type="text" class="item_price" id="txtItemC" value=""/>
            </td>
        </tr>
        <tr>
            <td>Total Price</td>
            <td>
                <input type="text" id="txtPrice"/>
            </td>
        </tr>
    </table>



jQUery
---------------------------
    $(document).ready(function(){ 
    $(".item_price").blur(function(){
    total = 0.00;
    item_row = $("table#invoice_tbl").children('tbody').children("tr.item");
    item_row.each(function(){
        item_price = parseFloat($(this).children('td').eq(1).html());
        item_qty = parseInt($(this).children('td').eq(2).children('input').val());
        row_price = item_price*item_qty;
        if(!isNaN(row_price)){
            total +=row_price;
        }
    });
    $("#txtPrice").val(total);
});
});

See demo here http://jsfiddle.net/UFS97/1/

Comments

Your Answer

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