Link to home
Start Free TrialLog in
Avatar of bigmoxy
bigmoxy

asked on

Has anyone created a 3 level nested repeater?

I have a requirement to create a display page with an unknown number of categories and sub-categories. It would be easy creating parent/child repeaters if I knew all of them. The web site is for used cars and trucks. My client wants a breakdown of vehicle manufacturer and model. Some display pages will be by manufacturer (e.g. Ford, Toyota, etc.) but the models are dependent on their inventory. Other display pages are by vehicle type (e.g. pickup truck, conversion van, etc.) and both the manufacturers and models are dependent on their inventory.

For manufacturer pages, how can I create a child repeater for each model where I don't know all of the models?

For the vehicle type pages, how can I create parent/child repeaters where I don't know either the manufacturer or model?

At first I thought I could use arrays to store the unique combinations in my code behind file but I don't know how to reference the arrays in my presentation page (ref: code behind file = mypage.aspx.vb, presentation page = mypage.aspx).

Now I am thinking about a 3 level nested repeater. Has anyone created a 3 level nested repeater?
 
Your help is greatly appreciated!!

Tim
Avatar of Reecio
Reecio

Where are you holding the information for each category and sub-category?
And what are you trying to create?

If its just a menu you might be better off using treeview.
Avatar of bigmoxy

ASKER

No, this is not a menu. This is for the body of a web page. I described the requirement in my original post.
ASKER CERTIFIED SOLUTION
Avatar of Reecio
Reecio

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bigmoxy

ASKER

Thank you! I now have a solid foundation for the 3 level repeater. Here are some examples of what I need to accomplish. My client has a one table Access db that resembles more of an XML file. I need to use that data and convert their current site from static to dynamic.

* http://www.cargovango.com/cubes.htm - ignore the Diesels section, I have separate code for that. Here I need to group the vehicles by make and model.

* http://www.cargovango.com/fordcargo.htm - Here I need to group the vehicles by model.

I don't have the luxury of using multiple tables for the nested repeater. I have to create the repeater from a single table.

Regards,
Tim
I did it, but its a bit messy! Since there is no distinct option when filtering data tables, it makes it increaasingly hard to use a single table with a repeater.
In the end the only way around this situation that I could think of was to dump the unique values in a temp table and bind them to repeaters.

I expect their table will get too big eventually and kill the efficiency of the database, but heres my solution below :)

Should Just have to replace FillTablle with your table (you can delete the function etc) and rename the column names.
    Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim Tab As DataTable = FillTable()
 
        'Create tables for parent & child repeaters to catch unique values
        Dim pTab, cTab As New DataTable
        pTab.Columns.Add("Col1", GetType(String))
        cTab.Columns.Add("Col2", GetType(String))
 
        Dim CatchLast As String
 
        'Fill table for parent repeater
        Tab.DefaultView.Sort = "Col1"
        For Each iRow As DataRow In Tab.Rows
            If Not iRow("Col1") = CatchLast Then
                Dim newRow As DataRow = pTab.NewRow
                newRow("Col1") = iRow("col1")
                pTab.Rows.Add(newRow)
            End If
            CatchLast = iRow("Col1")
        Next
 
        'Create loops to set datasources for repeaters and apply filter to main table for results
        parentRepeater.DataSource = pTab
        parentRepeater.DataBind()
        For Each cItem As RepeaterItem In parentRepeater.Items
 
            'Reset vars
            cTab.Clear()
            CatchLast = ""
 
            'Fill table for child repeater
            Tab.DefaultView.Sort = "Col2"
            For Each iRow As DataRow In Tab.Select("Col1 = '" & CType(cItem.FindControl("Col1"), Label).Text & "'")
                If Not iRow("Col2") = CatchLast Then
                    Dim newRow As DataRow = cTab.NewRow
                    newRow("Col2") = iRow("Col2")
                    cTab.Rows.Add(newRow)
                End If
                CatchLast = iRow("Col2")
            Next
 
            Dim childRep As Repeater = CType(cItem.FindControl("childrepeater"), Repeater)
            childRep.DataSource = cTab
            childRep.DataBind()
            For Each ccItem As RepeaterItem In childRep.Items
                Dim cchildRep As Repeater = CType(ccItem.FindControl("childchildrepeater"), Repeater)
                cchildRep.DataSource = Tab.Select("Col1='" & CType(cItem.FindControl("Col1"), Label).Text & "' and Col2 ='" & CType(ccItem.FindControl("Col2"), Label).Text & "'")
                cchildRep.DataBind()
            Next
        Next
 
    End Sub
 
    Function FillTable() As DataTable
        Dim dt As New DataTable
        Dim nRow As DataRow
 
        dt.Columns.Add("Col1", GetType(String))
        dt.Columns.Add("Col2", GetType(String))
        dt.Columns.Add("Col3", GetType(String))
 
        For i As Integer = 1 To 3
            nRow = dt.NewRow
            With nRow
                .Item("Col1") = "Ford"
                .Item("Col2") = "Van"
                .Item("Col3") = Rnd(100).ToString
            End With
            dt.Rows.Add(nRow)
        Next
 
        For i As Integer = 1 To 3
            nRow = dt.NewRow
            With nRow
                .Item("Col1") = "Ford"
                .Item("Col2") = "Car"
                .Item("Col3") = Rnd(100).ToString
            End With
            dt.Rows.Add(nRow)
        Next
 
        For i As Integer = 1 To 3
            nRow = dt.NewRow
            With nRow
                .Item("Col1") = "Chevy"
                .Item("Col2") = "Van"
                .Item("Col3") = Rnd(100).ToString
            End With
            dt.Rows.Add(nRow)
        Next
 
        For i As Integer = 1 To 3
            nRow = dt.NewRow
            With nRow
                .Item("Col1") = "Chevy"
                .Item("Col2") = "Car"
                .Item("Col3") = Rnd(100).ToString
            End With
            dt.Rows.Add(nRow)
        Next
 
        For i As Integer = 1 To 3
            nRow = dt.NewRow
            With nRow
                .Item("Col1") = "Nissan"
                .Item("Col2") = "Car"
                .Item("Col3") = Rnd(100).ToString
            End With
            dt.Rows.Add(nRow)
        Next
 
        Return dt
 
    End Function
