Question

Scenario:

  • User submits search criteria and selects an item from search results on the same page, which navigates to a new page of details for the selected item.

  • When the User returns to the search screen, the search criteria & results (including selected page and sort-order) should be preserved from their last visit.

Related information:

  1. All form submissions are POSTs.
  2. Navigation back to the search screen may not be available from last browser history (e.g. more than one details screen may be encountered, or the user may navigate directly to the search screen from an alternative menu.)
  3. Search results are provided using Telerik RadGrid control.
  4. I'm looking for a generic solution that will be able to be applied to different search screens.
  5. In some instances, the item may be DELETED from within the details screen, and should therefore not appear in the search results when the screen is next encountered.

Thoughts:

  • I've read a lot of suggested methods for addressing various parts of this scenario, but I'm still confused; no comprehensively "correct" solution jumps to the forefront.

  • I guess I'm asking for recommendations/approach rather than a whole solution spelled out for me (although that would be nice! ;-)

  • The .NET VIEWSTATE would seem to do exactly what I'm after (with the exception of #5) - Is there some way of leveraging off this so that viewstate can be used between pages, and not just between postbacks to the same page? (e.g. can I store/restore viewstate to/from a session variable or something? I haven't seen this suggested anywhere and I'm wondering if there's a reason why.)

Thanks in advance.

Was it helpful?

Solution

Thanks for all the advice.

For the benefit of others, here is a solution to this issue (no doubt there's room for improvement, but this works satisfactorily for the moment).

4 functions...

StoreSearchCookie - Persist the state/values of a panel of search criteria and a results grid in a cookie with a specified UID.

RestoreSearchCookie_Criteria - Read the cookie and re-populate the search criteira

RestoreSearchCookie_Results - Read the cookie and restore the grid state.

FindFormControls - Helper method to recursively find form-input controls in a container (pinched & modified from elsewhere on Stack Overflow)

NB...

  • I haven't addressed the multiple-tabs issue because our application doesn't allow them anyway.
  • RestoreSearchResults utilises GridSettingsPersister.cs available from Telerik website, (but I had to modify it to store the page number as well)

Usage is as follows...

protected void Page_PreRender(object sender, EventArgs e)
{
    if (Page.IsPostBack)
    {
        // Store the state of the page
        StoreSearchCookie("SomeSearchPage", pnlSearchCriteria, gridResults);
    }
    else
    {
        // Restore search criteria
        RestoreSearchCookie_Criteria("SomeSearchPage");

        // Re-invoke the search here
        DoSearch();  // (for example)

        // Restore the grid state
        RestoreSearchCookie_Results("SomeSearchPage");
    }
}

Code follows...

    protected void StoreSearchCookie(string cookieName, Panel SearchPanel, RadGrid ResultsGrid)
    {

        try
        {

            HttpCookie cookieCriteria = new HttpCookie("StoredSearchCriteria_" + cookieName);

            // 1. Store the search criteria
            //
            List<Control> controls = new List<Control>();
            FindFormControls(controls, SearchPanel);
            foreach (Control control in controls)
            {
                string id = control.ID;
                string parentId = control.Parent.ID;
                string uid = string.Format("{0}>{1}", parentId, id);
                string value = "";

                Type type = control.GetType();

                bool isValidType = true;      // Optimistic!

                if (type == typeof(TextBox))
                {
                    value = ((TextBox)control).Text;
                }
                else if (type == typeof(DropDownList))
                {
                    value = ((DropDownList)control).SelectedValue;
                }
                else if (type == typeof(HiddenField))
                {
                    value = ((HiddenField)control).Value;
                }
                else if (type == typeof(RadioButton))
                {
                    value = ((RadioButton)control).Checked.ToString();
                }
                else if (type == typeof(CheckBox))
                {
                    value = ((CheckBox)control).Checked.ToString();
                }
                else
                {
                    isValidType = false;
                }

                if (isValidType)
                {
                    cookieCriteria.Values[uid] = value;
                }

            }

            cookieCriteria.Expires = DateTime.Now.AddDays(1d);
            Response.Cookies.Add(cookieCriteria);

            // 2. Persist the grid settings
            //
            GridSettingsPersister SavePersister = new GridSettingsPersister(ResultsGrid);
            HttpCookie cookieResults = new HttpCookie("StoredSearchResults_" + cookieName);
            cookieResults.Values["GridId"] = ResultsGrid.ID;
            cookieResults.Values["GridSettings"] = SavePersister.SaveSettings();
            cookieResults.Expires = DateTime.Now.AddDays(1d);
            Response.Cookies.Add(cookieResults);

        }
        catch (Exception exception)
        {
            Logger.Write(exception);
        }


    }

    protected void RestoreSearchCookie_Criteria(string cookieName)
    {
        try 
        {
            HttpCookie cookieCriteria = Request.Cookies["StoredSearchCriteria_" + cookieName];

            if (cookieCriteria != null)
            {

                foreach (string key in cookieCriteria.Values.AllKeys)
                {

                    string value = cookieCriteria[key];
                    string[] ids = key.Split('>');
                    string parentId = ids[0];
                    string id = ids[1];
                    Control control = FindControl(parentId).FindControl(id);    

                    Type type = control.GetType();

                    if (type == typeof(TextBox))
                    {
                        ((TextBox)control).Text = value;
                    }
                    else if (type == typeof(DropDownList))
                    {
                        ((DropDownList)control).SelectByValue(value);
                    }
                    else if (type == typeof(HiddenField))
                    {
                        ((HiddenField)control).Value = value;
                    }
                    else if (type == typeof(RadioButton))
                    {
                        ((RadioButton)control).Checked = Boolean.Parse(value);
                    }
                    else if (type == typeof(CheckBox))
                    {
                        ((CheckBox)control).Checked = Boolean.Parse(value);
                    }
                }
            }
        }
        catch (Exception exception)
        {
            Logger.Write(exception);
        }
    }

    protected void RestoreSearchCookie_Results(string cookieName)
    {
        try 
        {

            HttpCookie cookieResults = Request.Cookies["StoredSearchResults_" + cookieName];

            if (cookieResults != null)
            {
                string gridId = cookieResults.Values["GridId"];
                string settings = cookieResults.Values["GridSettings"];

                RadGrid grid = (RadGrid)FindControl(gridId);

                GridSettingsPersister LoadPersister = new GridSettingsPersister(grid);
                LoadPersister.LoadSettings(settings);
                grid.Rebind();

            }
        }
        catch (Exception exception)
        {
            Logger.Write(exception);
        }
    }


    private void FindFormControls(List<Control> foundSofar, Control parent)
    {
        List<Type> types = new List<Type> { typeof(TextBox), typeof(DropDownList), typeof(RadioButton), typeof(CheckBox), typeof(HiddenField) };
        foreach (Control control in parent.Controls)
        {
            if (types.Any(item => item == control.GetType()))
            {
                foundSofar.Add(control);
            }
            if (control.Controls.Count > 0)
            {
                this.FindFormControls(foundSofar, control);  // Use recursion to find all descendants.
            }
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top