Formatting an asp:DataPager to show in ul li

Chris picture Chris · Nov 15, 2012 · Viewed 13.8k times · Source

I am building a website using the Twitter Bootstrap and ASP.Net C# Webforms. I have a ListView on my page with a DataPager bound to it, but I need to change the way .Net renders the HTML of the DataPager.

Currently, all pager items are displaying like this:

<div class="clearfix pagination pagination-centered"> <span id="cpBody_dpListing"> <a class="aspNetDisabled">First</a>&nbsp;<span>1</span>&nbsp; <a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl02$ctl01','')">2</a>&nbsp; <a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl03$ctl00','')">Last</a>&nbsp; </span> </div>

however I need to wrap all my items in an unordered list rather than span and a tags. My current mark-up looks like this:

<div class="clearfix pagination pagination-centered">
<asp:DataPager ID="dpListing" runat="server" PagedControlID="lvListing" PageSize="10" OnPreRender="dpListing_PreRender">
    <Fields>
        <asp:TemplatePagerField>
            <PagerTemplate>
                <asp:BulletedList ID="listPages" runat="server" DisplayMode="LinkButton" OnClick="listPages_Click"></asp:BulletedList>
            </PagerTemplate>
        </asp:TemplatePagerField>
        <asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="true" ShowNextPageButton="false" ShowPreviousPageButton="false" />
        <asp:NumericPagerField PreviousPageText="&lt; Prev 10" NextPageText="Next 10 &gt;" ButtonCount="10" />
        <asp:NextPreviousPagerField ButtonType="Link" ShowLastPageButton="true" ShowNextPageButton="false" ShowPreviousPageButton="false" />
    </Fields>
</asp:DataPager>

I somehow need to override the NextPreviousPagerField and NumericPagerField so they output <li> tags rather than <span> and <a>.

Answer

Richard Deeming picture Richard Deeming · Nov 15, 2012

The DataPager doesn't support this out of the box, so you're going to need a custom control. Fortunately, it's quite east to implement!

For each DataPagerField, the DataPager adds a DataPagerFieldItem control to its own control collection, and then tells the field to create its controls within that item. The built-in fields will add non-breaking spaces between the buttons (unless you set the RenderNonBreakingSpacesBetweenControls property to false), but they're quite easy to identify and suppress.

This control will still render the <a> tags for the enabled buttons and the <span> tag for the current page number, but should be close to what you need:

public class UnorderedListDataPager : DataPager
{
   protected override HtmlTextWriterTag TagKey 
   {
      get { return HtmlTextWriterTag.Ul; }
   }

   protected override void RenderContents(HtmlTextWriter writer)
   {
      if (HasControls())
      {
         foreach (Control child in Controls)
         {
            var item = child as DataPagerFieldItem;
            if (item == null || !item.HasControls())
            {
                child.RenderControl(writer);
                continue;
            }

            foreach (Control button in item.Controls)
            {
               var space = button as LiteralControl;
               if (space != null && space.Text == "&nbsp;") continue;

               writer.RenderBeginTag(HtmlTextWriterTag.Li);
               button.RenderControl(writer);
               writer.RenderEndTag();
            }
         }
      }
   }
}

HTML output:

<ul id="dpListing">
   <li><a class="aspNetDisabled">First</a></li>
   <li><span>1</span></li>
   <li><a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl02$ctl01','')">2</a></li>
   <li><a href="javascript:__doPostBack('ctl00$cpBody$dpListing$ctl03$ctl00','')">Last</a></li>
</ul>