ASP.NET Repeater Template, Conditional Code for every Nth element
Asked Answered
K

4

13

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.

Kisung answered 18/2, 2009 at 6:14 Comment(2)
You can achieve that using the concepts shown below, you just need to tweak it to suit your purposes. StackOverflow users aren't here to write 'teh codez' for you, we're here to help each other learn. Show us the code you've written/tried and we can help you sort it.Nightjar
Yup, just clarifying the questionKisung
B
24

This should work for you, with no need for anything in the code behind (other than binding the repeater..):

<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>
Betatron answered 18/2, 2009 at 18:37 Comment(4)
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)?Betatron
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.Xiphoid
@michielvoo - I thought that was the case, thanks for the explanationBetatron
How can the ID of each image become unique ??? actually, I want ID of image like image1 , image2, image3 . . . by using itemIndex. But ItemIndex is not allowed to be used in asp tag (runat="server"). Can anyone help?Hoodoo
K
10

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>
Kowalewski answered 14/5, 2009 at 18:24 Comment(0)
T
3

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;
Tunstall answered 18/2, 2009 at 6:37 Comment(2)
Yep, keeping the markup on the page is a good call Jorge. Probably more readable than my version too ;)Nightjar
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.Loser
N
2

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

Nightjar answered 18/2, 2009 at 6:26 Comment(4)
Stop the .NET insanity! In php this would be a simple condition within a foreach in the template. Anyway, +1 for the solution.Brianna
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 ; )Nightjar
The smarter way to do this in .NET is to switch to ASP.NET MVCCryo
The smarter way is to use ListViewKowalewski

© 2022 - 2024 — McMap. All rights reserved.