Jul
26
2012

Nested Repeaters, do it clean and simple – A Beginner’s Tutorial – Part 2

In my earlier article Nested Repeaters, do it clean and simple – A Beginner’s Tutorial – Part 1 , I showed you how to setup a Repeater to use a database backend to display Categories.  In this follow-up Article, we will add a Nested Repeater, allowing you to display a Sub-Category for each Main category.

Some SQL explanation

Nested Repeaters - Image 3I’ve seen some pretty nasty database layouts in the past but the Categories table I’ve laid out should be very straightforward.  Each Category has a name and a ParentId.

If the ParentId is NULL then it is a Main Category, if the Category is a Sub-Category, then simply set the ParentId to the categoryId of the Main Category.  Simple and clean, it also means that you can have subcategories many levels deep.

 

 

The Stored Procedure LocadCategories is as straightforward as they come;

ALTER PROCEDURE [dbo].[LoadCategories] 

AS
BEGIN

	SET NOCOUNT ON;

			SELECT     categoryId, categoryName, parentId

			FROM         categories

			WHERE     (parentId IS NULL) 

			ORDER BY categoryName
END

Find all Categories where the ParentId is Null, as stated above, this means that category is a Main Category.  Done.

Now, how do we find the SubCategory?

Well, the way this will work is when the Repeater’s row is Databound, the current CategoryId is sent to the DB where we look for any Categories where the ParentId matches the current.  This means that any resulting rows are a child (or sub) to this category and will be displayed.

ALTER PROCEDURE [dbo].[LoadSubCategories] 

		(
			@parentID int
		)

AS
BEGIN

	SET NOCOUNT ON;

			SELECT     categoryId, categoryName, parentId

			FROM         categories

			WHERE     (parentId=@parentID) 

			ORDER BY categoryName
END

 

The Code Behind – Nested Repeaters, bringing it all together

In your default.aspx, drag a new repeater to the form, rename and add some

tags around it.  Then, lets add a new label control in an Item Template, just as in the first example, so it now looks like this.

 

This is a Nested Repeater.

    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="repCategory" runat="server" >
            <ItemTemplate>
                <div>
                    <asp:Label ID="lblCategory" runat="server"></asp:Label>
                      <div>
                        <asp:Repeater ID="repSubCategory" runat="server"  OnItemDataBound="repSubCategory_ItemDatabound">
                            <ItemTemplate>
                                <div style="margin-left:8px;">
                                    <asp:Label ID="lblSubCategory" runat="server"></asp:Label>
                                </div>
                            </ItemTemplate>
                        </asp:Repeater>
                      </div>
                </div>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>

If you look at it closely, the second repeater is *almost* an exact copy of the first, placed inside the first repeater’s Item Template (obviously with the Control names changed).  I’ll get to the differences shortly.

At this point, there’s no code yet to load the content for the second repeater.  Let’s do that now.

In the code behind repCategory_ItemDataBound, we will simply add another call to the Database to databind the Nested Repeater under the lblCategory.text assignment.  In your default.vb, at this code so repCategory_ItemDataBound looks like this.

 

Private Sub repCategory_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles repCategory.ItemDataBound

        If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then

            Dim lblCategory As Label = Nothing
            lblCategory = CType(e.Item.FindControl("lblCategory"), Label)

            lblCategory.Text = e.Item.DataItem("categoryName").ToString

            'Time to load the SubCategories
            Dim repSubCategory As Repeater = Nothing
            repSubCategory = CType(e.Item.FindControl("repSubCategory"), Repeater)

            Dim param(1) As SqlParameter

            param(1) = New SqlParameter("@parentID", SqlDbType.Int)

            'The below is the CategoryId of the current row of the MAIN Categories
            param(1).Value = e.Item.DataItem("categoryId").ToString

            Using reader As SqlClient.SqlDataReader = data_readers.data.ExecuteDataReader("LoadSubCategories", param(1))
                If reader.HasRows Then
                    repSubCategory.DataSource = reader
                    repSubCategory.DataBind()
                End If
            End Using

        End If

