title: ASP.Net Nested Repeater Logic Hell
body: <p>Looking for help with a tripple nested repeater logic issue I have.</p>
  
  <p><strong>Background</strong><br>
  I am building a timetable system for booking rooms and resources pulling data from a SQL Server database.</p>
  
  <p><strong>Table Structure</strong>  </p>
  
  <pre><code>Table 1 - tblrooms  
  room_id (INT) PK  
  room_name (varchar(50))  
  room_resource (INT)  
  
  Table 2 - tblperiods  
  period_id (INT) PK  
  period_time_start (DATETIME)  
  period_time_end (DATETIME)  
  period_name (nvarchar(50))  
  
  Table 3 - tblbookings  
  booking_id (INT) PK  
  period_id (INT)  
  room_id (INT)  
  booking_status (INT)  
  booking_date (DATETIME)  
  booking_subject (nvarchar(50))
  </code></pre>
  
  <p>Problem
  I have for the most part got the repeaters pulling the data out as required however only the first column is ever populated and I am really struggling to work out how to pull the booking data out and build the timetable as required. <strong>(please see attached screenshot of what I have already got working)</strong></p>
  
  <p><strong>ASPX Page Code</strong></p>
  
  <pre><code>&lt;asp:Repeater ID="drPeriods" runat="server" OnItemDataBound="drPeriods_OnItemDataBound"&gt;
  
          &lt;HeaderTemplate&gt;
          &lt;table class="table table-striped table-bordered table-condensed"&gt;
              &lt;tr&gt;
                  &lt;th style="width:16.66%"&gt;&lt;asp:Label ID="lblResourceHeader" runat="server" /&gt;&lt;/th&gt;
          &lt;/HeaderTemplate&gt;
  
           &lt;ItemTemplate&gt;
  
                  &lt;th style="width:16.66%"&gt;&lt;asp:Label ID="lblPeriod" runat="server" Text='&lt;%# Eval("period_name") %&gt;' /&gt; - &lt;asp:Label ID="lblPeriodStart" runat="server" Text='&lt;%# Eval("period_time_start") %&gt;' /&gt; to &lt;asp:Label ID="lblPeriodEnd" runat="server" Text='&lt;%# Eval("period_time_end") %&gt;' /&gt;&lt;/th&gt;
  
           &lt;/ItemTemplate&gt;
  
           &lt;FooterTemplate&gt;
               &lt;/tr&gt; 
  
               &lt;asp:Repeater ID="drResources" runat="server" OnItemDataBound="drResources_OnItemDataBound"&gt;
  
                      &lt;ItemTemplate&gt;
  
                      &lt;tr&gt;
                          &lt;td height="50"&gt;
                              &lt;asp:Label ID="lblResource" runat="server" Text='&lt;%# Eval("room_name") %&gt;' /&gt;
                              &lt;br /&gt;&lt;asp:Label ID="lblResourceDetails" runat="server" /&gt;
                          &lt;/td&gt;
                          &lt;asp:Label ID="lblFreeBooking" runat="server" Visible="false" /&gt;
  
                          &lt;asp:Repeater ID="drBookings" runat="server" OnItemDataBound="drBookings_OnItemDataBound"&gt;
  
                              &lt;ItemTemplate&gt;
  
                                  &lt;td height="50"&gt;
                                      &lt;asp:Label ID="lblCellContent" runat="server" /&gt;
                                  &lt;/td&gt;
  
                              &lt;/ItemTemplate&gt;
  
                          &lt;/asp:Repeater&gt;
  
                      &lt;/tr&gt;
  
                      &lt;/ItemTemplate&gt;
  
                  &lt;/asp:Repeater&gt;
  
              &lt;/table&gt;
  
           &lt;/FooterTemplate&gt;
  
       &lt;/asp:Repeater&gt;
  </code></pre>
  
  <p><strong>Code Behind</strong></p>
  
  <pre><code>Namespace Staff
  
  Public Class Rb
      Inherits System.Web.UI.Page
      Private _periodId As Integer
  
  
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  
          If Not IsPostBack Then
  
              txtDate.Text = Request.QueryString("d")
  
              'check for weekend dates, show message if it is.
              Dim iWeekday As Integer = Weekday(Request.QueryString("d"))
  
              If iWeekday = 1 Or iWeekday = 7 Then
  
                  lblMsg.Text = "&lt;div class='alert alert-info alert-block'&gt;&lt;h4 class='alert-heading'&gt;&lt;i class='icon-warning-sign'&gt;&lt;/i&gt;&amp;nbsp;It's the weekend.&lt;/h4&gt;&lt;p&gt;The date you have choosen is a weekend, resources cannot be booked on weekends.&lt;/p&gt;&lt;/div&gt;"
                  lblMsg.Visible = True
                  drPeriods.Visible = False
  
              Else
  
                  Dim objConnection As SqlConnection
                  Dim objCommand As SqlCommand
                  Dim objDataReader As SqlDataReader
  
                  objConnection = New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("OPSDConnectionString").ConnectionString)
  
                  'Get Periods
                  objCommand = New SqlCommand("SELECT period_id, CONVERT(char(5), period_time_start, 108) AS period_time_start, CONVERT(char(5), period_time_end, 108) AS period_time_end, period_name FROM tblrb_periods", objConnection)
  
                  Try
                      objConnection.Open()
                      objDataReader = objCommand.ExecuteReader()
  
                      If objDataReader.HasRows Then
  
                          drPeriods.DataSource = objDataReader
                          drPeriods.DataBind()
                          objDataReader.Close()
  
                      Else
  
                          drPeriods.Visible = False
                          lblMsg.Text = "&lt;div class='alert alert-error alert-block'&gt;&lt;h4 class='alert-heading'&gt;&lt;i class='icon-warning-sign'&gt;&lt;/i&gt;&amp;nbsp;Error!&lt;/h4&gt;&lt;p&gt;Periods have not yet been setup, please set these up by selecting the periods tab above, if you cannot see this tab please ask the helpdesk administrator to set these up for you.&lt;/p&gt;&lt;/div&gt;"
                          lblMsg.Visible = True
                          objDataReader.Close()
  
                      End If
  
                  Catch ex As Exception
  
                      'Inform of the error
                      Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
  
                  Finally
                      objCommand.Dispose()
                      objConnection.Close()
                      objConnection.Dispose()
  
                  End Try
  
              End If
  
          End If
  
      End Sub
  
      Protected Sub drPeriods_OnItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles drPeriods.ItemDataBound
  
          If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
  
              _periodId = e.Item.DataItem("period_id")
  
          End If
  
          If e.Item.ItemType = ListItemType.Header Then
  
              Dim lblResourceHeader As Label = drPeriods.Controls(0).Controls(0).FindControl("lblResourceHeader")
              Dim layoutView As Integer = Request.QueryString("v")
              Select Case layoutView
                  Case 1 ' Rooms
                      lblResourceHeader.Text = "Rooms"
                  Case 2 ' Resources
                      lblResourceHeader.Text = "Resources"
                  Case 3 ' Both
                      lblResourceHeader.Text = "Rooms &amp;amp; Resources"
                  Case Else
                      lblResourceHeader.Text = "Rooms &amp;amp; Resources"
              End Select
  
          End If
  
          If e.Item.ItemType = ListItemType.Footer Then
  
              Dim objConnection As SqlConnection
              Dim objCommand As SqlCommand
              Dim objDataReader As SqlDataReader
  
              'find repeater in the footer of drPeriods (repeater)
              Dim drResources As Repeater = drPeriods.Controls(drPeriods.Controls.Count - 1).Controls(0).FindControl("drResources")
              Dim layoutView As Integer = Request.QueryString("v")
  
              'Get Rooms
              objConnection = New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("OPSDConnectionString").ConnectionString)
  
              Select Case layoutView
                  Case 1 ' Rooms
                      objCommand = New SqlCommand("SELECT * FROM tblrb_rooms WHERE room_resource = 1 ORDER BY room_name", objConnection)
                  Case 2 ' Resources
                      objCommand = New SqlCommand("SELECT * FROM tblrb_rooms WHERE room_resource = 2 ORDER BY room_name", objConnection)
                  Case 3 ' Both
                      objCommand = New SqlCommand("SELECT * FROM tblrb_rooms ORDER BY room_name", objConnection)
                  Case Else
                      objCommand = New SqlCommand("SELECT * FROM tblrb_rooms ORDER BY room_name", objConnection)
              End Select
  
              Try
                  objConnection.Open()
                  objDataReader = objCommand.ExecuteReader()
  
                  drResources.DataSource = objDataReader
                  drResources.DataBind()
                  objDataReader.Close()
  
              Catch ex As Exception
  
                  'Inform of the error
                  Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
  
              Finally
                  objCommand.Dispose()
                  objConnection.Close()
                  objConnection.Dispose()
  
              End Try
  
          End If
  
      End Sub
  
      Protected Sub drResources_OnItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs)
  
          If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
  
              Dim lblResourceDetails As Label = e.Item.FindControl("lblResourceDetails")
              If e.Item.DataItem("room_resource") &lt;&gt; 2 Then
                  lblResourceDetails.Text = "[ &lt;a href='#' class='withajaxpopover' title='Room Details' data-load='resourceManagerViewDetails.aspx?id=" &amp; e.Item.DataItem("room_id") &amp; "'&gt;View Room Details&lt;/a&gt; ]"
              End If
  
              Dim objConnection As SqlConnection
              Dim objCommand As SqlCommand
              Dim objDataReader As SqlDataReader
              Dim drBookings As Repeater = e.Item.FindControl("drBookings")
              Dim lblFreeBooking As Label = e.Item.FindControl("lblFreeBooking")
  
              'Get Bookings
              objConnection = New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("OPSDConnectionString").ConnectionString)
              objCommand = New SqlCommand("SELECT tblrb_bookings.booking_status, tblrb_bookings.booking_subject, tblrb_bookings.booking_notes FROM tblrb_bookings WHERE (tblrb_bookings.room_id = @room_id) AND (tblrb_bookings.booking_date = @booking_date) AND (tblrb_bookings.period_id = @period_id)", objConnection)
  
              objCommand.Parameters.Add("@room_id", SqlDbType.Int, 10).Value = e.Item.DataItem("room_id")
              objCommand.Parameters.Add("@period_id", SqlDbType.Int, 10).Value = _periodId
              objCommand.Parameters.Add("@booking_date", SqlDbType.DateTime).Value = Request.QueryString("d")
  
              Try
                  objConnection.Open()
                  objDataReader = objCommand.ExecuteReader()
  
                  If objDataReader.HasRows Then
  
                      drBookings.DataSource = objDataReader
                      drBookings.DataBind()
                      objDataReader.Close()
  
                  Else
  
                      'free period
                      lblFreeBooking.Text = "&lt;td height='50'&gt;&lt;div class='alert alert-block alert-success'&gt;&lt;h4 class='alert-heading'&gt;&lt;i class='icon-ok'&gt;&lt;/i&gt;&amp;nbsp;Free.&lt;/h4&gt;&lt;p&gt;&lt;a href='#'&gt;Click here to book this resource.&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;"
                      lblFreeBooking.Visible = True
  
                  End If
  
              Catch ex As Exception
  
                  'Inform of the error
                  Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
  
              Finally
                  objCommand.Dispose()
                  objConnection.Close()
                  objConnection.Dispose()
  
              End Try
  
          End If
  
      End Sub
  
      Protected Sub drBookings_OnItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs)
  
          Dim lblCellContent As Label = e.Item.FindControl("lblCellContent")
  
          Select Case e.Item.DataItem("booking_status")
              Case 1
                  'timetabled
                  lblCellContent.Text = "&lt;div class='alert alert-block alert-error'&gt;&lt;h4 class='alert-heading'&gt;&lt;i class='icon-warning-sign'&gt;&lt;/i&gt;&amp;nbsp;Timetabled.&lt;/h4&gt;&lt;p&gt;" &amp; e.Item.DataItem("booking_subject") &amp; "&lt;/p&gt;&lt;/div&gt;"
  
              Case 2
                  'user booked
                  lblCellContent.Text = "&lt;div class='alert alert-block'&gt;&lt;h4 class='alert-heading'&gt;&lt;i class='icon-warning-sign'&gt;&lt;/i&gt;&amp;nbsp;Booked.&lt;/h4&gt;&lt;p&gt;" &amp; e.Item.DataItem("booking_subject") &amp; ".&lt;/p&gt;&lt;/div&gt;"
  
          End Select
  
      End Sub
  
  
      Protected Sub btnDateSelect_Click(sender As Object, e As System.EventArgs) Handles btnDateSelect.Click
  
          'quick reload of page
          Response.Redirect("resourceManager.aspx?v=" &amp; Request.QueryString("v") &amp; "&amp;d=" &amp; txtDate.Text)
  
      End Sub
  
  End Class End Namespace
  </code></pre>
  
  <p>Can anyone help with how I can get the required layout so that when the timetable is built the rooms and periods contain the correct booking data for each cell in thier corresponding columns.</p>
  
  <p>Thanks in advance for any pointers you can provide, having spent 3 days on this I could do with a fresh pair of eyes :-)</p>
  
  <p>Regards,</p>
  
  <p>Ozzie</p>
  
  <p><img src="https://i.stack.imgur.com/GmOVw.png" alt="Repeater Data Issue"></p>