Monday, July 18, 2011

MVC3 Webgrid Html Helper persistent searchbox

Monday, July 18, 2011 Posted by Andre Broers , , , , 5 comments
I needed search functionality to the webgrid html helper. The searchbox itself wasn’t that hard. But everytime I changed the sort order the search got cleared. I created the following code to keep the search box persistent until the user actively clears the search box.
We need the model (a list of persons)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcApplication4.Models
{
  public class Person
  {
    public int id { get; set; }
    public string name { get; set; }
    public int age { get; set; }

    public List<Person> GetPersons()
    {
      return new List<Person>()
      {
         new Person() { id=1, name="Andre", age=10}
        ,new Person() { id=2, name="Bennie", age=20}
        ,new Person() { id=3, name="Roel", age=30}
        ,new Person() { id=4, name="Jeroen", age=40}
        ,new Person() { id=5, name="Arjan", age=50}
        ,new Person() { id=6, name="PietJan", age=60}
        ,new Person() { id=7, name="Alex", age=70}
        ,new Person() { id=8, name="Wim", age=80}
        ,new Person() { id=9, name="Jan", age=90}
        ,new Person() { id=10, name="Coby", age=100}
        ,new Person() { id=11, name="Marjan", age=110}
      };
    }
  }
}

We need a viewbag object where we store our Request variables:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MvcApplication4.Models
{
  public class QueryStringView
  {
    public string key { get; set; }
    public string value { get; set; }
  }
}

We need the controller in this case with an index ActionMethod:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication4.Models;

namespace MvcApplication4.Controllers
{
  public class TestController : Controller
  {
    //
    // GET: /Test/

    public ActionResult Index(string personSearch)
    {
      // Set the viewbag for the searchbox value     personSearh to persist the search
      ViewBag.personSearch = personSearch;
      // Save all other request values and set them in the hiddenfields of the form
      List<QueryStringView> qperson = new     List<QueryStringView>();
      foreach (string s in Request.QueryString.AllKeys)
      {
        if (!s.Equals("personSearch"))
        {
          qperson.Add(new QueryStringView() { key = s, value = Request.QueryString[s] });
        }
      }
      ViewBag.personSearchQueryString = qperson;

      // Filter the persons
      Person p = new Person();
      List<Person> lp = p.GetPersons();
      if (!string.IsNullOrEmpty(personSearch))
        lp = lp.Where(x => x.name.ToUpper().Contains(personSearch.ToUpper())).ToList();
      return View(lp);
    }
  }
}

Herein we store the request variables and the query. Later in the view we reset the variables.
@model IEnumerable<MvcApplication4.Models.Person>

@{
  ViewBag.Title = "Index";
  var grid = new WebGrid(source: Model, canSort: true,    canPage: true, rowsPerPage: 3);
}

<form id="pricesearchform" action="">
  <input class="personsearchtext" type="text" id="personSearch" name="personSearch" value="@ViewBag.personSearch" />
  <button class="personsearchbutton" type="submit">Search</button> 
  @foreach (var item in ViewBag.personSearchQueryString)
  {
    <input type="hidden" name="@item.key" value="@item.value" /> 
  }
</form>

@grid.GetHtml(columns: grid.Columns(
    grid.Column("name"),
    grid.Column("age")
  )
)

In this view we create a form in which the search input is defined. The value is set from the ViewBag in which we stored the search query. After this we create a bunch of hiddenfields for all the webgrid parameters so they are submitted to the server on a form submit.

Now we can search and after the search change the order of the grid on the columns or page through the pages. The search will stay active until the searchbox is cleared and submitted.

As you can see, this is all stateless. Someone can bookmark this and on return the same query will be fired again.

Look at: http://www.watzdprice.com/en/Product/Details/2/diesel-1-liter for a live sample.

5 comments:

  1. This was exactly what I needed! Want to give credit where credit is due!

    Thank you!

    ReplyDelete
  2. Potong Pasir MRT at the doorstep, residents can easily access almost to any destination through.
    theinterlacecondo.sg

    ReplyDelete