4

I'm trying to get a JqGrid to do some client-side filtering (and sorting) just after it has finished loading in the data. I can set the search-field correctly, but calling TriggerToolbar() doesn't seem to have any effect.

$("#list").GridUnload();
        var mygrid = $("#list").jqGrid({
            url: '@Url.Action("GetSearchCriteriaWithNoComponents", "SearchCriteria")',
            postData: { BookingSiteId: function () { return $("#BookingSiteId option:selected").val(); }, MethodId: function () { return $("#MethodId option:selected").val(); } },
            datatype: 'json',
            mtype: 'Post',
            colNames: ['Id', 'PID', 'Ori', 'Dest', 'Conn', 'Pos', 'Method', 'Billing', 'Filter', 'Pattern', 'Class', 'Wildcard', 'Components', 'Comment'],
            colModel: [
          { name: 'Id', index: 'Id', width: 30, hidden: true },
          { name: 'PID', index: 'PID', width: 35 },
          { name: 'Ori', index: 'Ori', width: 35 },
          { name: 'Dest', index: 'Dest', width: 35 },
          { name: 'Conn', index: 'Conn', width: 35 },
          { name: 'Pos', index: 'Pos', width: 35 },
          { name: 'Method', index: 'Method', width: 50 },
          { name: 'Billing', index: 'Billing', width: 45, search: true, stype: 'text', searchoptions: { sopt: ['cn']} },
          { name: 'Filter', index: 'Filter', width: 90, search: true, stype: 'text', searchoptions: { sopt: ['cn']} },
          { name: 'Pattern', index: 'Pattern', width: 100, search: true, stype: 'text', searchoptions: { sopt: ['cn']} },
          { name: 'Class', index: 'Class', width: 40 },
          { name: 'Wildcard', index: 'Wildcard', width: 50 },
          { name: 'Components', index: 'Components', width: 80, search: true, stype: 'text', searchoptions: { sopt: ['cn']} },
          { name: 'Comment', index: 'Comment', width: 75, search: true, stype: 'text', searchoptions: { sopt: ['cn']} }
          ],
            pager: '#pager',
            rowNum: 25,
            rowTotal: 1000,
            rowList: [25, 50, 100],
            sortname: 'Origin',
            sortorder: "asc",
            viewrecords: true,
            loadonce: true,
            multiselect: true,
            ignoreCase: true,
            gridview: true,
            height: "100%",
            caption: 'Subscribed Search Criteria without Components'
        }).jqGrid('navGrid', '#pager', { add: false, edit: false, del: false, search: false, refresh: false }
         ).jqGrid('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-search", onClickButton: function () { mygrid[0].toggleToolbar() }, position: "first", title: "Toggle Search Toolbar", cursor: "pointer" })
          .jqGrid('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-refresh", onClickButton: function () { mygrid[0].clearToolbar() }, title: "Clear Search Toolbar", cursor: "pointer" }
        );

        $("#list").jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false });

        if(firstrun = true)
        {
            $("#gs_PID").val('AA');
            mygrid[0].triggerToolbar();
            firstrun = false;
        }
        else
        {
            mygrid[0].toggleToolbar(); //hide the toolbar by default
        }

The general idea is that the fixed value will be populated with something from the viewmodel.

We would also like to have the option of saving and restoring filter and sorting selection for when we do gridUnload() and subsequent reloads, but one hurdle at a time. stuff with @prefixes such as @Url.Action is Razor markup, which is handled before the page is sent to the browser.

Grubsnik
  • 918
  • 9
  • 25

1 Answers1

6

You use datatype: 'json' in combination with loadonce: true. So you should call mygrid[0].triggerToolbar() inside of the loadComplete event handle. Only after the data are loaded you should filter the data. Probably you should place the code with triggerToolbar inside of setTimeout method to start the filtering already after the datatype will be changed to 'local' during loadonce: true. So the code of your loadComplete event handle could be about the following:

loadComplete: function () {
    var gridDOM = this; // save $("#list")[0] in a variable
    if ($(this).jqGrid('getGridParam', 'datatype') === 'json') {
        // the first load from the server
        setTimeout(function () {
            $("#gs_PID").val('AA');
            gridDOM.triggerToolbar();
        }, 100);
    }
}

Additionally I don't full understand how you use the code fragment which you posted and why you need to use gridUnload method.

UPDATED: Free jqGrid fork of jqGrid supports forceClientSorting: true option, which force sorting and optional filtering of the data, returned from the server, before displaying the first page of data. It makes unneeded the above code. Instead of that one can set postData.filters use

forceClientSorting: true,
search: true,
postData: {
    filters: {
        groupOp: "AND",
        rules: [
            { op: "le", field: "PID", data: "AA" }
        ]
    }
}

see the demo.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Works like a charm, the gridUnload() call is not really related, but it because the problematic code was part of a bigger function call. – Grubsnik Oct 10 '11 at 09:40
  • @Oleg - why do you need a setTimeout if the loadComplete function only fires once the grid is finished loading? – froadie Nov 30 '15 at 08:35
  • @froadie: `loadComplete` will be called during reloading the grid. `datatype: "json"` will be changed to `datatype: "local"` **at the end to loading** after the processing of `loadComplete`. The usage of `setTimeout` allows to finish the first processing of `loadComplete` till the end and *then* call `triggerToolbar()`. It's important to understand that `triggerToolbar()` works synchronousle and calls `.trigger("reloadGrid")` also synchronously. Thus calling of `triggerToolbar()` in `loadComplete` will process reloadGrid with `datatype: "json"` and **before** finishing the first `loadComplete` – Oleg Nov 30 '15 at 08:43
  • @froadie: Instead of setting `$("#gs_PID").val('AA')` I would recommend better to set `postData.filters` to the required filter, set `search: true` option of the grid and trigger reloadGrid (all inside of `setTimeout` of cause). See [the old answer](http://stackoverflow.com/a/5750127/315935) – Oleg Nov 30 '15 at 08:45