End Class

Open in new window

Avatar of bigmoxy

ASKER

Thank you! I actually figured out how to accomplish this already. The key item for me was having to create unique relationship keys for the VehicleModels and Vehicles tables. Here is my code for a page where I am displaying vehicles by type (e.g. Passenger Vans).

Public Class NestedRepeater

    Inherits System.Web.UI.Page
    Private Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs) Handles Me.Load

        Dim strConnection As String = _
        ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
         "e:\websites\cargovango.com\currentDB\VinMaster_be.mdb;Persist Security Info=False;")

        Dim strDiesel As String = "Diesel"
        Dim strDsl As String = "Dsl"
        Dim strDieselUpper As String = strDiesel.ToUpper()
        Dim strDslUpper As String = strDsl.ToUpper()

        Dim strSQLDiesel As String = "SELECT DISTINCT tfkVehicleMake," & _
            " fld15Model, fld15Year, fld15ExteriorColor, fld15Mileage," & _
            " fld15AskingPrice, fld15StockNum, fld15Status, blnImage1," & _
            " blnImage2, blnImage3, blnImage4, blnImage5" & _
            " FROM tbl15Vehicles" & _
            " WHERE fld15VehicleType LIKE 'Pass%'" & _
            " AND (fld15EngineDescription LIKE '%" & strDieselUpper & "%'" & _
            " OR fld15EngineDescription LIKE '%" & strDslUpper & "%')" & _
            " ORDER BY tfkVehicleMake ASC, fld15Model ASC"
        Dim strSQLMake As String = "SELECT DISTINCT fld15VehicleType," & _
            " tfkVehicleMake " & _
            " FROM tbl15Vehicles" & _
            " WHERE fld15VehicleType LIKE 'Pass%'" & _
            " AND (fld15EngineDescription NOT LIKE '%" & strDieselUpper & "%'" & _
            " AND fld15EngineDescription NOT LIKE '%" & strDslUpper & "%')" & _
            " ORDER BY tfkVehicleMake ASC"
        Dim strSQLModel As String = "SELECT DISTINCT tfkVehicleMake," & _
            " fld15Model" & _
            " FROM tbl15Vehicles" & _
            " WHERE fld15VehicleType LIKE 'Pass%'" & _
            " AND (fld15EngineDescription NOT LIKE '%" & strDieselUpper & "%'" & _
            " AND fld15EngineDescription NOT LIKE '%" & strDslUpper & "%')" & _
            " ORDER BY tfkVehicleMake ASC, fld15Model ASC"
        Dim strSQLVehicle As String = "SELECT DISTINCT tfkVehicleMake," & _
            " fld15Model, fld15Year, fld15ExteriorColor, fld15Mileage," & _
            " fld15AskingPrice, fld15StockNum, fld15Status, blnImage1," & _
            " blnImage2, blnImage3, blnImage4, blnImage5" & _
            " FROM tbl15Vehicles" & _
            " WHERE fld15VehicleType LIKE 'Pass%'" & _
            " AND (fld15EngineDescription NOT LIKE '%" & strDieselUpper & "%'" & _
            " AND fld15EngineDescription NOT LIKE '%" & strDslUpper & "%')" & _
            " ORDER BY tfkVehicleMake ASC, fld15Model ASC"

        Dim conn As New OleDbConnection(strConnection)
        Dim daDiesels As New OleDbDataAdapter(strSQLDiesel, conn)
        Dim daMakes As New OleDbDataAdapter(strSQLMake, conn)
        Dim daModels As New OleDbDataAdapter(strSQLModel, conn)
        Dim daVehicles As New OleDbDataAdapter(strSQLVehicle, conn)

        Dim ds As New DataSet()

        daDiesels.Fill(ds, "VehicleDiesels")
        daMakes.Fill(ds, "VehicleMakes")
        daModels.Fill(ds, "VehicleModels")
        daVehicles.Fill(ds, "Vehicles")

        If ds.Tables("VehicleDiesels").Rows.Count > 0 Then
            modelDieselRepeater.visible = True
            ds.Tables("VehicleDiesels").Columns.Add("fldCameraPhoto", GetType(System.String))
            ds.Tables("VehicleDiesels").Columns.Add("fldVehicleMakeLink", GetType(System.String))
            For Each r As DataRow In ds.Tables("VehicleDiesels").Rows
                If ((r("fld15Status") <> 4 And r("fld15Status") <> 6) And _
                    (r("blnImage1") Or r("blnImage2") Or r("blnImage3") Or _
                        r("blnImage4") Or r("blnImage5"))) Then
                    r("fldCameraPhoto") = "<img src='/images/camera14x15.gif'" & _
                      " width='14' height='15' alt='This vehicle has photos'>"
                Else
                    r("fldCameraPhoto") = "&nbsp;"
                End If
                If (r("fld15Status") = 4 Or r("fld15Status") = 6) Then
                    r("fldVehicleMakeLink") = "<img src='/images/auctionsoldstamp.gif' width='66' height='13' alt='This vehicle is sold'>"
                Else
                    r("fldVehicleMakeLink") = "<a href='/vehicleDetails.aspx?id=" & r("fld15StockNum").ToString.Trim & "' style='text-decoration:underline;'>" & _
                     r("tfkVehicleMake") & "</a>"
                End If
            Next
        Else
            modelDieselRepeater.visible = False
        End If

        ds.Tables("Vehicles").Columns.Add("fldCameraPhoto", GetType(System.String))
        ds.Tables("Vehicles").Columns.Add("fldVehicleMakeLink", GetType(System.String))

        For Each r As DataRow In ds.Tables("Vehicles").Rows
            If ((r("fld15Status") <> 4 And r("fld15Status") <> 6) And _
                (r("blnImage1") Or r("blnImage2") Or r("blnImage3") Or _
                    r("blnImage4") Or r("blnImage5"))) Then
                r("fldCameraPhoto") = "<img src='/images/camera14x15.gif'" & _
                  " width='14' height='15' alt='This vehicle has photos'>"
            Else
                r("fldCameraPhoto") = "&nbsp;"
            End If
            If (r("fld15Status") = 4 Or r("fld15Status") = 6) Then
                r("fldVehicleMakeLink") = "<img src='/images/auctionsoldstamp.gif' width='66' height='13' alt='This vehicle is sold'>"
            Else
                r("fldVehicleMakeLink") = "<a href='/vehicleDetails.aspx?id=" & r("fld15StockNum").ToString.Trim & "' style='text-decoration:underline;'>" & _
                 r("tfkVehicleMake") & "</a>"
            End If
        Next

        ds.Relations.Add("Make_Model", _
            ds.Tables("VehicleMakes").Columns("tfkVehicleMake"), _
            ds.Tables("VehicleModels").Columns("tfkVehicleMake"))
        ds.Relations(0).Nested = True
        Dim dcVehicleModelsKey As DataColumn() = _
            {ds.Tables("VehicleModels").Columns("tfkVehicleMake"), _
            ds.Tables("VehicleModels").Columns("fld15Model")}
        Dim dcVehiclesKey As DataColumn() = _
            {ds.Tables("Vehicles").Columns("tfkVehicleMake"), _
            ds.Tables("Vehicles").Columns("fld15Model")}
        ds.Relations.Add("Model_Vehicle", _
            dcVehicleModelsKey, _
            dcVehiclesKey)
        ds.Relations(1).Nested = True

        parentRepeater.DataSource = ds.Tables("VehicleMakes")
        parentRepeater.DataBind()

    End Sub

    Protected Function GetChildRelation(ByVal dataItem As Object, ByVal relation As String) As DataView

        Dim drv As DataRowView = dataItem
        If Not (drv Is Nothing) Then
            Return drv.CreateChildView(relation)
        Else
            Return Nothing
        End If
    End Function

    Sub GetListURL(ByVal Src As Object, ByVal Args As EventArgs)
        If (URLlist.SelectedIndex > -1 And URLlist.SelectedItem.Value <> "") Then
            Response.Redirect(URLlist.SelectedItem.Value)
        End If
    End Sub

