2

I'm developing a web application using MVC 3 RTM. In a view I have a WebGrid which works fine with sorting and paging. However, I also needed some filtering support on the page, so I added a textbox and a checkbox. The view code looks like this:

@using (Html.BeginForm("Index", "Customer", FormMethod.Get))
{
    <fieldset>
        <legend>Filter</legend>
        <div class="display-label">
            Search for</div>
        <div class="display-field">@Html.TextBox("filter", null, new { onchange = "$('form').submit()" })</div>
        <div class="display-label">
            Show inactive customers?
        </div>
        <div class="display-field">
            @Html.CheckBox("showInactive", false, new { onchange = "$('form').submit()" })
        </div>
    </fieldset>

    var grid = new WebGrid(canPage: true, canSort: true, ajaxUpdateContainerId: "grid", rowsPerPage: 10, defaultSort: "Name");
    grid.Bind(Model, rowCount: Model.Count, autoSortAndPage: false);
    grid.Pager(WebGridPagerModes.All);
    @grid.GetHtml(htmlAttributes: new { id = "grid" },
                  columns: grid.Columns(
                    grid.Column("Name", "Name"),
                    grid.Column("Address", "Address"),
                    grid.Column("IsActive", "Active", (item) => item.IsActive ? "Yes" : "No")));

}

This works fine except when I check the checkbox. When I load the page for the first time, the checkbox is not checked. Sorting and paging works, and I can enter some text as a filter and it filters my result, and sorting and paging still works after that. However, if I check the checkbox, it updates the result, but sorting no longer works. The filter still works though, so if I enter some text, it correctly filters the result and still respects the checkbox.

I've tried setting a breakpoint in my controller, and there's no problem there. The request is sent when I try to sort, and the controller correctly returns the view with the result as the model. But it doesn't seem like the WebGrid is updating itself.

Has anyone else experienced this, or has anyone some good advice on what to look for?

Thanks!

René
  • 9,880
  • 4
  • 43
  • 49

1 Answers1

1

I normally add a form (above my WebGrid) which contains a textbox called "Keywords" and a checkbox called "IsActive" and when the "Go" button is clicked it reloads the WebGrid adding the "Keywords" and "IsActive" options to the query string.

You can add more elements to your form and their values will be sent al

Use the following helper script - webgrid.helper.js:

function reloadGrid(form) {
    var grid = form._grid ? form._grid.value : "grid";
    var args = {};
    updateQueryParams(args, grid + " th a");
    args.sort = "";
    args.sortdir = "";
    updateQueryParams(args, grid + " tfoot a");
    args.page = 1;

    for (var i = 0; i < form.elements.length; i++) {
        var el = form.elements[i];
        if (el.type == "text" || el.type == "select" || (el.type == "radio" && el.checked))
            args[el.name] = el.value;
        else if (el.type == "checkbox")
            args[el.name] = el.checked;
    }

    //get controller name
    var s = $("#grid th a")[0].onclick.toString();
    s = s.substring(s.indexOf("/"));
    var controller = s.substring(0, s.indexOf("?"));

    var queryString = "";
    for (var key in args)
        queryString += "&" + key + "=" + escape(args[key]);

    var url = controller + "?" + queryString.substring(1);
    $("#" + grid).load(url + " #" + grid);
}


function updateQueryParams(args, path) {
    var links = $("#" + path);
    if (links.length == 0)
        return;

    var s = links[0].onclick.toString();
    s = s.substring(s.indexOf("?") + 1);
    s = s.substring(0, s.indexOf(" #"));

    var a = /\+/g;  // Regex for replacing addition symbol with a space
    var r = /([^&=]+)=?([^&]*)/g;
    var d = function (s) { return decodeURIComponent(s.replace(a, " ")); };
    var q = s;

    while (e = r.exec(q))
        args[d(e[1])] = d(e[2]);
}

Then just above my webgrid, I have the following partial file - *_ListFilter.cshtml*

@using (Html.BeginForm(null, null, FormMethod.Get))
{ 
    <div id="filter">
    <table width="600">
    <tr>
    <td>@Html.TextBoxFor(c => c.Keywords, new { size = 50, placeholder = Strings.SearchByKeywords, title = Strings.SearchByKeywords })</td>

    <td>&nbsp
Tawani
  • 11,067
  • 20
  • 82
  • 106
  • @Gunder: My answer keeps getting rejected by the server – Tawani Mar 24 '11 at 14:24
  • 1
    Thank you for your answer @Tawani. I have to be honest with you and say that I haven't tried your posted code, so I don't know if it would solve the issue I had with the WebGrid. But I'm sure it was me who had made an error somewhere, so I'm accepting your answer as it's a nice example of how to post extra parameters, which is what I wanted. However, I decided to abandon the WebGrid as it made a request for the whole page and not just the data for the grid. I switched to jqGrid instead. It supports extra parameters without any problems, and I haven't looked back since. – René Apr 03 '11 at 22:34