views:

835

answers:

3

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?

+1  A: 

In your aspx file:

<GroupTemplate>
  <ul id='<%# "group"+GroupNumber %>'>
    <asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
  </ul>
</GroupTemplate>

In your code behind (assuming C#):

int _GroupNumber=0;

protected string GroupNumber
{
   get { return (++_GroupNumber).ToString(); }
}
Keltex
Great Simple solution and it would be great if it worked. But the Group Property never gets called from the ListView.
Atømix
Huh. Must not be part of the databinding process. How about <%# "group"+GroupNumber %>?
Keltex
I found out that it doesn't databind the GroupTemplate. Doesn't really work, unfortunately. I am trying to avoid splitting the data into a lists of lists and doing Nested ListViews. I need the IDs.
Atømix
+1  A: 

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>
Mark Brackett
Well, I was thinking of doing it all in jQuery, but it's not so much the count I need. I need a unique ID for each group. Can't use the class, because the links above reference those IDs (for accessibility and in-page links)Container.DataItemIndex is a good idea, though.
Atømix
Atømix
I'm not familiar with the UI Tab Ctrl specifics, but you should be able to use JQuery to dynamically find the id's by looking for UL's (of a certain class or whose id's contain (*=) "group").
Mark Brackett
+1  A: 

The solution from Keltex above would work with a small change; use <%= instead <%#,

<%# wouldnt work because GroupTemplate doesnt support databinding

Manesh Karunakaran