Sunday, April 29, 2012

How to edit the gridview row data in client side

I always use GridView to show the transactoins or product list in hand without using third party product such as Telerik control. I have to calculate the price or grand total on GridView often. In that sample, I am developing code to show how to access every row and cell from JavaScript, and populate some data operation on these row and cell as below image.
Populating the row data in client side

Frist, create a gridview as below. Here, I used "Products" table from "Northwind" db and loaded data using Entity Framework.
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
Width="492px" OnPageIndexChanging="GridView1_PageIndexChanging" 
ShowFooter="True" onrowdatabound="GridView1_RowDataBound">
<Columns>
    <asp:BoundField DataField="ProductID" HeaderText="ProductID" />
    <asp:BoundField DataField="ProductName" HeaderText="Name" />
    <asp:BoundField DataField="UnitPrice" HeaderText="Price/Unit" DataFormatString="{0:F}" />
    <asp:TemplateField HeaderText="Qty">
        <ItemTemplate>
            <asp:DropDownList ID="DropDownList1" runat="server" onchange="showData(this)">
                <asp:ListItem Selected="True" Text="1" Value="1"></asp:ListItem>
                <asp:ListItem Text="2" Value="2"></asp:ListItem>
                <asp:ListItem Text="3" Value="3"></asp:ListItem>
                <asp:ListItem Text="4" Value="4"></asp:ListItem>
                <asp:ListItem Text="5" Value="5"></asp:ListItem>
            </asp:DropDownList>
        </ItemTemplate>
        <FooterTemplate>
            <asp:Label ID="lblTotalPrice" runat="server" Text="Grand Total"></asp:Label>
        </FooterTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Price">
        <ItemTemplate>
            <asp:Label ID="lblPrice" runat="server" Text='<%# Eval("UnitPrice", "{0:F}") %>'></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>
</Columns>
</asp:GridView>

Second, here is the javascript that "showData(this)" is called from onchange metod of drop down list which is in the Item Template of GridView.
<script language="javascript" type="text/javascript">
function showData(dropdown) {
        //get dropdownlist 
        var myindex = dropdown.selectedIndex;
        var SelValue = dropdown.options[myindex].value;
        //get the row of the drop down list
        var row = getParentRow(dropdown);
        var newRate = 0;
        //set value in the cell of grid view
        if (isFireFox()) {
            newRate = parseFloat(row.cells[2].textContent) * SelValue;
        }
        else {
            newRate = parseFloat(row.cells[2].innerText) * SelValue;
        }
        row.cells[4].innerHTML = newRate.toFixed(2);
        //set background color if selected value is greater than 1
        if (SelValue > 1) {
            row.style.backgroundColor = 'Silver';
        } else {
            row.style.backgroundColor = '';
        }
        //get gridview
        var gridViewCtlId = '<%=GridView1.ClientID%>';
        var grid = document.getElementById(gridViewCtlId);
        var gridLength = grid.rows.length;
        var sum = 0;
        //calculate sum of the prices looping through the gridview and operation in every cell
        for (var i = 1; i < gridLength - 2; i++) {
            if (isFireFox()) {
                sum = sum + parseFloat(grid.rows[i].cells[4].textContent);
            }
            else {
                sum = sum + parseFloat(grid.rows[i].cells[4].innerText);
            }
        }
        grid.rows[gridLength - 2].cells[4].innerHTML = sum.toFixed(2);
    }
    function getParentRow(obj) {
        while (obj.tagName != "TR") {
            if (isFireFox()) {
                obj = obj.parentNode;
            }
            else {
                obj = obj.parentElement;
            }
        }
        return obj;
    }
    function isFireFox() {
        return navigator.appName == "Netscape";
    }
</script>

Finally, put the following snippet in code-behind.
decimal total;
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        using (var container = new NorthwindEntities())
        {
            GridView1.DataSource = container.Products.ToList();
            GridView1.DataBind();
        }

    }
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    using (var container = new NorthwindEntities())
    {
        GridView1.PageIndex = e.NewPageIndex;
        GridView1.DataSource = container.Products.ToList();
        GridView1.DataBind();
    }
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    //calculate the grand total here
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        total += Convert.ToDecimal(DataBinder.Eval(e.Row.DataItem, "UnitPrice"));

    }
    else if (e.Row.RowType == DataControlRowType.Footer)
    {
        e.Row.Cells[4].Text = total.ToString("#,##0.00");
    }
}

Everytime you select the dropdown list, it calculate the price and change the grand total.
Note : It don't keep the selected values across the pages.

Original post here

No comments:

Post a Comment