5

Okay, so in a nutshell, what I need to do is to automatically apply a set of sorting criteria and data filters to the jqGrid when it loads. The intent is that the user will start with about 10 pre-filled filters and then, if they so choose, they can alter those filters or the sorting however they see fit.

So far, with much Google-ing, trial and error and sweat, I have the following working:

-> I can load/save the sort column & sort order in a session cookie.

-> I can load the search dialog with pre-defined search filters. After the grid loads, I can open the modal dialog and see the proper filters and if I click "Find" the appropriate data is posted to the server and the right results are returned to the screen.

The thing that is biting me in the butt right now is, I think, the easy part, but it escapes me. I can't seem to do either of the following:

( A ) The ideal thing would be if I could attach these filters to the grid and it's post data in advance of the initial load so that there is only a single trip to the server.

( B ) The workable solution, though less ideal, would be for the grid to load the first page of the unfiltered data first, and then apply the filters and re-query the server for the filtered data.

Since I can manually click the "find" button today and it works, I thought that "B" would be a good next-step. So, in my gridComplete function, I have the following code:

    $('#AccountGrid').clearFilter({gridName:'AccountGrid', pagerName:'AccountPager'});
    $('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:1, op:'ne'});
    $('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:3, op:'ne'});
    // $('#fbox_AccountGrid').searchFilter().search();
    // $('#fbox_AccountGrid .ui-search').click();
    $('#AccountGrid').trigger('reloadGrid');

NOTE: "clearFilter" and "addFilter" are extension functions I have added to jqGrid to simplify adding and removing filters on the grid.  They work exactly as desired at this point.

As you can see with those last three lines of code, I have tried using the built-in function, as well as going after the find button directly and even just forcing the entire grid to refresh.  Either way, there is no attempt by the grid to go get new data (I am using Fiddler to watch for it).

What am I doing wrong in trying to force the grid to reload with the new filters?

And, if you know how, can you give me some direction on how to get the initial load of the grid to respect these filters?

TIA

Tony


Here is the full grid configuration (minus the extra columns and some colModel "cruft"):


    jQuery('#AccountGrid').jqGrid({
        url: '<my URL>',
        width: 950,
        height: 330,
        shrinkToFit: 'true',
        datatype: 'json',
        mtype: 'POST',
        multiselect: true,
        multiboxonly: true,
        multiselectWidth: 20,
        colNames: [
            'Account ID'
        ],
        colModel: [
            { name: 'AccountID', index: 'AccountID', sortable: false, hidden:false, search:true }
        ],
        gridComplete: function () {
            // add the search criteria to the grid
            if (initialLoad == true){
                $('#AccountGrid').clearFilter({gridName:'AccountGrid', pagerName:'AccountPager'});
                $('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:1, op:'ne'});
                $('#AccountGrid').addFilter({gridName:'AccountGrid', field:'AccountID', data:3, op:'ne'});
                // $('#fbox_AccountGrid').searchFilter().search();
                // $('#fbox_AccountGrid .ui-search').click();
                $('#AccountGrid').trigger('reloadGrid');
                initialLoad = false;
            }
        },
        jsonReader: {
            repeatitems: false,
            id: 'AccountID'
        },
        pager: jQuery('#AccountPager'),
        rowNum: 50,
        rowList: [10, 15, 25, 50, 75, 100],
        onSortCol : function (sortname, indexColumn, sortorder){
            $.cookie('AccountGrid_sortname', sortname);
            $.cookie('AccountGrid_sortorder'  , sortorder);
        },
        sortname : $.cookie('AccountGrid_sortname') ? $.cookie('AccountGrid_sortname') : 'AccountID',
        sortorder: $.cookie('AccountGrid_sortorder') ? $.cookie('AccountGrid_sortorder') : 'asc',
        viewrecords: true,
        imgpath: ''
    });

    $('#AccountGrid').jqGrid('navGrid','#AccountPager', 
        { view: false, add: false, edit: true, del: false,
          alertcap:'No Account Selected',
          alerttext: 'Please select an Account from the grid before performing this operation.',
          editfunc: showAccountEditDialog },
        {}, // default settings for edit
        {}, // default settings for add
        {}, // delete
        {closeOnEscape: true, multipleSearch: true, closeAfterSearch: true }, // search options
        {}
    );

And, by request, here is the code I have for add/clear filter:

/*
    This is a grid extension function that will insert a new filter criteria
    on the specified grid with the provided field, operation & data values
*/
(function ($) {
    jQuery.jgrid.addSearchFilter =
    {
        // get/set the parameters
        addFilter: function (options) {
            var grid = $(this);
            // get offset values or assign defaults
            var settings = $.extend({
                gridName: '',
                field: '',
                data: '',
                op: ''
            }, options || {});
            // get the column model object from the grid that matches the provided name
            var colModel = grid.getGridParam('colModel');
            var column;
            for (var i = 0; i < colModel.length; i++) {
                if (colModel[i].name == options.field){
                    column = colModel[i];
                    break;
                }
            }
            colModel = null;
            if (column){
                // if the last filter has a value, we need to create a new one and not overwrite the existing ones
                if ($('#fbox_' + options.gridName + ' .sf .data input').last().val()){
                    $('#fbox_' + options.gridName).searchFilter().add();
                }
                // assign the selections to the search dialog
                $('#fbox_' + options.gridName + ' .sf .fields select.field').last().val(column.index).change();
                $('#fbox_' + options.gridName + ' .sf .data input').last().val(options.data);
                $('#fbox_' + options.gridName + ' .sf .ops select.default').last().val(options.op).change();
            }
        }
    }
})(jQuery);
jQuery.fn.extend({ addFilter: jQuery.jgrid.addSearchFilter.addFilter });

/*
    This is a grid extension function that will clear & reset the filter criteria
*/
(function ($) {
    jQuery.jgrid.clearSearchFilter =
    {
        // get/set the parameters
        clearFilter: function (options) {
            var grid = $(this);
            // get offset values or assign defaults
            var settings = $.extend({
                gridName: '',
                pagerName: ''
            }, options || {});
            // clear the filters and "pop" the dialog to force the HTML rendering
            $('#fbox_' + options.gridName).searchFilter().reset();
            $('#' + options.pagerName + ' .ui-icon-search').click();
            $('#fbox_' + options.gridName).searchFilter().close();
        }
    }
})(jQuery);
jQuery.fn.extend({ clearFilter: jQuery.jgrid.clearSearchFilter.clearFilter });
Tony
  • 55
  • 1
  • 8

1 Answers1

4

First of all because you don't post the code which define the jqGrid I make some assumption myself. I try to base on indirect information from your question.

1) I suppose that you use server side datatype parameter of jqGrid like 'json' or 'xml'. 2) You don't use loadonce:true parameter. In general if would be possible to make server reload from the grid having loadonce:true, but in the case you have to reset the value of datatype parameter to initial value (one from the value 'json' or 'xml').

The following three old answer: this (in case of single value searching) and this (in case of advanced searching or the toolbar searching with additional parameter stringResult:true) will give you enough information about setting the searching filters and reloading the grid corresponds to the new filters. Another answer shows how to clear the searching filter if it is no more needed.

Loading of the grid at the first time with the filters is another question. It can be very easy implemented. You should just use datatype:"local" instead of datatype:"json" or datatype:"xml" which you really need. In the case the url parameter of jqGrid will be just ignored at the first load and jqGrid send no request to the server. Then you set the filters like you as need and only then use $("#youGridId").trigger("reloadGrid");

The reason why the reloadGrid didn't work in your case I could not know exactly, but I suppose that you didn't set the search:true parameter of the jqGrid which one confuses frequently with the _search property of the postData parameter (see here).

Community
  • 1
  • 1
Oleg
  • 217,934
  • 30
  • 386
  • 757
  • Thanks, Oleg. I have added the grid definition. Originally I had omitted it because the actual functionality of defining and assigning the search filters was working fine and if you click the "find" button manually, they work as expected, so I presumed from that information that my grid was configured correctly. But you are right, I should have included it regardless. – Tony Feb 10 '11 at 12:20
  • Some of the links you provided, I had seen, and some I had not. As I look at them, however, they focus on how to get the search working. That part, the hard part, I have done already. It just the reloading of the grid and/or the pre-loading of the search criteria that I haven't been able to nail down. Your suggestion of setting the data type, then the filters and the resetting the data type is interesting. I'll give that a try this morning. – Tony Feb 10 '11 at 12:22
  • I tried your suggestion of setting the datatype to "local" first, and then applying the filters and resetting datatype to "json" and then calling reload grid. The first problem is that the filters don't get applied to the grid when the grid is in that mode. I haven't checked yet, but either you can't apply the filters when datatype is "local" or changing the datatype clears the filters. Regardless, the second problem is that when I use Fiddler to watch the browser requests, the grid never calls back to the server for data, even after setting the datatype to json and reloading the grid. – Tony Feb 10 '11 at 12:51
  • I ran out of room in the previous comment and wanted to add that I did include a new $('#AccountGrid').setGridParam({search: true}); before doing the reload grid, as you had suggested. – Tony Feb 10 '11 at 12:57
  • @Tony: Do use set `datatype:'json'` back before the reloading? It is required to send the request to the server. If all this together not solve the problem you have probably an error in the `clearFilter` or `addFilter`. Try to use directly about the following `$.extend(grid[0].p.postData,{filters:JSON.stringify(f)});` where you construct `f` like in the `$(".myFilfer").change` function of the example http://www.ok-soft-gmbh.com/jqGrid/CheckboxesWithVerticalHeaders1.htm. You can also append the text of your question with the code of `clearFilter` or `addFilter`. – Oleg Feb 10 '11 at 14:27
  • @Oleg: I added the clear/add filter code as you requested. Yes, I am setting the datatype to json beofre calling the refresh grid. What I have found so far is that my code for clearing/adding the filters works when I load the grid with datatype json initially, which is leading me to think that I can only set filters after the grid has been loaded with data. If I try to use the datatype as local, set the filters, reset the datatype as json and then refresh the grid, the filters are not set and the grid never goes back to the server for its data. – Tony Feb 10 '11 at 14:40
  • @Tony: Sorry, but I do't understand your code of `addFilter`. Why you get any information from `'#fbox_'` which can not exist? Just try to use `postData` only like I do in my examples. – Oleg Feb 10 '11 at 14:56
  • @Oleg: I appreciate your help, Oleg, but I can't you the method in your example unles it integrates with and uses the advanced search/filter pop-up box correctly, which your example does not appear to do. I need my users to be able to use the filter box exactly as they do today on all of their grid screens, the only difference is that on one screen, I want the grid to load with a pre-set group of filters, which they can then modify as they like. I have all the code working perfectly for clearing & setting the filters and when you click "find" the post data is sent to the server. – Tony Feb 10 '11 at 15:05
  • [continued] I just need a way to be able to trigger the grid refresh so that the added filteres are applied to the grid data - ideally before the initial load, but a second load is also acceptable, though less desireable. – Tony Feb 10 '11 at 15:06
  • @Tony: You misunderstand how the search filter are build. The `filters` property of the `postData` parameter and the `search:true` parameter are **all what you need**. Look at the demo from my other answer http://stackoverflow.com/questions/3981874/multiple-search-with-multiplefields-by-default/3981986#3981986. You will see that the setting of the `postData.filters` follows to predefined filters from the advanced search dialog. Just try what I recommend you and you will see that it will work. – Oleg Feb 10 '11 at 16:50
  • @Oleg: Ah ha! I see now. The example you refered to before, with the externally displayed check boxes, is the one I tried and saw that it didn't update the advanced search box, so I stopped digging. The postData example you mentioned above works like a champ! Now I just need to get the grid to use that post data before it goes to get it's initial json data. Thanks for sticking with this, Oleg. I was being stupid. – Tony Feb 11 '11 at 13:00
  • Which, of course, is that you were saying about "search: true" ... Excellent! it's working. And I can store the initial filters in the DB so that they can be altered by the users. Thanks, Oleg! – Tony Feb 11 '11 at 13:03
  • @Tony: I wrote one more answer http://stackoverflow.com/questions/4973361/how-can-i-preserve-the-search-filters-in-jqgrid-on-page-reload/4977896#4977896 about the same subject as we discussed before. If you have yet some opened questions the reading of the answer could probably help you. – Oleg Feb 12 '11 at 11:58