Search code examples
javascriptasp.netcssviewstate

Div's Class not persisting when 'back' button is used


I have an ASP.NET page that contains two div's. Both have search fields and a search button contained within each of them. When I first come to this page, Div A has the class 'SearchDiv' while Div B has 'SearchDivDisabled'. These classes change the appearance so the user knows which search type they currently have enabled.

When Div B is clicked, JavaScript changes it's class to 'SearchDiv', and changes Div A to 'SearchDivDisabled'. This all works like a charm. The problem I have is when a user changes to Div B, clicks Div B's search button (which obviously redirects to a results page), and then uses the browser's back button. When they return to the search page, Div A is enabled again, and Div B is Disabled, even though they last used Div B. In the search button event handler I set the class attribute of the Divs before I redirect, hoping this will update the page on the server so when the user returns, their last-enabled Div will still be enabled (regardless of which one was enabled when the page was first visited).

I believe this involves the ViewState, but I'm unsure why the class attribute is not saved so when the user returns to the page it is restored. Is there something I'm missing here, or some easy way to guarantee the behavior I want? Thanks!

Edit: Here is the button event handler code:

protected void RedirectToResults(int searchEnum, string resultPage)
{
    ShowContainer(searchEnum);
    Response.Redirect(resultPage + this.webParams.getAllVariablesString(null));
}

  protected void ShowContainer(int searchContainerToShow)
  {
     if (searchContainerToShow < 0 || searchContainerToShow > SearchContainers.Count || SearchContainers.Count == 0)
        return;

     //disable all search panels
     foreach (SearchContainer container in SearchContainers.Values)
     {
        container.searchDiv.Attributes.Add("class", "SearchDivDisabled");
     }

     //enable selected panel
     SearchContainers[searchContainerToShow].searchDiv.Attributes.Add("class", "SearchDiv");
  }

RedirectToResults() is called from the actual button event handler with the enum representing the selected search panel and the results page url. SearchContainers is a dictionary mapping an integer to the search Div. The important code is the last line, where I'm updating the selected search container with the 'active' search class, rather than the disabled one (which I assign to the other div(s) )

Additional Update: I have been battling with this issue for the last couple days. I was sort of able to get the following code to work (in page_load):

        Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
        Response.AppendHeader("Expires", "0"); // Proxies.

But this really isn't a solution, as everything else that gets cached correctly is lost, which leaves me worse off than when I started. Everything else seems to persist fine, it is just the class of the div that is causing me struggles.

Edit: Just wanted to update this for anyone else that comes across this. While I believe there is a solution here with setting the cacheability of the page to force the browser to postback, I could not get it working 100% with all browsers (primarily Firefox was giving me fits, which is a documented bug). I do believe the cookie solution would work, but I felt that may be a bit more complex than necessary for just trying to store the state of a couple div's.

What I ended up doing was tying the div's class to the state of it's correlating radio button (there are radio buttons next to the div which allow the users a more visual way of enabling search panels). I noticed these radio buttons retained the correct checked value when the back button was used, so I could guarantee they would indicate the correct div to be enabled. So in JavaScript's onload I check which radio button is enabled, and then adjust the classes of the search div's accordingly. This is a pretty big hack, but has worked 100% across all browsers, and only took about 10 lines of JavaScript.


Solution

  • Because you are not posting back to change the div's style, when the user hits the back button it is taking it back to how the page was originally posted. The easy way to fix this is to have the button cause a postback that toggles the style.