I've want to shy away from using the term 'post' with this entry - but Dave Jeavons' blog entry inspired by to 'throw' up my version of a custom paging control (I have been meaning to post it up - honest Dave) - but with a twist...
Working on certain quasi-public sector web projects, issues such as accesibility are always bounded about by individuals who simply haven't got the first inclination about what they mean OR the implications of implementing such 'guidelines', e.g. Section 508 for the States, the UK has a similar one, W3C, etc. When I initially checked out the paging and the samples / approaches available - I was somewhat disappointed that all examples used linkbuttons. Sure - they are cool to use, they make coding easier - just drag-n-drop, double click for the code, typey-typey and back to the wife and beer.
The problem was that they were not accessible (at least, certainly not to W3C standard Level 2 (or Double AA if you will). Now don't get me wrong - I don't live for standard and guidelines that restrict development and design practice, but dropping statements such as Level 2 W3C compliance into discussions with other organisations = big kudos points especially as this is certainly one of the de-riguer subjects that I'm certainly aware of.
So - I came up with the following, a paging control (Note: WebControl as opposed to a UserControl) that can be added to an existing or new WebControl library, built, referenced in your project and dragged and dropped on form. It strictly uses the querystring parameters to pass appropriate page numbers and alike, and thus is compliant with Level 2 W3C.
Disclaimer: This is my personal development code and as you can imagine has been improved for its commercial implementation - therefore, test it and amend as necessary kids! The webcontrol code is below...
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.Design
Imports System.Text
<Serializable(), ToolboxData("<{0}:PagingControl runat=server></{0}:PagingControl>")> Public Class PagingControl
Inherits System.Web.UI.WebControls.WebControl
#Region "Private"
Private _PageCount As Integer
Private _LastPage As Boolean
Private _FirstPage As Boolean
Private _CurrentIndex As Integer
Private _PageSize As Integer
Private _TotalRecords As Integer
Private _BaseURL As String
#End Region
#Region "Properties"
<Category("Paging"), DefaultValue("0"), Description("Base URL of the current page, e.g. Request.URL.AbsolutePath?")> _
Public Property BaseURL() As String
Get
Return _BaseURL
End Get
Set(ByVal Value As String)
_BaseURL = Value
End Set
End Property
<Category("Paging"), DefaultValue("0"), Description("Are we positioned at the first page?")> _
Public Property FirstPage() As Boolean
Get
Return _FirstPage
End Get
Set(ByVal Value As Boolean)
_FirstPage = Value
End Set
End Property
<Category("Paging"), DefaultValue("0"), Description("Are we positioned at the last page?")> _
Public Property LastPage() As Boolean
Get
Return _LastPage
End Get
Set(ByVal Value As Boolean)
_LastPage = Value
End Set
End Property
<Category("Paging"), DefaultValue("0"), Description("Number of pages from the paging control")> _
Public Property PageCount() As Integer
Get
Return _PageCount
End Get
Set(ByVal Value As Integer)
_PageCount = Value
End Set
End Property
<Category("Paging"), DefaultValue("0"), Description("Current Page Index of the paging control")> _
Public Property CurrentPageIndex() As Integer
Get
Return _CurrentIndex
End Get
Set(ByVal Value As Integer)
_CurrentIndex = Value
End Set
End Property
<Category("Paging"), DefaultValue("0"), Description("Page size used by the paging control")> _
Public Property PageSize() As Integer
Get
Return _PageSize
End Get
Set(ByVal Value As Integer)
_PageSize = Value
End Set
End Property
<Category("Paging"), DefaultValue("0"), Description("Total number of records from the paging control")> _
Public Property TotalNumberOfRecords() As Integer
Get
Return _TotalRecords
End Get
Set(ByVal Value As Integer)
_TotalRecords = Value
End Set
End Property
#End Region
Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
' Determine the top level elements to display
If Me.PageCount > 0 Then
output.Write(PagingDisplay)
Else
output.Write(NoPagingDisplay)
End If
End Sub
Private Function NoPagingDisplay() As String
' Generates appropriate DIV tag and default text
Dim retStr As New StringBuilder
' Top DIV tag
retStr.Append("<div class=""" & Me.CssClass.ToString & """>")
' Add the default text
If Me.TotalNumberOfRecords <> 0 Then
retStr.Append("You are currently viewing topics 1 to " & Me.TotalNumberOfRecords)
Else
retStr.Append("You are currently viewing topics 0 of 0")
End If
' Close Top Tag
retStr.Append("</div>")
' Return the appropriate values
Return retStr.ToString
End Function
Private Function PagingDisplay() As String
' Generates appropriate DIV tag and default text
Dim retStr As New StringBuilder
' Top DIV tag
retStr.Append("<div class=""" & Me.CssClass.ToString & """>")
' Calculate start and end positions
Dim currentTopicStart As Integer = (Me.CurrentPageIndex) * Me.PageSize
Dim currentTopicEnd As Integer
If Me.LastPage Then
currentTopicEnd = Me.TotalNumberOfRecords
Else
currentTopicEnd = currentTopicStart + Me.PageSize
End If
' Display the first element 'Current Viewing...'
retStr.Append("You are currently viewing topics " & (currentTopicStart + 1) & " to " & currentTopicEnd)
' Can we display the 'previous page' link?
If Not Me.FirstPage Then
retStr.Append(" ")
' Is this the first parameter?
If Me.BaseURL.IndexOf("?") > 0 Then
retStr.Append("<a href=""" & Me.BaseURL & "&PagePos=" & (Me.CurrentPageIndex - 1) & """><< Previous Page</a>")
Else
retStr.Append("<a href=""" & Me.BaseURL & "?PagePos=" & (Me.CurrentPageIndex - 1) & """><< Previous Page</a>")
End If
End If
' Display the positioning data
retStr.Append(" ")
retStr.Append("Page " & Me.CurrentPageIndex + 1 & " of " & Me.PageCount)
' Can we display the 'next page' link?
If Not Me.LastPage Then
retStr.Append(" ")
If Me.BaseURL.IndexOf("?") > 0 Then
retStr.Append("<a href=""" & Me.BaseURL & "&PagePos=" & (Me.CurrentPageIndex + 1) & """>Next Page >></a>")
Else
retStr.Append("<a href=""" & Me.BaseURL & "?PagePos=" & (Me.CurrentPageIndex + 1) & """>Next Page >></a>")
End If
End If
' Close Top Tag
retStr.Append("</div>")
' Return the appropriate values
Return retStr.ToString
End Function
End Class
#Region "Designer Details"
Public Class PagingControlDesigner
Inherits Web.UI.Design.ControlDesigner
Private _LocalObject As PagingControl
Public Sub New(ByVal component As IComponent)
If GetType(PagingControl) Is component Then
MyBase.Initialize(component)
_LocalObject = CType(component, PagingControl)
End If
End Sub
Public Overrides Function GetDesignTimeHtml() As String
' Build the HTML for the designer
Dim sb As New Text.StringBuilder
' Build the UI
sb.Append("<table")
sb.Append(" border=""0"">")
' Set the table row
sb.Append("<tr valign=""top"">")
sb.Append("<td>Currently viewing topics x to x <a href=""#""><< Previous Page</a> Page x of x <a href=""#"">Next Page >></a></td>")
sb.Append("</tr>")
' End the table
sb.Append("</table>")
End Function
End Class
#End Region
[Note: the above is unformatted as the code munched up the template / browser - sry]
So once you've got the above into your web control library, referenced in your project and dropped onto your form you simply need to configure your control (after configuring the paging control) using the following...
' Configure appropriate datasource
' Configure paging data source
_Pager =
New PagedDataSource
With _Pager
.AllowPaging = True
.DataSource = dt.DefaultView
.PageSize = 10
.CurrentPageIndex = CurrentPage
End
With
' Configure the paging control
With Me.PagingTop
.FirstPage = _Pager.IsFirstPage
.LastPage = _Pager.IsLastPage
.CurrentPageIndex = _Pager.CurrentPageIndex
.PageCount = _Pager.PageCount
.PageSize = _Pager.PageSize
' Note: the Page Numbers will be appended to this base URL
.BaseURL = Request.Url.AbsolutePath & "?catID=" & _CategoryID
.TotalNumberOfRecords = _Pager.DataSourceCount
End
With
. . .
And that's pretty much it - have fun. M