How to change the order of a List(Of Order) and do paging

I need help with my code.

My goal is to be able to use the click event of two buttons to page through a list of orders. This list of orders, can also be re-sorted using a parameter passed via Query-string.

Currently I am able to do the paging, but not working 100% accurately.

For example, with my current code, if I have a list with the following order by email:

J@email.com
R@email.com
R@email.com
R@email.com
T@email.com

My paging code will browse the records as if they were in this order:

T@email.com - previous
J@email.com - current
R@email.com - next
R@email.com - next
R@email.com - next

If I change the order to be descending:

T@email.com
R@email.com
R@email.com
R@email.com
J@email.com

The the paging code will begin like:

T@email.com
J@email.com
R@email.com
R@email.com
R@email.com

If I click previous when on record for 'T@email.com' then I get the page where user gets notified that there are no more records to browse to, but if I click the 'Next' button, then I go to the records for: 'J@email.com', but the entire set set and paging gets changed to:

T@email.com
J@email.com
R@email.com
R@email.com
R@email.com

This is my current code:

    Protected Sub btnUp_Click(sender As Object, e As EventArgs) Handles btnUp.Click

        Dim currentOrderID As String
        Dim currentOrder As Order
        Dim nextOrder As Order = Nothing

        spiderSiteKey = Request.QueryString("siteKey")
        strEnv = Request.QueryString("strEnv")
        currentOrderID = Request.QueryString("order_id")
        strSortBy = Request.QueryString("SortBy")
        strSortDirection = Request.QueryString("SortDirection")

        orderList = New Orders(spiderSiteKey)
        orderList.GetOrdersByDate(CDate(Request.QueryString("Start")), CDate(Request.QueryString("End")).AddDays(1), strEnv)

        If Not String.IsNullOrEmpty(strSortBy) Then
            orderList.Items.AsQueryable.OrderBy(strSortBy + " " + strSortDirection)
        End If

        currentOrder = (From order In orderList.Items
            Where order.OrderID.Equals(currentOrderID)
            Select order).FirstOrDefault()

        If currentOrder IsNot Nothing Then
            Dim index = orderList.Items.IndexOf(currentOrder)
            If Not index <= 0 Then _
                nextOrder = DirectCast(orderList.Items(index - 1), Order)
            If nextOrder IsNot Nothing Then
                btnUp.Visible = True
                Response.Redirect("~/order-review.aspx?order_id=" & nextOrder.OrderID &
                                  "&siteKey=" & spiderSiteKey &
                                  "&strEnv=" & strEnv &
                                  "&Start=" & CDate(Request.QueryString("Start")) &
                                  "&End=" & CDate(Request.QueryString("End")) &
                                  "&SortBy=" & strSortBy &
                                  "&SortDirection=" & strSortDirection
                    )
            Else
                btnUp.Visible = False
                lblnoRecs.Visible = True
                lblnoRecs.Text = "No records to display. " &
                    "Click the Previous button to go to the next available order, " &
                    "or the link below to go to the search page."
                lnkgoBack.Visible = True
                lnkgoBack.Text = "SpiderWeb"
                lnkgoBack.NavigateUrl = Page.ResolveUrl("~/order-history.aspx?&siteKey=" & spiderSiteKey &
                                                        "&strEnv=" & strEnv &
                                                        "&Start=" & Request.QueryString("Start") &
                                                        "&End=" & Request.QueryString("End"))
            End If
        End If

    End Sub

    Protected Sub btnDown_Click(sender As Object, e As EventArgs) Handles btnDown.Click

        Dim currentOrderID As String = String.Empty
        Dim previousOrder As Order = Nothing

        spiderSiteKey = Request.QueryString("siteKey")
        strEnv = Request.QueryString("strEnv")
        currentOrderID = Request.QueryString("order_id")
        strSortBy = Request.QueryString("SortBy")
        strSortDirection = Request.QueryString("SortDirection")

        orderList = New Orders(spiderSiteKey)
        orderList.GetOrdersByDate(CDate(Request.QueryString("Start")), CDate(Request.QueryString("End")).AddDays(1), strEnv)

        Dim temporders As System.Collections.Generic.List(Of Order) = orderList.Items

        If Not String.IsNullOrEmpty(strSortBy) Then
            orderList.Items.AsQueryable.OrderBy(strSortBy + " " + strSortDirection)
        End If

        Dim currentOrder = (From order In orderList.Items
                            Where order.OrderID.Equals(currentOrderID)
                            Select order).FirstOrDefault()

        If currentOrder IsNot Nothing Then
            Dim index = orderList.Items.IndexOf(currentOrder)
            If Not index >= orderList.Items.Count - 1 Then _
                previousOrder = DirectCast(orderList.Items(index + 1), Order)
            If previousOrder IsNot Nothing Then
                btnDown.Visible = True
                Response.Redirect("~/order-review.aspx?order_id=" & previousOrder.OrderID &
                                  "&siteKey=" & spiderSiteKey &
                                  "&strEnv=" & strEnv &
                                  "&Start=" & CDate(Request.QueryString("Start")) &
                                  "&End=" & CDate(Request.QueryString("End")) &
                                  "&SortBy=" & strSortBy &
                                  "&SortDirection=" & strSortDirection)
            Else
                btnDown.Visible = False
                lblnoRecs.Visible = True
                lblnoRecs.Text = "No records to display. " &
                    "Click the Next button to go to the next available order, " &
                    "or the link below to go to the search page."
                lnkgoBack.Visible = True
                lnkgoBack.Text = "SpiderWeb"
                lnkgoBack.NavigateUrl = Page.ResolveUrl("~/order-history.aspx?&siteKey=" & spiderSiteKey &
                                                        "&strEnv=" & strEnv &
                                                        "&Start=" & Request.QueryString("Start") &
                                                        "&End=" & Request.QueryString("End"))
            End If
        End If
    End Sub

