Search code examples
c#asp.netlistviewpagination

Can I Number a GroupTemplate or ItemTemplate?


I would like to use a GroupTemplate to separate a list of items into groups. However, I need each Group to be numbered sequentially so I can link to them and implement some JS paging. I'm binding to an IEnumerable

Here's some pseudo code. I would like the output to look like this:

<a href="#group1">Go to Group 1<a>
<a href="#group2">Go to Group 2<a>
<a href="#group3">Go to Group 3<a>

<ul id="group1">
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>
<ul id="group2">
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>
<ul id="group3">
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>

Is this easy to do in a ListView, using GroupTemplate and ItemTemplate?

<asp:ListView ID="lv" runat="server" GroupPlaceholderID="groupPlaceholder">
    <LayoutTemplate>
        <asp:PlaceHolder ID="groupPlaceholder" runat="server"></asp:PlaceHolder>
    </LayoutTemplate>
    <GroupTemplate>
        <ul id="<!-- group-n goes here -->">
            <asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
        </ul>
    </GroupTemplate>
    <ItemTemplate>
        <li>Item</li>
    </ItemTemplate>
</asp:ListView>

I can get the number of groups to do the links at the top from the Datasource and basic math, but how do I get id="groupN" number into the template?


Solution

  • I don't think you can DataBind the id, so I'd probably either use a hidden field, have JQuery count them up, or use the CssClass. You can use Container.DataItemIndex to get your number.

    Edit: By just changing the ul to be runat="server", ASP.NET will generate a unique id for you in it's infamous INamingContainer format. That will include an index as well, though it'll be something like lv_ctrl0_group, and is an implementation detail.

    You could hook a handler to the ul's Init event and append a number to it, making it something like lv_ctrl0_group1. I don't think you can get rid of the prepended INamingContainer stuff very easily, and this would probably break any IPostDataHandler controls.

    <script runat="server">
        void Group_Init(object sender, EventArgs e) {
           ((Control)sender).ID += groupId++.ToString();
        }
        int groupId = 0;
    </script>
    
    <asp:ListView id="lv" runat="server" GroupItemCount="3">
        <LayoutTemplate>
            <asp:PlaceHolder ID="groupPlaceHolder" runat="server" />
        </LayoutTemplate>
        <GroupTemplate>
            <ul id="group" runat="server" oninit="Group_Init">
                <asp:PlaceHolder ID="itemPlaceHolder" runat="server"/>
            </ul>
        </GroupTemplate>
        <ItemTemplate>
            <li>Item</li>
        </ItemTemplate>
    </asp:ListView>