Stephanie
Stephanie

Reputation: 55

jqGrid custom formatter and toolbar filtering

Similar questions to this have been asked here before but I haven't had any success using those answers in my scenario.

I have a grid with datatype: 'local', and loadonce: true. In 3 of my columns I use a custom formatter.

The first one takes a timestamp in milliseconds and displays a time in the form of "H:MM am" (eg, 8:35 am, 12:19 pm). I'll omit that code as I'm sure it's not relevant.

The second customer formatter takes an integer and returns a string indicating which days of the week the number represents. It uses bitwise operations where 1 is Sunday, 2 is Monday, 4 is Tuesday, 8 is Wed, etc. So the number 67 represents Sunday, Monday, and Saturday (1+2+64), so the formatter returns "SMSa"

function daysOfWeekFormatter(daysMask, options, rowObject) {
  var days='';

  if ((daysMask & 1) != 0)    days+="S";
  if ((daysMask & 2) != 0)    days+="M";
  if ((daysMask & 4) != 0)    days+="T";
  if ((daysMask & 8) != 0)    days+="W";
  if ((daysMask & 16) != 0)   days+="Th";
  if ((daysMask & 32) != 0)   days+="F";
  if ((daysMask & 64) != 0)   days+="Sa";
  return days;
}

The third custom formatter is very simple, it just returns a string is a boolean is false, and nothing if it's true:

function closedFormatter(isOpen, options, rowObject) {
  return isOpen ? '' : 'Closed';
}

Here is my jqgrid call.

$("#jqgrid").jqGrid({
    colModel: [
                { name: 'timeField', label: 'Time', index: 'timeField', width: 100, formatter: timeFormatter},
                { name: 'daysOfWeek', label: 'Days of the Week', formatter: daysOfWeekFormatter},
                { name: 'openClosed', label: 'CLOSED', formatter: closedFormatter}
            ],
   datatype: 'local',
    loadonce: true, 
   scrollOffset: 0,
   viewrecords: false,
   rowNum: -1
});

$("#jqgrid").jqGrid("filterToolbar", {stringResult: true, searchOnEnter: false, defaultSearch: "cn"});

In the column filters, I want users to be able to just type what they see in the table and get those filtered. For example, if they type "F" in the days of week, they see all the rows including F. "S" would yield the saturday and sunday rows.

Any ideas how this can be done? I'd like to write a function that gets called for every row with the typed in filter and I can return true or false. Does jqgrid provide anything like this? Thanks!

Upvotes: 1

Views: 2177

Answers (1)

Oleg
Oleg

Reputation: 221997

I find the question absolutely correct. It's important for correctly understanding of custom formatters. First of all I'd recommend you to define always unformatter (unformat callback in the colModel) always if you define custom formatter (formatter callback in the colModel). The unformater will still help only for editing the data, but not for searching/filtering.

The solution of your problem depends on the jqGrid version, which you use and from the fork of jqGrid (free jqGrid, commercial Guriddo jqGrid JS or an old jqGrid in version <=4.7). I develop free jqGrid fork and have implemented custom filtering searching operation, which can be used to solve the problem. The wiki article described the possibility more detailed.

To understand correctly the problem one have to understand that the data will be hold locally in the same form like in the data parameter. The formatter helps only to display the data as some another visual representation in the cells of the grid. The searching/filtering of data use local data and compare it with the input data, which the user wrote in the filter toolbar. You didn't used searchOperators: true option of filterToolbar. Thus only one operation will be used for searching/filtering in every column. The searching operation will be used either from the first element from sopt array of the searchoptions or from defaultSearch option of filterToolbar is no searchoptions.sopt is specified (like in your case). Your current code will apply cn operation with the value from the filter and the local data in the column. It will work incorrectly in your case.

Which ways one have to implement correct filtering operation? The most easy and direct way would be the usage of custom filtering searching operation. You can find the corresponding examples in the answer, the answer and this one. In general you can just define one - tree custom operation and provide your callback function which will be called if jqGrid will need to filter by the field. For example you can use defaultSearch: "myFilter" option of filterToolbar instead of defaultSearch: "cn". Additionally ou should include the option customSortOperations to jqGrid in the form:

customSortOperations: {
    myFilter: {
        operand: "myFilter",
        text: "my filter",
        filter: function (options) {
            // the callback function should return true if the item of data corresponds
            // the searchValue, which the user entered in the filter toolbar

            // options.cmName is the column name ("timeField", "daysOfWeek"
            // or "openClosed")
            // options.item represent the item of data (options.item.daysOfWeek, ...) 
            // options.searchValue is the value from the filter toolbar

            // you can just format options.item[options.cmName] using
            // the corresponding formater and compare it with options.searchValue
            // if the values are the same then the callback should return true
        }
    }
}

Alternatively one can use beforeSearch callback of filterToolbar (see the answer) to modify the postData.filters. For example you can use defaultSearch: "eq" option of filterToolbar and "unformat" the data properties of the rules of the filters.

Upvotes: 2

Related Questions