End Class


<div id="pageTitle">Passenger Vans</div>
<table cellpadding="5" cellspacing="0" style="margin:0 0 0 5px;">
<%  If modelDieselRepeater.Visible = True Then%>
    <tr>
        <td colspan="8" class="modelTitle">Diesels</td>
    </tr>
    <tr>
        <th align="center">
            <img src="/images/camera14x15.gif" width="14" height="15"
                alt="This vehicle has photos" />
        </th>
        <th align="center"><b>Make</b></th>
        <th align="center"><b>Model</b></th>
        <th align="center"><b>Year</b></th>
        <th align="center"><b>Color</b></th>
        <th align="center"><b>Mileage</b></th>
        <th align="center"><b>Price</b></th>
        <th align="center"><b>Stock #</b></th>
    </tr>
  <asp:repeater id="modelDieselRepeater" runat="server">
      <HeaderTemplate>
      </HeaderTemplate>
      <ItemTemplate>
                    <tr style="background-color:#FFFFFF">
                         <td align="center"><%#Container.DataItem("fldCameraPhoto")%></td>
                         <td align="center"><%#Container.DataItem("fldVehicleMakeLink")%></td>
                         <td align="center"><%#Container.DataItem("fld15Model")%></td>
                         <td align="center"><%#Container.DataItem("fld15Year")%></td>
                         <td align="center"><%#Container.DataItem("fld15ExteriorColor")%></td>
                         <td align="center"><%#Container.DataItem("fld15Mileage")%></td>
                         <td align="center"><%#Container.DataItem("fld15AskingPrice")%></td>
                         <td align="center"><%#Container.DataItem("fld15StockNum")%></td>
                    </tr>
      </ItemTemplate>
  </asp:repeater>
