views:

5214

answers:

5

I'm using an asp.net repeater to create a bunch of images. The image markup is all the same so the standard <ItemTemplate> is fine.

However, I want to wrap K images in a div. Lets say I bind 25+ images to the repeater and I want 5 images per div. How do I go about conditionally creating the start and close tags for the div?

Is this a case better suited for a for loop.

+2  A: 

Add two empty label controls into your Repeaters ItemTemplate where you'd want your div tags to be.

Then add an ItemDataBound event to the Repeater.

Then add this code into the ItemDataBound event:

    Protected Sub Repeater1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
 If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then
  If e.Item.ItemIndex Mod 5 = 0 Then
   Dim lblDivStart As Label = CType(e.Item.FindControl("lblDivStart"), Label)
   Dim lblDivEnd As Label = CType(e.Item.FindControl("lblDivEnd"), Label)
   lblDivStart.text = "<div>"
   lblDivEnd.text = "</div>"
  End If
 End If
End Sub

Note - This will need some tweaking to handle the first div and you may need to do something like If (e.Item.ItemIndex + 1) Mod 5 = 0 to get the divs to show up exactly where you want them.

For more info:
DataListItem.ItemIndex Property
DataList.ItemDataBound Event

David HAust
Stop the .NET insanity! In php this would be a simple condition within a foreach in the template. Anyway, +1 for the solution.
rick
HaHa. Fair call Rick. I'm sure there is a smarter way to do this in .NET, I'm just not smart enough to know it ; )
David HAust
The smarter way to do this in .NET is to switch to ASP.NET MVC
John Sheehan
The smarter way is to use ListView
Steve Tranby
+2  A: 

If you want to keep your markup on the ASPX page you could also try this variation on David's method:

On the aspx page:

<ItemTemplate>
<asp:Literal runat="server" ID="divStart" Text="<div>" />
<asp:Image ....>
<asp:Literal runat="server" ID="divEnd" Text="</div>" />
</ItemTemplate>

In the ItemDataBound event in the codebehind:

e.Item.FindControl("divStart").Visible
    = e.Item.FindControl("divEnd").Visible 
    = e.Item.ItemIndex % 5 == 0;
cbp
Yep, keeping the markup on the page is a good call Jorge. Probably more readable than my version too ;)
David HAust
Good use of the literal tags. It seems too many people use labels to write markup on the page, when the literal control does the same, but without the <span> tags that are generated with the label controls.
Dan Appleyard
+8  A: 

This should work for you, with no need for anything in the code behind:

<asp:Repeater ID="repImages" runat="server">
<HeaderTemplate><div></HeaderTemplate>

<ItemTemplate>
<%# (Container.ItemIndex != 0 && Container.ItemIndex % 5 == 0) ? @"</div><div>" : string.Empty %>
<asp:Image ID="imgGallery" runat="server" ImageUrl='<%# /* your code  here */ %>' />
</ItemTemplate>

