Drydo's Blog

Teenager of the Internet

This blog hosted by:
http://blogs.vbcity.com
  Home :: Syndication  :: Login   Community Forums   :: vbCity.com   :: DevCity.NET  

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...

Code CopyHideScrollFull
' 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

posted on Thursday, March 09, 2006 2:06 PM