Our Blog

Creating a nested GridView in ASP.Net using very little jQuery code

Plamen Penev
by Plamen Penev on Fri 20 December 2013 2 comments

In this example, I will show how to create a nested GridView, i.e. a GridView under another GridView, using very little jQuery code.

NestedGrid

Background

I will use the Northwind database for this example.

Quick Start

In Master GridView I’ll display ContactName and City from ‘Customer’ table. Then in the Child GridView I’ll show you Order details of corresponding Customers i.e. OrderID and OrderDate.

I’ll insert ‘plus sign image’ to the First Column of every row. When I click this ‘plus sign image’ then the Child GridView will be displayed and the ‘plus sign image’ will be the ‘minus sign image’. And when I click the ‘minus sign image’ the Child GridView will be removed and ‘minus sign image’ becomes the ‘plus sign image’ like toggle. So, I have to take an ItemTemplate within a TemplateField inside the Columns on first position.

<asp:GridView ID="grdViewCustomers" runat="server" AutoGenerateColumns="false" DataKeyNames="CustomerID" OnRowDataBound="grdViewCustomers_OnRowDataBound" CssClass="Grid">
    <Columns>
        <asp:TemplateField ItemStyle-Width="20px">
            <ItemTemplate>
                <a href="JavaScript:divexpandcollapse('div<%# Eval("CustomerID") %>');">
                <img alt="Details" id="imgdiv<%# Eval("CustomerID") %>" src="images/plus.png" /></a>
                <div id="div<%# Eval("CustomerID") %>" style="display: none;">
                <asp:GridView ID="grdViewOrdersOfCustomer" runat="server" AutoGenerateColumns="false" DataKeyNames="CustomerID" CssClass="ChildGrid">
                    <Columns>
                         <asp:BoundField ItemStyle-Width="150px" DataField="OrderID" HeaderText="Order ID" />
                         <asp:BoundField ItemStyle-Width="150px" DataField="OrderDate" HeaderText="Order Date" />
                    </Columns>
                </asp:GridView>
                </div>
            </ItemTemplate>
       </asp:TemplateField>
       <asp:BoundField ItemStyle-Width="150px" DataField="ContactName" HeaderText="Contact Name" />
       <asp:BoundField ItemStyle-Width="150px" DataField="City" HeaderText="City" />
    </Columns>
</asp:GridView>

Now, you see that I have linked a JavaScript function to the ‘plus sign image’ which does all the functionality against the Click event of the ‘plus sign image’. This JavaScript function takes the Div name in which the Child GridView exists. There will be one Child GridView for each row of the Master GridView. So the Div id must be different. That’s why I concatenate Div id with CustomerID and there will be one ‘plus sign image’ for each row of the Master GridView. I also concatenate the img id with CustomerID. In the Div, just after the link of the ‘plus sign image’ the Child GridView,  is implemented.

Let’s see the little piece of JQuery which checks whether the ‘plus sign image’ source contains the path of the ‘plus sign’ image or ‘minus sign’ image and does the  functionality accordingly:

<script type="text/javascript">
     function divexpandcollapse(divname) {
         var img = "img" + divname;
         if ($("#" + img).attr("src") == "images/plus.png") {
             $("#" + img)
             .closest("tr")
             .after("<tr><td></td><td colspan = '100%'>" + $("#" + divname)
             .html() + "</td></tr>");
             $("#" + img).attr("src", "images/minus.png");
         } else {
             $("#" + img).closest("tr").next().remove();
             $("#" + img).attr("src", "images/plus.png");
         }
    }
</script>

Now the client side part is over. Child GridView is filled in an event which is triggered when there is one container control within the row of the GridView. The event is OnRowDataBound. And I’ve already added this event to the Master GridView properties and the name of event handler is: grdViewCustomers_OnRowDataBound. And we also fill the Master GridView in the Page_Load() event. So here is the implementation in the code behind:

public partial class NestedGridView : System.Web.UI.Page
{
     protected void Page_Load(object sender, EventArgs e)
     {
          grdViewCustomers.DataSource = SelectData("SELECT top 3 CustomerID, ContactName, City FROM Customers");
          grdViewCustomers.DataBind();
     }
     private DataTable SelectData(string sqlQuery)
     {
         string connectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["SQLServerConnectionString"].ConnectionString;
         using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlQuery, connectionString))
         {
             DataTable dt = new DataTable("Customers");
             sqlDataAdapter.Fill(dt);
             return dt;
         }
      }
      protected void grdViewCustomers_OnRowDataBound(object sender, GridViewRowEventArgs e)
      {
         if (e.Row.RowType == DataControlRowType.DataRow)
         {
             string customerID = grdViewCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
             GridView grdViewOrdersOfCustomer = (GridView)e.Row.FindControl("grdViewOrdersOfCustomer");
             grdViewOrdersOfCustomer.DataSource = SelectData("SELECT top 3 CustomerID, OrderID, OrderDate FROM Orders WHERE CustomerID='" + customerID + "'");
             grdViewOrdersOfCustomer.DataBind();
         }
      }
}
Plamen PenevCreating a nested GridView in ASP.Net using very little jQuery code

2 comments

Join the conversation
  • erictrarner - Thu 27 February 2014 reply

    Tutorial on asp.net gridview

    http://asp.net-informations.com/gridview/asp-gridview.htm

    asp.net tutorial

  • Ron - Tue 7 June 2016 reply

    how would you force the first row to default to being displayed at the start. For example if your gridview has only one row then the inner gridview should display without the user having to click the plus sign

Join the conversation