views:

642

answers:

3

Hello, I have a grid with contact information which I need to be able to page through.

All the plumbing is already in place, with one last detail. Paging is done through a simple p Querystring parameter, e.g. www.myurl.com/grid?p=3 would be the third page; the repository is automatically fetching the right data, and also the total count of items. The size of each page is defined somewhere else and I don't need to worry about that in the query string.

However, I support searching etc. as well. The search term searched for in denoted as q in my Querystring. So now I can have a combination: www.myurl.com/grid?q=tom&p=2 which searches for "tom" and pulls the second page of results.

The problem I face now, since the q (or other) parameters may be present in the query string, how do I create a pager for this (which would need to keep the original parameters, so if I click on "page 2" it needs to go from

  • www.myurl.com/grid?a=1&b=xyz&q=tom

    to

  • www.myurl.com/grid?a=1&b=xyz&q=tom&p=2

How can I do this?

A: 

I asked a similar question yesterday. Maybe you want to check out http://stackoverflow.com/questions/1425000/preserve-data-in-net-mvc

following is the code copied from Steve Sanderson's book

public static class PagingHelpers
{
    public static string PageLinks(this HtmlHelper html, int currentPage,
    int totalPages, Func<int, string> pageUrl)
    {
        StringBuilder result = new StringBuilder();
        for (int i = 1; i <= totalPages; i++)
        {
            TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag

            tag.MergeAttribute("href", pageUrl(i));
            tag.InnerHtml = i.ToString();
            if (i == currentPage)
                tag.AddCssClass("selected");


            result.AppendLine(tag.ToString());
        }
        return result.ToString();
    }
}
Wei Ma
Your question is similar, but not the same as I want the parameters to also stay visible (as part of the entire query string, not in a hidden field) so that people can bookmark page 5 of a search query for example.
Alex
Wei Ma
if your want to have page=5 as well, you should go to Global.ascx.cs and change your route mapping from "Grid/{page}" to "Grid".
Wei Ma
Where do you have the Html.PageLink extension method? Could you add the sample code to your answer?
Alex
A: 

So you need to have your page links direct the user to the same URL but with a different "page" value. The most obvious way to do this is to have your code that renders a page link grab the query string from the current request, modify the "page" value, and render a link using the modified string.

Alternatively, and this is the approach I've taken, you can define a new route for your "list" pages, that includes any paging and sorting values. This way they're part of the URL but also very easy to handle in your controller.

An example that includes sorting and paging values might look something like this:

routes.MapRoute(
    "List",
    "{controller}/List/{pageNumber}/{sortBy}/{sortOrder}/{pageSize}",
    new { action = "List", sortBy = "Id", sortOrder = "Asc", pageNumber = 1, pageSize = 10 },
    new { sortBy = @"[A-Za-z0-9+-]*", sortOrder = "Asc|Desc", pageNumber = @"\d{1,6}", pageSize = @"\d{1,6}" });

Obviously your "List" action method needs to be able to interpret the values and handle the data accordingly. This may not be what your really looking for but I just thought I'd throw it out there.

ASIDE: I've also written a [List] action filter attribute that picks up these values from the route and (if the model is a collection) automatically applies the sorting and paging in OnActionExecuted. This way all my action has to do is retrieve the data and set the model.

Ty
How would you create a pager that works with this structure? Could you post a code example as you have it?
Alex
Well basically you have all the same bits of information you have now, but it's all available in your route data instead of your query string. I'm assuming, however, that this approach will require significant changes to your code.
Ty
A: 

I persist the search values for each form in the session. In methods that respond to search or paging, I first load up any values from the session, then override them (and set the session values, if necessary) with values from the querystring or form parameters, depending on whether it is a get or post. This way I don't have to worry about the paging code including the search criteria -- it simply uses what is already stored. If I want to do a new search, then the values in the search boxes change and the search is performed using a filter button -- which starts with results from page 1.

tvanfosson
Care to share some code to visualize?
Alex