End Sub

You’ll notice that again, this is almost a replica of the code for the MainCategory, though we are now sending a parameter to the LoadSubCategories stored Procedure with the id of the Current Main Category.

One last step remains and that is the Databound Event for the SubCategory repeater repSubCategory.

 

Add the below code to your default.vb page

Protected Sub repSubCategory_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)

        Dim lblSubCategory As Label = Nothing
        lblSubCategory = CType(e.Item.FindControl("lblSubCategory"), Label)

        lblSubCategory.Text = e.Item.DataItem("categoryName").ToString

End Sub

What’s happening here?  Ok, so when we added the Repeater as a Nested Repeater, we also added OnItemDataBound=”repSubCategory_ItemDatabound” to the control’s parameters.  This is because a nested Control, in this case the Nested Repeater, won’t fire its own events, so we have to manually tell the repSubcategory control to fire the repSubCategory_ItemDatabound procedure when that row is Databound.

We could have named the above procedure LoadMySubCategories and it would have worked fine, so long as it was so named in both the Control and the Code Behind.

See Below:

<form id="form1" runat="server">
    <div>
        <asp:Repeater ID="repCategory" runat="server" >
            <ItemTemplate>
                <div>
                    <asp:Label ID="lblCategory" runat="server"></asp:Label>
                      <div>
                        <asp:Repeater ID="repSubCategory" runat="server"  OnItemDataBound="LoadMySubCategories">
                            <ItemTemplate>
                                <div style="margin-left:8px;">
                                    <asp:Label ID="lblSubCategory" runat="server"></asp:Label>
                                </div>
                            </ItemTemplate>
                        </asp:Repeater>
                      </div>
                </div>
            </ItemTemplate>
        </asp:Repeater>
    </div>
</form>
Protected Sub LoadMySubCategories (ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)

        Dim lblSubCategory As Label = Nothing
        lblSubCategory = CType(e.Item.FindControl("lblSubCategory"), Label)

        lblSubCategory.Text = e.Item.DataItem("categoryName").ToString

End Sub

Conclusion

At this point, you have a functioning, simple Nested Repeater.  In many cases, you would replace the label with a HyperLink control to allow a user to navigate using the Categories list.  In that case, you would simply amend the code from

            Dim lblCategory As Label = Nothing
            lblCategory = CType(e.Item.FindControl("lblCategory"), Label)

            lblCategory.Text = e.Item.DataItem("categoryName").ToString

to

            Dim lnkCategory As HyperLink = Nothing
            lnkCategory = CType(e.Item.FindControl("lnkCategory"), HyperLink)

            lnkCategory.Text = e.Item.DataItem("categoryName").ToString
            lnkCategory.NavigateUrl = “yourNewURL”

 

In future articles I will address things such as adding buttons or linkButtons in conjunction with the repCategory_ItemCommand.

I sincerely hope these articles have helped to clear things up for someone, I know when I frist started, this was a complete mystery to me.  I’ve attached the SQL script inside the .zip file for convenience.  If you have any further questions or comments, please feel free to comment below.

Happy Coding!

 

 

 

If you enjoyed this post, please consider leaving a comment, or sharing it by Tweeting or using the FaceBook Like button.

You may also Subscribe to this blog and receive notifications of new posts by email using the feature at the top of the page.

Please remember to visit my Sponsors (right column) as it helps me get the bills paid.

Nested Repeaters - A Beginners Tutorial
72.1 KiB
120 Downloads
Details...

Comments

comments

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Visit my Sponsors

Read previous post:
asp.Net Logo
Nested Repeaters, do it clean and simple – A Beginner’s Tutorial – Part 1

Using nested controls in asp.Net can be a little confusing at first and using Nested Repeaters is no different.  In...

Close