Wednesday, August 21, 2013

Add a Repeater inside a GridView in ASP.NET and implement Expand/Collapse rows in GridView using javascript/jQuery

This article will explain how to add a repeater inside a grid view. This will help you to display well organized data to the end users. Also it is good if we can allow user to expand/ collapse records at once or once by one. If there are lot of records exists in the record set, always better to display in this way. For this example i'm using Adventure works database ProductCategory & ProductSubCategory Tables to demonstrate this topic. Hope this will help someones' life easy :). You can download the sample code snippet end of this article.

Create the following markup in your application. And add jQuery library (i'm using both java-script and jQuery to do this. But if you like just go with jQuery either java-scripts). I use this example just to give you the idea behind the topic.


<div id="divWrapper">
<div>
    <table>
        <tr>
            <td style="width: 15px; padding-left: 2px;">
                <a href="JavaScript:ExpandCollapseAll();" id="div_0">
                    <img id="imgdiv_0" width="9" border="0" src='<%= ResolveClientUrl("~/images/ig_treeMsdn_plus.gif") %>' />
            </td>
            <td style="font-weight: bold; font-size: 16px;">
                View Product Categories & sub categories
            </td>
        </tr>
    </table>
</div>
<div>
    <asp:GridView ID="gvProductsCategory" runat="server" AutoGenerateColumns="false" GridLines="Both" ShowHeader="false"
        ShowFooter="false" Width="100%">
        <RowStyle BackColor="#A0EFFA" ForeColor="#333333" />
        <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
        <EmptyDataTemplate>
            No Products were found!
        </EmptyDataTemplate>
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <table style="width: 100%;" class="removeCellPaddingsAll">
                        <tr>
                            <td style="width: 20px; height: 25px;">
                                <a href="JavaScript:ExpandCollapseDiv('div_<%# Eval("ProductCategoryID") %>');">
                                    <img id='imgdiv_<%# Eval("ProductCategoryID") %>' width="9" border="0" src='<%= ResolveClientUrl("~/images/ig_treeMsdn_plus.gif") %>'
                                        class="CollapseExpandIMGClass" />
                            </td>
                            <td style="width: 130px;">
                                <%#Eval("Name")%>
                            </td>
                            <td>
                                <%# Eval("rowguid")%>
                            </td>
                        </tr>
                        <tr>
                            <td colspan="3">
                                <div id='div_<%# Eval("ProductCategoryID") %>' style="display: none; border-top: 1px solid darkgray;"
                                    class="CollapseExpandDIVClass">
                                    <asp:Repeater ID="rptProductSubCategory" runat="server" DataSource='<%# DataBinder.Eval(Container, "DataItem.InnerVal") %>'>
                                        <HeaderTemplate>
                                            <table style="width: 100%;">
                                        </HeaderTemplate>
                                        <ItemTemplate>
                                            <tr>
                                                <td style="width: 30px; height: 25px;" />
                                                <td style="width: 120px;">
                                                    <%#Eval("Name") %>
                                                </td>
                                                <td>
                                                    <%#Eval("ModifiedDate")%>
                                                </td>
                                            </tr>
                                        </ItemTemplate>
                                        <FooterTemplate>
                                            </table>
                                        </FooterTemplate>
                                    </asp:Repeater>
                                </div>
                            </td>
                        </tr>
                    </table>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
</div>
</div>

Following code snippet for expand/ collapse gridview rows using javascipts. Add this scripts to head tag in the page.

<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>
    <script type="text/javascript">
        var expanded = false;
        var collapseImage = '<%= ResolveClientUrl("~/images/ig_treeMsdn_plus.gif")%>';
        var expandImage = '<%= ResolveClientUrl("~/images/ig_treeMsdn_minus.gif")%>';

        function ExpandCollapseDiv(divname) {
            var div = document.getElementById(divname);
            var img = document.getElementById('img' + divname);

            if (div.style.display == "none") {
                div.style.display = "block";
                img.src = expandImage;
                expanded = true;
            } else {
                div.style.display = "none";
                img.src = collapseImage;
                expanded = false;
            }

            $(".CollapseExpandDIVClass").each(function (index) {
                console.log(index + ": " + $(this).text());
                console.log($(this).css("display") == "block");
                if ($(this).css("display") == "block") {
                    expanded = true;
                }
            });


            if (expanded) {
                $('#imgdiv_0').attr("src", expandImage);
            }
            else {
                $('#imgdiv_0').attr("src", collapseImage);
            }

        }
        function ExpandCollapseAll() {
            if (expanded) {
                $('.CollapseExpandDIVClass').css("display", "none");
                $('.CollapseExpandIMGClass').attr('src', collapseImage);
                $('#imgdiv_0').attr('src', collapseImage);
                expanded = false;
            }
            else {
                $('.CollapseExpandDIVClass').css("display", "block");
                $('.CollapseExpandIMGClass').attr('src', expandImage);
                $('#imgdiv_0').attr('src', expandImage);
                expanded = true;
            }
        }
    </script>
</head>

The C# code,
 protected void Page_Load(object sender, EventArgs e)
        {
            DataSet _dsProducts = new DataSet();
            // create connection string
            using (SqlConnection _con = new SqlConnection(@"Data Source=ARUNA\MSSQLSERVER1;Initial Catalog=AdventureWorks2008R2;Integrated Security=True"))
            {
                using (SqlCommand _cmd = new SqlCommand())
                {
                    _cmd.CommandText = "sp_GetProducts";
                    _cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    _cmd.Connection = _con;
                    SqlDataAdapter _adapter = new SqlDataAdapter(_cmd);

                    if (_con.State != ConnectionState.Open)
                        _con.Open();
                    _adapter.Fill(_dsProducts); // this will fill _dsProducts with two tables

                    // this will map the dataset into two tables which returns from sp
                    _dsProducts.Tables["Table"].TableName = "ProductCategory";
                    _dsProducts.Tables["Table1"].TableName = "ProductSubcategory";
                }
            }

            // lets create the relation with two tables
            _dsProducts.Relations.Add(
                        "InnerVal",
                        _dsProducts.Tables["ProductCategory"].Columns["ProductCategoryID"],
                        _dsProducts.Tables["ProductSubcategory"].Columns["ProductCategoryID"]);

            gvProductsCategory.DataSource = _dsProducts.Tables["ProductCategory"];
            gvProductsCategory.DataBind();
        }

Following SP is to get some dummy records for demonstration purposes using AdventureWorks2008R2 database.

USE AdventureWorks2008R2
-- =============================================
-- Author      : Aruna Perera (anishantha87.blogspot.com)
-- Create date : 2013-08-21
-- Description : Returns Product category & sub category
-- =============================================
CREATE PROCEDURE sp_GetProducts
 
AS
BEGIN

 SET NOCOUNT ON;

 SELECT TOP 4 [ProductCategoryID],
  [Name],
  [rowguid]
 FROM   [AdventureWorks2008R2].[Production].[ProductCategory]

 SELECT TOP 40 [ProductSubcategoryID],
  [ProductCategoryID],
  [Name],
  [ModifiedDate]
 FROM   [AdventureWorks2008R2].[Production].[ProductSubcategory] 

END
GO

Sample output
Download

No comments:

Post a Comment