Open in new window


If there are not sort parameters for property, and direction, then this code should be ignored:

        If Not String.IsNullOrEmpty(strSortBy) Then
            orderList.Items.AsQueryable.OrderBy(strSortBy + " " + strSortDirection)
        End If

Open in new window

the_lone_noteAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

it_saigeDeveloperCommented:
This is by no means meant to be a direct implementation on your site but should serve as an idea of how these things would work.  Ultimately, you are talking about two different tasks, namely, paging and sorting.  Consider the following:
Imports System.Runtime.CompilerServices
Imports System.Linq.Expressions

Module Module1
	Sub Main()
		Dim people As New List(Of Person) From _
		 {
		  New Person() With {.ID = 0, .FirstName = "Zed", .LastName = "Anderson", .Birthday = New DateTime("2014", "1", "1")},
		  New Person() With {.ID = 1, .FirstName = "Yancy", .LastName = "Benson", .Birthday = New DateTime("2003", "1", "1")},
		  New Person() With {.ID = 2, .FirstName = "Xarius", .LastName = "Centillier", .Birthday = New DateTime("2012", "1", "1")},
		  New Person() With {.ID = 3, .FirstName = "Victor", .LastName = "Davidson", .Birthday = New DateTime("2005", "1", "1")},
		  New Person() With {.ID = 4, .FirstName = "Ullyses", .LastName = "Eaton", .Birthday = New DateTime("2010", "1", "1")},
		  New Person() With {.ID = 5, .FirstName = "Terry", .LastName = "Foster", .Birthday = New DateTime("2007", "1", "1")},
		  New Person() With {.ID = 6, .FirstName = "Simon", .LastName = "Guillen", .Birthday = New DateTime("2008", "1", "1")},
		  New Person() With {.ID = 7, .FirstName = "Randolph", .LastName = "Harrison", .Birthday = New DateTime("2009", "1", "1")},
		  New Person() With {.ID = 8, .FirstName = "Quicy", .LastName = "Iverson", .Birthday = New DateTime("2006", "1", "1")},
		  New Person() With {.ID = 9, .FirstName = "Paul", .LastName = "Jones", .Birthday = New DateTime("2011", "1", "1")},
		  New Person() With {.ID = 10, .FirstName = "Oscar", .LastName = "Kite", .Birthday = New DateTime("2004", "1", "1")},
		  New Person() With {.ID = 11, .FirstName = "Norman", .LastName = "Lyle", .Birthday = New DateTime("2013", "1", "1")},
		  New Person() With {.ID = 12, .FirstName = "Mary", .LastName = "Margaret", .Birthday = New DateTime("2002", "1", "1")}
		 }

		Console.WriteLine("Ordering the first page of five results by descending ID:")
		For Each p In people.GetPage(1, 5).GetOrdered("ID", SortDirection.Descending)
			Console.WriteLine(p)
		Next

		Console.WriteLine()
		Console.WriteLine("Now ordering the last page of 5 results by ascending First Name, descending Birthday and descending Last Name:")
		For Each p In people.GetPage(3, 5).GetOrdered({New SortOption("FirstName"), New SortOption("Birthday", SortDirection.Descending), New SortOption("LastName", SortDirection.Descending)})
			Console.WriteLine(p)
		Next

		Console.ReadLine()
	End Sub