<% End If%>
<asp:repeater Runat="server" ID="parentRepeater"
              EnableViewState="false">
    <ItemTemplate>
    <tr>
    <th colspan="8" class="makeTitle"><%#DataBinder.Eval(Container.DataItem, "tfkVehicleMake")%></th>
    </tr>
    <asp:repeater ID="Repeater1" runat="server" EnableViewState="false"
            DataSource='<%# GetChildRelation(Container.DataItem, "Make_Model")%>'>
    <ItemTemplate>
    <tr>
    <th colspan="8" class="modelTitle"><%#DataBinder.Eval(Container.DataItem, "fld15Model")%></th>
    </tr>
    <headertemplate>
    <tr>
        <th align="center">
            <img src="/images/camera14x15.gif" width="14" height="15"
                alt="This vehicle has photos" />
        </th>
        <th align="center"><b>Make</b></th>
        <th align="center"><b>Model</b></th>
        <th align="center"><b>Year</b></th>
        <th align="center"><b>Color</b></th>
        <th align="center"><b>Mileage</b></th>
        <th align="center"><b>Price</b></th>
        <th align="center"><b>Stock #</b></th>
    </tr>
    </headertemplate>
    <asp:repeater ID="Repeater1" runat="server" EnableViewState="false"
            DataSource='<%# GetChildRelation(Container.DataItem, "Model_Vehicle")%>'>
    <ItemTemplate>
                    <tr style="background-color:#FFFFFF">
                         <td align="center"><%#Container.DataItem("fldCameraPhoto")%></td>
                         <td align="center"><%#Container.DataItem("fldVehicleMakeLink")%></td>
                         <td align="center"><%#Container.DataItem("fld15Model")%></td>
                         <td align="center"><%#Container.DataItem("fld15Year")%></td>
                         <td align="center"><%#Container.DataItem("fld15ExteriorColor")%></td>
                         <td align="center"><%#Container.DataItem("fld15Mileage")%></td>
                         <td align="center"><%#Container.DataItem("fld15AskingPrice")%></td>
                         <td align="center"><%#Container.DataItem("fld15StockNum")%></td>
                    </tr>
    </ItemTemplate>
    </asp:repeater>
    </ItemTemplate>
    </asp:repeater>
    </ItemTemplate>
</asp:repeater>
</table>