<FooterTemplate></div></FooterTemplate>
</asp:Repeater>
Nick
Anyone know how I can use a regular 'if' statement in my answer instead of the ternary operator (to lose the empty string option at the end)?
Nick
Not possible, the if statement is not an expression (doesn't evaluate to a value), so it can't be used in data binding syntax.
michielvoo
@michielvoo - I thought that was the case, thanks for the explanation
Nick
+5  A: 

Here is where Asp.Net WebForms can give you incredible RAD efficiency. You can use the new ListView control, and set the number of items per "group", which will allow you to setup the HTML that surrounds a group, as well as each individual item. This way you can surround the group with the conditional tags.

<asp:ListView ID="ListView1" runat="server" DataKeyNames="id" DataSourceID="LinqDataSource1" GroupItemCount="3">
<LayoutTemplate>
    <div id="layout">
        <asp:PlaceHolder ID="groupPlaceholder" runat="server"></asp:PlaceHolder>
    </div>
</LayoutTemplate>
<GroupTemplate>
    <div class="group">
        <asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
    </div>
</GroupTemplate>
<EmptyDataTemplate>
    <span>No data was returned.</span>
</EmptyDataTemplate>
<ItemTemplate>
    <div class="item">
        <img alt='<%# Eval("title") %>' title='<%# Eval("title") %>'
            src='<%# Eval("filename","photos/{0}") %>' />
    </div>
</ItemTemplate>
</asp:ListView>
Steve Tranby
A: 

ok i have tried to get this to work but am just not having any luck. I am very new to asp.net so if anyone could help me and show me the code to do this i would be soooo thankful!

This is my code

<script runat="server">   
    Private sConn As String = ConfigurationManager.ConnectionStrings("SiteConnectionString").ConnectionString.ToString()
    Private oConn As New SqlConnection(sConn)

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        If Not IsPostBack Then
            SqlDataSource1.ConnectionString = sConn
            'Shows upcoming events and recurring events
            SqlDataSource1.SelectCommand = "SELECT * FROM calendar WHERE " & _
                "end_time>getdate() AND page_id=" & Me.ModuleData & "ORDER BY start_time asc"
      'Shows upcoming events and NOT recurring events
            'SqlDataSource1.SelectCommand = "SELECT * FROM calendar WHERE is_rec=0 AND " & _
            '    "start_time>getdate() AND page_id=" & Me.ModuleData & " ORDER BY start_time desc"
            'Shows recurring events and NOT upcoming events
            'SqlDataSource1.SelectCommand = "SELECT * FROM calendar WHERE is_rec=1 AND " & _
            '    "start_time>getdate() AND page_id=" & Me.ModuleData & " ORDER BY start_time desc"
      'SqlDataSource1.SelectParameters.Add("root_id", SqlDbType.Int)
            'SqlDataSource1.SelectParameters(0).DefaultValue = Me.RootID
            dlPagesWithin.DataSourceID = "SqlDataSource1"
            dlPagesWithin.DataBind()

      MyLabel.Text = System.DateTime.Now.ToString()
      dlPagesWithin.DataBind()



            If dlPagesWithin.Items.Count = 0 Then
                boxNewsList.Style.Add("display", "none")

            End If
        End If

        Dim oContent As Content = New Content
        Dim dt As DataTable
        dt = oContent.GetPage(Me.ModuleData, True)
        If dt.Rows.Count > 0 Then
            litTitle.Text = dt.Rows(0).Item(1).ToString
            lnkMore.NavigateUrl = "~/" & dt.Rows(0).Item(3).ToString
        Else
            lnkMore.Visible = False
        End If
        oContent = Nothing

        Dim cLiteral As New LiteralControl
        cLiteral = New LiteralControl("<" & "script language=""javascript"" src=""systems/nlsscroller/nlsscroller.js"" type=""text/javascript""></" & "script>")
        Page.Master.Page.Header.Controls.Add(cLiteral)

        cLiteral = New LiteralControl("<script language=""javascript"" type=""text/javascript""> var n = new NlsScroller(""scroll" & scrContents.ClientID & """); var isIE=(window.navigator.appName==""Microsoft Internet Explorer""); n.setContents(NlsGetElementById(""" & scrContents.ClientID & """).innerHTML); n.scrollerWidth=""100%""; n.scrollerHeight=175; n.showToolbar=false; n.setEffect(new NlsEffContinuous(""direction=up,speed=" & StartStopNLS & ",step=1,delay=0"")); n.render(); n.start(); </" & "script>")
        divHelp.Controls.Add(cLiteral)
    End Sub



    Protected Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) 
    Label1.Text = "Grid Refreshed at: " + DateTime.Now.ToLongTimeString()
    End Sub





    Function ShowURL(ByVal sURL As String) As String
        If sURL = "" Then
            Return ""
        Else
            Return "<a href=""" & sURL & """>" & GetLocalResourceObject("More") & "</a><br />"
        End If
    End Function

    Protected Function ShowEventDate(ByVal dtStart As Date, ByVal dtEnd As Date) As String
        If dtStart = dtEnd Then
            Return FormatDateTime(dtStart, DateFormat.LongTime)
        Else
            Return FormatDateTime(dtStart, DateFormat.LongTime) & " - " & FormatDateTime(dtEnd, DateFormat.LongTime)
            'If dtStart.Month = dtEnd.Month And dtStart.Year = dtEnd.Year Then
            '    Return dtStart.Day & " - " & dtEnd.Day & " " & MonthName(dtStart.Month) & " " & dtStart.Year
            'Else
            '    Return FormatDateTime(dtStart, DateFormat.LongDate) & " - " & FormatDateTime(dtEnd, DateFormat.LongDate)
            'End If
        End If
    End Function

    'BEGIN Function to not scroll if less than 4 events listed
     Function StartStopNLS() As String
       If dlPagesWithin.Items.Count > 4 Then
       Return "50"
      Else
       Return "0"
      End If
     End Function
    'END Function to not scroll if less than 4 events listed

'    protected System.Timers.Timer _timer;
'    protected void Page_Init(object sender, EventArgs e)
'    {
'      'initialize the time control
'      _timer = new System.Timers.Timer(5000);
'    
'      'subscribe to the Elapsed event
'      _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
'    }
'    
'    protected void Page_Load(object sender, EventArgs e)
'    {
'       _timer.Start();
'    }
'    
'    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
'    {
'       ' Do whatever you want to do on each tick of the <strong class="highlight">timer</strong>
'         Label1.Text = "Grid Refreshed at: " + DateTime.Now.ToLongTimeString()
'    }


</script>

And this is the html or list template code

<asp:SqlDataSource ID="SqlDataSource1" runat="server" >
</asp:SqlDataSource>

<!--    <asp:Label ID="Label2" runat="server" Text="This is Time, When The Full Page Load :" Font-Bold="true"></asp:Label>&nbsp;
    <asp:Label ID="MyLabel" runat="server"></asp:Label><br /><br /> 

    <asp:Label ID="Label3" runat="server" Text="This is The Time when Only Data Grid will Referesh :" Font-Bold="true"></asp:Label>&nbsp;
    <asp:Label ID="Label1" runat="server" Text="Grid not refreshed yet."></asp:Label><br />
    <asp:Label ID="Label4" runat="server" Text="(Grid Will Referesh after Every 30 Sec)" Font-Bold="true"></asp:Label>&nbsp;
    <br /><br />
-->
<table cellpadding="0" cellspacing="0" class="scrollNewsList" id="boxNewsList" runat=server>
<tr>
    <td class="scrollHeaderNewsList">
        <asp:Literal ID="litTitle" runat="server" Visible="false"></asp:Literal>    
    </td>
</tr>
<tr>
    <td class="scrollContentNewsList">
    <div id="scrContents" style="display:none;" runat="server">
        <asp:Repeater ID="dlPagesWithin" runat="server">
        <ItemTemplate>
            <div class="EventItem"> 
            <table width="100%" border="0" cellspacing="0" cellpadding="5">
              <tr>
                <td width="50%"><b><%#Eval("subject")%></b></td>
                <td width="23%"><div><%#Eval("location")%></div></td>
                <td align="right" width="27%"><div class="EventTime"><%#ShowEventDate(CDate(Eval("start_time")), CDate(Eval("end_time")))%></div>
                <%#ShowURL(Eval("url", ""))%>
                </td>
              </tr>
            </table>
            </div>
        </ItemTemplate>        
        </asp:Repeater>

    </div>
    <div id="divHelp" runat="server"></div>
    </td>
</tr>
<tr>
    <td class="scrollFooterNewsList">

        <asp:HyperLink ID="lnkMore" meta:resourcekey="lnkMore" runat="server" Visible="false">More</asp:HyperLink>
    </td>
</tr>
</table>
Aaron
This should be posted as a separate question.
Bill the Lizard