You're right about having to use a querystring. You should be able to clean up those calls to Request.QueryString by adding "search" as one of the parameters to your action.
I'm very curious to know what exactly that first function is accomplishing. "search" and "SearchFilter" are already being included in the querystring by the form submit...
You'll find that if you turn ajax off, the querystring persists on sorts after you've filtered (the sort links won't clobber your search parameter) which is why I suggested not using it to begin with. Doing it that way means you have to maintain the state
of the rest of the page through a ViewModel or ViewData. The way you do it depends on what will be more convenient for you.
denappel
Member
5 Points
8 Posts
mvc 3 webgrid filtering combined with sorting problem
Jan 31, 2011 08:49 AM|LINK
Hi,
I'm trying to use the new webgrid helper in mvc3. The grid is quite ok, but I got stuck on the following:
On the page, we have a search filter above the webgrid, to filter the data in the grid with an ajax call.
After the grid is filtered, when we click on a column header to sort the data, again all data is shown in the grid.
Since the sorting is done with an http-get, we lose the search string.
Now one solution would be to use the session to store the last search string, but imo this is not a good solution,
since we'll have a lot of pages with this functionality, we would start creating session variables for every kind of filter,
what is not really ideal I think.
A better solution would be to inject the search filter into the querystring for the sorting request.
However the grid doesn't seem to support this, there is a GetSortUrl() method, but not Set Method, or no property
to handle this.
Does anybody has an idea how to solve this?
Thanks in advance!
Koen
Razor code:
<table border="0" cellpadding="0" cellspacing="5"> <tr> <td> @using (Ajax.BeginForm("Index", new AjaxOptions { UpdateTargetId = "results" })) { <table border="0" cellpadding="0" cellspacing="5"> <tr> <td> Search </td> <td> @Html.TextBox("SearchFilter", Model.SearchFilter) </td> <td> <input name="button" type="submit" value="Search" /> </td> </tr> </table> } </td> </tr> <tr> <td> <div id="results"> @if(!string.IsNullOrEmpty(Model.SearchFilter)){ <p>Search Filter: @Model.SearchFilter</p> } <p> @{ var grid = new WebGrid(Model.SubscriptionList, canPage: true, rowsPerPage: 30); grid.Pager(WebGridPagerModes.NextPrevious); @grid.GetHtml(tableStyle: "webGrid", headerStyle: "header", alternatingRowStyle: "alt", columns: grid.Columns( grid.Column(format: (item) => Html.ActionLink("View", "Details", new { id = item.Id })), grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.Id })), grid.Column("Id", "ID", canSort: true), grid.Column("ISP", "ISP", canSort: true), grid.Column("SubscriptionName", "Name", canSort: true), grid.Column("Mode", "Mode", canSort: true), grid.Column("SetupFee", "Setup Fee", canSort: true), grid.Column("MonthlyFee", "Monthly Fee")) ); } </p> </div> </td> </tr> </table>asp. net mvc3 WebGrid
ryanw51
Contributor
2363 Points
511 Posts
Re: mvc 3 webgrid filtering combined with sorting problem
Jan 31, 2011 12:40 PM|LINK
Is it completely necessary for you to use AJAX? I stay away from AJAX when I use the webgrid as it's much easier to maintain the state of the grid.
denappel
Member
5 Points
8 Posts
Re: mvc 3 webgrid filtering combined with sorting problem
Jan 31, 2011 03:04 PM|LINK
Hi,
No I woudn't be that necessary to use ajax, however the problem woudn't be solved when ajax is not used,
it would make no difference imo.
I've been thinking about a workaround for the problem, and I've found one.
I inject an extra parameter into the querystring collection. That way I can put the search filter into the querystring.
Normally the querystring collection is readonly, but I've found some code to fix this.
Code to add parameter to querystring:
public static void Add(string name, string value) { NameValueCollection qs = System.Web.HttpContext.Current.Request.QueryString; qs = (NameValueCollection)System.Web.HttpContext.Current.Request.GetType().GetField("_queryString", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(System.Web.HttpContext.Current.Request); PropertyInfo readOnlyInfo = qs.GetType().GetProperty("IsReadOnly", BindingFlags.NonPublic | BindingFlags.Instance); readOnlyInfo.SetValue(qs, false, null); qs[name] = value; readOnlyInfo.SetValue(qs, true, null); }New controller code:
public ActionResult Index(string SearchFilter) { // check querystring search if (string.IsNullOrEmpty(SearchFilter) && !String.IsNullOrEmpty(Request.QueryString["search"])) SearchFilter = Request.QueryString["search"]; var model = new Models.SubscriptionListModel { SearchFilter = SearchFilter }; if (string.IsNullOrEmpty(SearchFilter)) { model.SubscriptionList = _subscriptionHandler.ReadWhereIdLessThanThousand(); } else { // add search filter to the querystring Common.QueryString.Add("search", SearchFilter); model.SubscriptionList = _subscriptionHandler.ReadWhereContains(SearchFilter); } if (Request.IsAjaxRequest()) { return View("SubscriptionList", model); } else { return View("Index", model); } }If anyone has a cleaner solution to fix this, suggestions are still welcome :-)
Regards,
Koen
ryanw51
Contributor
2363 Points
511 Posts
Re: mvc 3 webgrid filtering combined with sorting problem
Jan 31, 2011 03:36 PM|LINK
This is how I include searching in my grids:
Action:
public ActionResult Index(string search) { var employees = repository.GetEmployees(search); ViewData["filterval"] = search; return View(employees); }View:
<div id="top-menu"> <form id="search-form" action=""> <input type="text" name="Search" id="txtSearch" value="@ViewData["filterval"]" /> <input type="submit" value="Search" class="btnSearch" /> <input type="button" value="Clear" class="btnClear" /> </form> </div> <div id="grid"> @grid.GetHtml() </div>You're right about having to use a querystring. You should be able to clean up those calls to Request.QueryString by adding "search" as one of the parameters to your action.
I'm very curious to know what exactly that first function is accomplishing. "search" and "SearchFilter" are already being included in the querystring by the form submit...
denappel
Member
5 Points
8 Posts
Re: mvc 3 webgrid filtering combined with sorting problem
Feb 03, 2011 12:02 PM|LINK
When you click on a column header of the webgrid to sort on that column, an http-get is done (it's a link, the column header),
so the form is not submitted to the server, and the search is not persisted.
Therefor I put the search into the querystring.
But indeed you're right, I can name the parameter search instead of search filter, because it's basicly the same,
and then the querystring is mapped to that parameter directly. Sounds like a good idea :-)
Tnx & regards
ryanw51
Contributor
2363 Points
511 Posts
Re: mvc 3 webgrid filtering combined with sorting problem
Feb 03, 2011 12:40 PM|LINK
You'll find that if you turn ajax off, the querystring persists on sorts after you've filtered (the sort links won't clobber your search parameter) which is why I suggested not using it to begin with. Doing it that way means you have to maintain the state of the rest of the page through a ViewModel or ViewData. The way you do it depends on what will be more convenient for you.
FThomas04
Member
2 Points
1 Post
Re: mvc 3 webgrid filtering combined with sorting problem
Dec 11, 2012 05:25 PM|LINK
Try adding the following script to the top of your code between the @{ }:
<script type="text/javascript">
$(function(){
$('th a, tfoot a').live('click', function() {
$('form').attr('action', $(this).attr('href')).submit();
return false;
});
});
</script>
I pulled this from "http://www.mikesdotnetting.com/Article/180/Displaying-Search-Results-In-A-WebGrid" and it worked for my application.