3 (and more) level hierarchy

jqGrid for ASP.NET supports infinite number of nested subgrids. Just make sure you define a separate grid for each level (e.g. 3 grids for 3-level hierarchy). The parent grid should have its HierarchySettings.HierarchyMode set to Parent, grids that are both parent and child (e.g. the second grid in a 3-level hierarchy) should have their HierarchySettings.HierarchyMode set to ParentAndChild and grids that have no child grids (leaf) should have their HierarchySettings.HierarchyMode set to Child. In the screenshot below, you can see a 3-level hierarchy Customers -> Orders -> OrderDetails.

This approach allows fully functional child grids with all the features and programming model you would expect from a normal grid - there are no limitations.

For this type of scenario you will need three grid definitions - one for the parent grid (Customers), one of the 2nd grid (Orders) and one for the child (OrderDetails). The key here is to set the HierarchySettings.HierarchyMode of the parent grid to Parent and to hook its client-side event SubGridRowExpanded. This can be achieved in the following way:

<trirand:JQGrid runat="server" ID="JQGrid1" DataSourceID="SqlDataSource1"> <Columns> <trirand:JQGridColumn DataField="CustomerID" HeaderText="ID" PrimaryKey="True" Width="50" /> <trirand:JQGridColumn DataField="CompanyName" /> <trirand:JQGridColumn DataField="ContactName" /> <trirand:JQGridColumn DataField="Phone" /> <trirand:JQGridColumn DataField="City" /> </Columns> <HierarchySettings HierarchyMode="Parent" /> <ClientSideEvents SubGridRowExpanded="showSubGrid" /> </trirand:JQGrid> <asp:SqlDataSource runat="server" ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:SQL2008_449777_fhsConnectionString %>" SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName], [Phone], [City] FROM [Customers]"> </asp:SqlDataSource>

The client-side event designated by ClientSideEvents.SubGridRowExpanded should call a special autogenerated function which will expand the grid. The name of the autogenerated function is fixed and is always "showSubGird_GridID", where "GridID" is the ID of the grid. Example:

<script type="text/javascript"> function showSubGrid(subgrid_id, row_id) { // the "showSubGrid_JQGrid2" function is autogenerated and available globally on the page by the second child grid. // Calling it will place the child grid below the parent expanded row and will call the OnDataRequesting event // of the child grid, with ID equal to the ID of the parent expanded row showSubGrid_JQGrid2(subgrid_id, row_id); } </script>

Setting up the the second grid is similar to that, the difference being that the HierarchySettings.HierarchyMode property should be set to ParentAndChild. In most cases you would also typically need to hook the OnDataRequesting event - this even will fire just prior to binding the grid with data and can be used to pass the parent row key to the child grid before requesting the data - this is usually required to change the SQL query to only fetch records that are children of the parent row. Similar to the parent grid, you would also need to hook the client-side event SubGridRowExpanded, in order to show the third grid.

<trirand:JQGrid runat="server" ID="JQGrid2" DataSourceID="SqlDataSource2" Width="550px" OnDataRequesting="JQGrid2_DataRequesting"> <Columns> <trirand:JQGridColumn DataField="OrderID" HeaderText="Order ID" PrimaryKey="True" Width="50" /> <trirand:JQGridColumn DataField="RequiredDate" DataFormatString="{0:d}" Width="100" /> <trirand:JQGridColumn DataField="ShipName" Width="200" /> <trirand:JQGridColumn DataField="ShipCity" Width="100" /> <trirand:JQGridColumn DataField="Freight" Width="100" /> </Columns> <HierarchySettings HierarchyMode="ParentAndChild" /> <ClientSideEvents SubGridRowExpanded="showSubGrid3" /> </trirand:JQGrid> <asp:SqlDataSource runat="server" ID="SqlDataSource2" ConnectionString="<%$ ConnectionStrings:SQL2008_449777_fhsConnectionString %>" SelectCommand="SELECT [OrderID], [CustomerID], [RequiredDate], [ShipName], [ShipCity], [Freight] FROM [Orders] WHERE ([CustomerID] = @CustomerID)"> <SelectParameters> <asp:Parameter DefaultValue="" Name="CustomerID" Type="String" /> </SelectParameters> </asp:SqlDataSource>

<script type="text/javascript"> // the "showSubGrid_JQGrid3" function is autogenerated by the third child grid. Calling it will place the child grid below // the parent expanded row and will call the OnDataRequesting event of the child grid, with ID equal to the ID of the parent function showSubGrid3(subgrid_id, row_id) { showSubGrid_JQGrid3(subgrid_id, row_id); } </script>

public void JQGrid2_DataRequesting(object sender, JQGridDataRequestEventArgs e) { SqlDataSource2.SelectParameters["CustomerID"].DefaultValue = e.ParentRowKey; }

Setting up the third child (leaf) grid is similar, just set the HierarchySettings.HierarchyMode property to Child. In most cases you would also typically need to hook the OnDataRequesting event - this even will fire just prior to binding the grid with data and can be used to pass the parent row key to the child grid before requesting the data - this is usually required to change the SQL query to only fetch records that are children of the parent row.

<trirand:JQGrid runat="server" ID="JQGrid3" DataSourceID="SqlDataSource3" Width="350px" Height="100%" OnDataRequesting="JQGrid3_DataRequesting"> <Columns> <trirand:JQGridColumn DataField="OrderID" PrimaryKey="True" Width="50" /> <trirand:JQGridColumn DataField="ProductID" /> <trirand:JQGridColumn DataField="UnitPrice" Width="200" /> </Columns> <ToolBarSettings ShowRefreshButton="true" ShowSearchButton="true" /> <HierarchySettings HierarchyMode="Child" /> </trirand:JQGrid> <asp:SqlDataSource runat="server" ID="SqlDataSource3" ConnectionString="<%$ ConnectionStrings:SQL2008_449777_fhsConnectionString %>" SelectCommand="SELECT [OrderID], [ProductID], [UnitPrice], [Quantity], [Discount] FROM [Order Details] WHERE ([OrderID] = @OrderID)"> <SelectParameters> <asp:Parameter Name="OrderID" Type="Int32" /> </SelectParameters> </asp:SqlDataSource>

public void JQGrid3_DataRequesting(object sender, JQGridDataRequestEventArgs e) { SqlDataSource3.SelectParameters["OrderID"].DefaultValue = e.ParentRowKey; }


  Last Updated: 11/12/2009 | © Trirand, 2009