Search Forms

The search or filter function of jqGrid is a great idea, but I want to have my search form appear above my table, all the time, as a reminder of or quick reference to what has been selected, rather than appearing only when the search button on the navigation bar is clicked.

Let's start at the very beginning. In your html, add a div where you want the search form to appear (in this example it has the id of "srccontents" and appears above the jqGrid table marker).

<div id="srccontents"></div> <table id="tblcontents" class="scroll"></table> <div id="tblcontentsPager" class="scroll" style="text-align:right;"></div>

Next, for a very simple search/filter form, add to the definition of your jqGrid the following:

$("#srccontents").filterGrid("tblcontents",{ gridModel:true, gridNames:true, formtype:"vertical", enableSearch: false, enableClear: false, autosearch: true });

And jqGrid takes it from there. Every column that is visible in the grid will now appear in the search form above your table, something like this (it helps to imagine that this table contains far more entries than it really does, some number large enough to need filtering to see, for example, only the Divisions for a particular Branch):

That's all very nice, but I don't want to search on every column; the division name, for instance, is unique and easily found simply scrolling through the grid.

You can easily exclude any column from the search form by adding search:false in your definition of that column in the grid, as shown here:

colModel: [{name:'division', search:false, editable:true, editoptions:{size:'50', maxlength:'25'}, width:250 },

Note that the syntax is slightly different from other similar options: it is editable and sortable, but search, not searchable.

Cool. But it really would be better to have default search conditions applied when the page first appears, e.g. I want to see only those divisions that are Active because those are the ones the operator is most likely to want to work with.

This example shows the same table as above (with the search on Division name removed), and with the Active search option selected so that only the active entries are included in the table. Again, imagine that there are many more that are no longer active, and while we have to keep them in the data (so that older entries in other tables are not orphaned), we hardly ever want to access them again. So, when we come to this page, we want to see only the Active divisions, with an option to see all should we need to.

There are three steps to take to achieve this situation:

  1. set the datatype of the table to 'local' when first defined, so that it does not retrieve any data,
  2. set the default values you want applied when the page first appears (you may have to scroll to the far right to see this: defval:'Yes' on the Active line), and
  3. after the grid has been created, change the datatype back to 'xml' (or whatever you wish to use to retrieve the data) and trigger a search

For example:

$("#tblcontents").jqGrid( { url: 'your url for retrieving data', datatype: 'local', colNames: ['Division','Section','Head','Active','Active','Default','Default'], colModel: [{name:'division', search:false, editable:true, editoptions:{size:'50', maxlength:'25'}, width:250 }, {name:'branch', sortable:false, editable:true, edittype:'select', editoptions:{value:' :;1:Head Office;2:International Office;4:Northwest Region;3:Regional Office;5:SouthEast Region'}, width:125 }, {name:'head', sortable:false, editable:true, edittype:'select', editoptions:{value:' :;14:Bleu, Elizabeth;17:Alderson, Bernard;20:Bakerson, Cathy;27:Catterson, Harrold;39:Davidson, John; ... and many more'}, width:125 }, {name:'active', align:'center', hidden:true, sortable:false, editable:true, edittype:'select', editoptions:{value:'Yes:Yes;No:No'}, editrules:{edithidden:true, searchhidden:true}, defval:'Yes', width:80 }, {name:'activeimage', align:'center', sortable:false, search:false, editable:false, width:80 }, {name:'default', align:'center', hidden:true, sortable:false, editable:true, edittype:'select', editoptions:{value:'Yes:Yes;No:No'}, editrules:{edithidden:true, searchhidden:true}, width:80 }, {name:'defaultimage', align:'center', sortable:false, search:false, editable:false, width:80 }], height: 'auto', pager: $('#tblcontentsPager'), rowNum:10, rowList:[10,25,50,100,999], page: 1, sortname: 'Division', sortorder: 'asc', viewrecords: true, imgpath: '../scripts/jqGrid/themes/basic/images', hidegrid: false, caption: 'Divisions', editurl:editurl, loadError: function(xhr,st,err) { $("#tblcontentsMessage").html("Type: "+st+"; Response: "+ xhr.status + " "+xhr.statusText); }, ondblClickRow: function(rowid) { $("#tblcontents").editGridRow(rowid,editprm);} }); $("#srccontents").filterGrid("tblcontents",{ gridModel:true, gridNames:true, formtype:"vertical", enableSearch: false, enableClear: false, autosearch: false }); $("#tblcontents").setGridParam({datatype:'xml'}); var ts = $('#srccontents')[0]; ts.triggerSearch()

That's very nice, but… I have to have different options in the Search form than in the Edit form. For example, an item in the table is either Active or it is not; there is no valid option of 'not specified' or 'unknown', so for the Edit form the options for the Active drop-down include only 'Yes' and 'No'. But in the Search form, it is quite possible that I want to see all items regardless of whether they are active or not, so I also need to provide for 'All'.

For this, we need to provide two different lists of options: one for the Edit form and one for the Search form. The Edit form list of options is already defined within the colModel; for the Search form options we use another feature of the colModel: surl -- search url. (Scroll to the right in the following example, again on the Active line.)

colNames: ['Division','Branch','Head','Active','Active','Default','Default'], colModel [... {name:'active', align:'center', hidden:true, editable:true, edittype:'select', editoptions:{value:'Yes:Yes;No:No'}, editrules:{edithidden:true, searchhidden:true}, defval:'Yes', surl: activeurl, width:80 }, {name:'activeimage', align:'center', sortable:false, search:false, editable:false, width:80 }, {name:'default', align:'center', hidden:true, editable:true, edittype:'select', editoptions:{value:'Yes:Yes;No:No'}, editrules:{edithidden:true, searchhidden:true}, surl: activeurl, width:80 }, {name:'defaultimage', align:'center', sortable:false, search:false, editable:false, width:80 }],

where activeurl has been defined somewhere in your javascript as in the following example:

var activeurl = 'AjaxSearch~&amp;Field=Active';

In the following snippet, the three options (blank, Yes and No) make up the dropdown for Active (they overlap the Default dropdown):

It really would be useful to be able to search on Branch and Division Head as well. But as I may want to set combinations of search criteria, I don't want the search to happen automatically as soon as I change one of them. Plus, I'll want to undo any search criteria and return to the default easily.

That change is easily accommodated. In your search form definition, set enableSearch and enableClear to 'true', and set autosearch to 'false', as shown here:

$("#srccontents").filterGrid("tblcontents",{ gridModel:true, gridNames:true, formtype:"vertical", enableSearch: true, enableClear: true, autosearch: false });

With this, you now get buttons to start the search or to clear (actually, return to the default settings) and nothing happens until a button is clicked.




  Last Updated: 3/2/2009 | © Tony's jqGrid - a jQuery Plugin, 2010