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.

ckarbass
  • 3,539
  • 7
  • 31
  • 43
  • 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. – Dhaust Feb 19 '09 at 07:11
  • 1
    Yup, just clarifying the question – ckarbass Feb 19 '09 at 17:25

4 Answers4

23

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>
Nick
  • 5,498
  • 9
  • 50
  • 72
  • 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 Feb 18 '09 at 20:56
  • 5
    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. – Michiel van Oosterhout May 20 '09 at 20:33
  • @michielvoo - I thought that was the case, thanks for the explanation – Nick May 20 '09 at 21:16
  • 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? – chourn solidet Jul 13 '17 at 06:53
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>
Steve T
  • 7,469
  • 6
  • 41
  • 64
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;
John Sheehan
  • 74,152
  • 28
  • 154
  • 191
cbp
  • 23,600
  • 27
  • 118
  • 194
  • Yep, keeping the markup on the page is a good call Jorge. Probably more readable than my version too ;) – Dhaust Feb 18 '09 at 06:52
  • 1
    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 tags that are generated with the label controls. – Dan Appleyard Feb 18 '09 at 15:32
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

Dhaust
  • 5,306
  • 8
  • 50
  • 73