Jun 03, 2012

Quantity Validation and Total Calculation in ASP.NET Gridview Shopping Cart with jQuery

In this article, You will get how to implement following features in ASP.NET Gridview shopping cart using jQuery:

1. Enter Numeric quantity for product which must not exceed available quantity.

2. Calculate product wise total price based on entered quantity.

3. Calculate grand total of cart if any quantity is updated.

shopping cart gridview

Consider following gridview structure:


<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" ShowFooter="true" >
        <Columns>
            <asp:BoundField DataField="Code" HeaderText="Code" />
            <asp:BoundField DataField="ProductName" HeaderText="Name" />
            <asp:BoundField DataField="AvlQty" HeaderText="Available Qty" ItemStyle-CssClass="avlQty" />
            <asp:BoundField DataField="Price" DataFormatString="{0:0.00}" ItemStyle-CssClass="price" 
                HeaderText="Price" />
            <asp:TemplateField HeaderText="Qty">
                <ItemTemplate>                
                    <asp:TextBox ID="TextBoxQty" CssClass="txtQty" runat="server" Text='<%# Eval("SelQty") %>' MaxLength="5" Width="45"></asp:TextBox>
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="TextBoxQty" Display="Dynamic" ForeColor="Red" ErrorMessage="RequiredFieldValidator">*</asp:RequiredFieldValidator>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Net Price">
                <ItemTemplate>
                    <span class="totalPrice"></span> 
                </ItemTemplate>
                <FooterTemplate>
                   Total: <span class="grandtotal"></span> 
                </FooterTemplate>
            </asp:TemplateField>
        </Columns>        
    </asp:GridView>

Here you notice that different CSS are applied on different columns. It'll be used in jQuery to get or set values.

Let us consider dummy data to bind gridview:


//product class
public class Product
{
    public string Code { get; set; }
    public string ProductName { get; set; }
    public int AvlQty { get; set; }
    public int SelQty { get; set; }
    public double Price { get; set; }
}

//Get product list
public List<Product> GetProducts()
    {

        var products = new List<Product>()
    {
	new Product(){ Code = "ASD123" , ProductName = "Product 1", AvlQty = 10, SelQty=1, Price = 12.5},
	new Product() {Code = "BBB123",	ProductName = "Product 2", AvlQty = 12, SelQty=1, Price = 15},
	new Product() {Code = "CCC123", ProductName = "Product 3", AvlQty = 15, SelQty=1, Price=20},
	new Product() {Code = "DDD123", ProductName = "Product 4", AvlQty = 20, SelQty=1, Price=37.5},
	new Product() {Code = "EEE123", ProductName = "Product 5", AvlQty = 21, SelQty=1, Price=25}
    };
        return products;

    }
//To bind gridview
 protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            GridView1.DataSource = GetProducts();
            GridView1.DataBind();
        }
    }

To implement quantity validation and total price calculation for valid quantity:



            //Change price and grand total on changing qty
            $('#<%=GridView1.ClientID %> .txtQty').blur(function () {
                var $tr = $(this).parents('tr');
                if ($tr.length > 0) {
                    if (parseInt($tr.find('.avlQty').html()) < $(this).val()) {
                        alert('Qty must not exceed available quantity.');
                        var $ctrl = $(this);
                        window.setTimeout(function () {
                            $ctrl.focus();
                         }, 50);
                        return false;
                    }
                    $tr.find('.totalPrice').html(parseFloat($tr.find('.price').html()) * parseInt($(this).val()));
                }
                CalculateGrandTotal();
            });
            //To get grand Total
            function CalculateGrandTotal() {
                var grandTotal = 0.0;
                $('#<%=GridView1.ClientID %> tr:gt(0)').each(function () {
                    grandTotal = grandTotal + parseFloat($(this).find('.totalPrice').length == 0 || !$(this).find('.totalPrice').html() ? 0 : $(this).find('.totalPrice').html());
                });
                $('#<%=GridView1.ClientID %> .grandtotal').html(grandTotal);
            }

To allow only numeric data in quantity textbox:


 //To allow numeric character only
            $('#<%=GridView1.ClientID %> .txtQty').keydown(function (event) {
                // Allow: backspace, delete, tab, escape, and enter
                if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
                // Allow: Ctrl+A
            (event.keyCode == 65 && event.ctrlKey === true) ||
                // Allow: home, end, left, right
            (event.keyCode >= 35 && event.keyCode <= 39)) {
                    // let it happen, don't do anything
                    return;
                }
                else {
                    // Ensure that it is a number and stop the keypress
                    if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                        event.preventDefault();
                    }
                }
            });

First time,total price should be auto calculated for all products:


 //First Time to display all total amount and grand total
            function initGrid() {
                $('#<%=GridView1.ClientID %> tr:gt(0)').each(function () {
                    $(this).find('.totalPrice').html(parseFloat($(this).find('.price').html()) * parseInt($(this).find('.txtQty').val()));

                });
                CalculateGrandTotal();
            }
			   initGrid();

Demo:

Here is the HTML rendered demo, In this requiredfield validator js code is not included, So It will not work. In following demo, Change qty in textbox, You will get total amount auto calculated:

Hope, It helps.