2

I have a simple ListView paged by a DataPager giving a list of products. When we click on the product we open the product details page. On the details page we want to "return to product list" but of course we want it to remember what page the datapager was at.

Surely this was conceived as a natural design requirement - what is the simple out-of-the-box way to do this?

If we use the QueryStringField property of DataPager we get the page number in the URL so I hoped I could use the referrer URL in the back link, but I have found the Request.UrlReferrer to be unreliable (when I use F5 to debug the app in Internet Explorer for example, Request.UrlReferrer is always null).

I have found some success with storing the page number in a session variable:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            if (Session["PagerIndex"] != null)
            {
                DataPager1.SetPageProperties((int)Session["PagerIndex"],
                  DataPager1.MaximumRows, false);
            }
        }
    }

    protected void DataPager1_PreRender(object sender, EventArgs e)
    {
        if (Page.IsPostBack)
        {
            Session["PagerIndex"] = DataPager1.StartRowIndex;
        }
    }

This method has some drawbacks:

  1. Only works if QueryStringField is blank (so IsPostBack can be detected)
  2. Session/cookie variable required for each pager
  3. Question of how to reset the session/cookie variables arises

What is the "proper" way to do this?

Thanks

Etherman
  • 1,777
  • 1
  • 21
  • 34

2 Answers2

2

You can try my solution Set the QueryStringField property of your datapager to a querystringfield say page.

 <asp:DataPager ID="DataPager2" runat="server" PagedControlID="ListView1" 
    QueryStringField="page">
    ....

Note: I placed the DataPager outside of the ListView.

Put linkButton in your listview that will redirect you to detailspage and in its click event save the current page number in a Session

 int integ;
    decimal fract;
    integ = DataPager2.StartRowIndex / DataPager2.PageSize;
    fract = (DataPager2.StartRowIndex / DataPager2.PageSize) - integ;
    if (fract > 0)
        page = integ;
    else if (integ > 0) page = integ - 1;
  Session["page"]=page;

On the details page retrieve the page and pass back as a querystring to ListViewpage. Automatically the datapager will take you to that page number, if not specified to page number 1.

Good Luck !

Mubarek
  • 2,691
  • 1
  • 15
  • 24
  • Your solution eliminates the reliance on IsPostBack and referrer url, and I think it removes the problems I had with session variables - we can use the same session variable for every pager. Also, this saves me the task of figuring out which page a certain product ID is on (and the possibility of the product list changing is minimal). – Etherman Jan 26 '12 at 07:28
  • I used a combination of yours and Stilgar's suggestions: I used QueryStringField parameter, but passed the page number to the detail page in the URLs instead of session vars (this was more convenient). I used this to get page number: PageNo = (int)Math.Truncate((double)(DataPager1.StartRowIndex / DataPager1.PageSize)) + 1; – Etherman Jan 26 '12 at 08:42
  • What matters is the workaround, if it worked that was the goal. Thanks – Mubarek Jan 26 '12 at 08:48
1

If you don't have any filters you can simply recalculate the page on which the product was.

Another option will be to encode the page (together with possible filter values for the list) in the URL of the product detail page and use them to generate an URL for the list that will be essentially the same as the one of the original list. Even something like the ReturnUrl approach used for login. Sharepoint does similar thing with its lists but I feel the URL can get too messy (and I am not a person that falls for the whole "clean URL" bullshit when I say it is messy it really is)

One more option would be to pass the product ID to the list page via the URL. The list page can then calculate the appropriate page. This will remove the noise from the URLs

Stilgar
  • 22,354
  • 14
  • 64
  • 101
  • I get what you're saying - pass required data via the URLs to the details page and back again, but it seems like I'd have to custom code that for every scenario. I'm moving from an environment where I hand code every minute detail and have been looking forward to having all these sort of inane tasks done for me! I guess your first suggestion is the more apropriate because the data in the list may have changed leading to re-ordering etc. and thus invalidating the stored page index. – Etherman Jan 25 '12 at 14:02
  • You can add this logic to a BasePage class or something so you won't need to handle it on a case by case basis. I also added another option to my answer that I feel is more generic in a way. – Stilgar Jan 25 '12 at 14:31
  • Actually your last option is how I understood your first one to be. This is how I have decided to implement it - only the product ID is required to be passed from the detail page. From there I can work out exactly which page to display, even if the product list has since been changed. – Etherman Jan 26 '12 at 07:10