End Module

Public Class Person
	Public Property ID() As Integer
	Public Property FirstName() As String
	Public Property LastName() As String
	Public Property Birthday() As DateTime

	Public Overrides Function ToString() As String
		Return String.Format("{0} {1}; Born on - {2}", FirstName, LastName, Birthday.ToShortDateString())
	End Function
End Class

Public Module Extensions
	<Extension()> Public Function GetPage(Of T)(ByVal source As IEnumerable(Of T), Optional ByVal index As Integer = 0, Optional ByVal size As Integer = 10) As IEnumerable(Of T)
		Return source.Skip((index - 1) * size).Take(size)
	End Function

	<Extension()> Public Function GetOrdered(Of T)(ByVal source As IEnumerable(Of T), ByVal name As String, ByVal direction As SortDirection) As IEnumerable(Of T)
		If String.IsNullOrEmpty(name) Then
			Return source
		End If
		Return source.GetOrdered(New List(Of SortOption) From {New SortOption(name, direction)})
	End Function

	<Extension()> Public Function GetOrdered(Of T)(ByVal source As IEnumerable(Of T), Optional ByVal sortOptions As IEnumerable(Of SortOption) = Nothing) As IEnumerable(Of T)
		Dim results As IEnumerable(Of T) = source
		Dim firstExpression As Boolean = True

		If sortOptions IsNot Nothing Then
			For Each [option] In sortOptions
				Select Case [option].Direction
					Case SortDirection.None
					Case SortDirection.Ascending
						If firstExpression Then
							results = results.OrderBy(GetType(T).GetOrderByFunction(Of T)([option].Name))
						Else
							results = DirectCast(results, IOrderedEnumerable(Of T)).ThenBy(GetType(T).GetOrderByFunction(Of T)([option].Name))
						End If
						Exit Select
					Case SortDirection.Descending
						If firstExpression Then
							results = results.OrderByDescending(GetType(T).GetOrderByFunction(Of T)([option].Name))
						Else
							results = DirectCast(results, IOrderedEnumerable(Of T)).ThenByDescending(GetType(T).GetOrderByFunction(Of T)([option].Name))
						End If
						Exit Select
				End Select
				If firstExpression Then firstExpression = False
			Next
		End If
		Return results
	End Function

	<Extension()> Public Function GetOrderByFunction(Of T)(ByVal source As Type, ByVal value As String) As Func(Of T, Object)
		Dim parameter As ParameterExpression = Nothing
		Dim conversion As Expression = Nothing
		Dim result As Func(Of T, Object) = Nothing

		If Not String.IsNullOrEmpty(value) Then
			parameter = Expression.Parameter(source, "x")
			conversion = Expression.Convert(Expression.Property(parameter, value), GetType(Object))
			result = Expression.Lambda(Of Func(Of T, Object))(conversion, parameter).Compile()
		End If
		Return result
	End Function
End Module

Public Class SortOption
	''' <summary>The name field</summary>
	Private ReadOnly fName As String = String.Empty
	''' <summary>The direction field</summary>
	Private ReadOnly fDirection As SortDirection = SortDirection.None

	''' <summary>Gets the name.</summary>
	''' <value>The name.</value>
	Public ReadOnly Property Name() As String
		Get
			Return fName
		End Get
	End Property

	''' <summary>Gets the direction.</summary>
	''' <value>The direction.</value>
	Public ReadOnly Property Direction() As SortDirection
		Get
			Return fDirection
		End Get
	End Property

	''' <summary>Prevents a default instance of the <see cref="SortOption"/> class from being created.</summary>
	Private Sub New()
		fName = String.Empty
		fDirection = SortDirection.None
	End Sub

	''' <summary>Initializes a new instance of the <see cref="SortOption"/> class.</summary>
	''' <param name="Name">The name.</param>
	Public Sub New(ByVal Name As String)
		Me.New(Name, SortDirection.Ascending)
	End Sub

	''' <summary>Initializes a new instance of the <see cref="SortOption"/> class.</summary>
	''' <param name="Name">The name.</param>
	''' <param name="Direction">The direction.</param>
	Public Sub New(ByVal Name As String, ByVal Direction As SortDirection)
		fName = Name
		fDirection = If(Direction.Equals(SortDirection.Descending), Direction, SortDirection.Ascending)
	End Sub
End Class

Public Enum SortDirection
	None = 0
	Ascending = 1
	Descending = 2
End Enum

Open in new window


Which produces the following output -Capture.JPG-saige-

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
If you have any questions, please ask.

-saige-
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.