jqgridfree-jqgridjqgrid-formatter

free jqgrid custom formatter lost after sorting or filtering


I am using free jqgrid 4.13.0

I wrote a custom formatter, but unfortunately my cell contents of that column are always lost after sorting the table or filtering. I am probably doing something wrong in the formatter function, but haven't really understood what is missing. Anyone can spot my mistake? Why is it working fine with the built in ones, but not with mine. I got inspired by this one: http://www.ok-soft-gmbh.com/jqGrid/CascadingFormater.htm

I can see how the example is calling $.fn.fmatter.call and maybe I need to do this too. Is this the key? Unfortunately I can't find any documentation on how to do this if I write the function myself.

This is my setup:

var formatEnduser = function (cellValue, options, rowObject, action){
    return rowObject.so_enduser_id == undefined ? '' : '<a href="index.php?module=Accounts&view=Detail&record='+rowObject.so_enduser_id+'">'+rowObject.so_enduser_name+'</a>';
}

$("#jqGrid").jqGrid({
    datatype: "jsonstring",
    datastr: jsonData,
    jsonReader: {
        root: 'rows',
        id: 'crmentity_id',
        repeatitems: false,
        page:  function(obj) { return 1; },
        total: function(obj) { return 1; },
        records: function(obj) { return obj.rows.length; },
    },
    autowidth: true,
    height: 600,
    shrinkToFit: true,
    rownumbers: true,
    rowNum: 5,
    pager: false,
    loadonce: true,
    viewrecords: true,
    colModel: [
        {
            name: 'crmentity_id',
            key: true,
            hidden: true
        },
        {
            label: 'Enduser',
            name: 'so_enduser_name',
            searchoptions: {
                sopt : ['cn']
            },
            formatter: formatEnduser
        },
    ]
});
$('#jqGrid').jqGrid('filterToolbar');

The object jsonData looks like this:

Object { rows=[623],  so_total_total=4321, in_total_total=1234 }

In the property rows can be found this:

[Object { crmentity_id="60199",  so_enduser_id="6808",  so_enduser_name="enduser123",  mehr...}, Object { crmentity_id="60136",  so_enduser_id="6362",  so_enduser_name="userend321",  mehr...}, 620 mehr...]

Thanks a lot for any help!

EDIT: I added a jsfiddle to demonstrate the problem, search for end in the filter and see how the data disappears. Sorting does the same. http://jsfiddle.net/tztj9yn7/2/


Solution

  • The main problem is your code is the following. You use datatype: "jsonstring" and the custom formatter uses the property so_enduser_id of the input data, but the property is not a column of the grid. The datatype "jsonstring" will be processed in the same way like the datatype "json" (or "jsonp" or "xml"). It will be read by jqGrid and saved locally only the columns from colModel and jsonReader.id additionally. Thus the property so_enduser_id of the input data will be available in rowObject only during initial reading of the grid. All what I wrote till now is the same for old jqGrid and for free jqGrid.

    In case of usage old jqGrid there are two alternative ways to fix the problem:

    If you would need to load the data directly from the URL then the second way (datatype: "local") will be not possible and the only way will be the usage of hidden columns for all properties which you need later.

    Free jqGrid provides you another very simple way: the usage of additionalProperties option. The idea of additionalProperties is very simple. One need sometimes to save some additional properties from every item of input data to use there locally later (because of usage of loadonce: true). Saving the data in DOM is much more expensive as saving the data in the JavaScript structures. One can just use the option like additionalProperties: ["crmentity_id", "so_enduser_id"] to inform free jqGrid to read some other properties and to save there locally. As the result your code will be fixed immediately: see http://jsfiddle.net/tztj9yn7/3/

    One more important recommendation about the usage of custom formatters in free jqGrid. There are exist some important problem with the rowObject parameter. It's just the input item exactly like it be in the source. Thus if you would use datatype: "xml" for example then the rowObject parameter would be XML node. In the same way, if you would use repeatitems: true format (["60199", "6808", "enduser123"] instead of {crmentity_id:"60199", so_enduser_id:"6808", so_enduser_name:"enduser123"}) then you will have to use rowObject[1] instead of rowObject.so_enduser_id to access the property so_enduser_id from initial input data. On the next sorting or filtering you will have another format of rowObject (rowObject.so_enduser_id) because of the input data will be the data from the local data parameter. Free jqGrid still use the same format of rowObject parameter to provides the best compatibility with the old versions of jqGrid, but it set additionally rowData property of the options parameter. The options.rowData have always deterministic named format of data and one can use always options.rowData.so_enduser_id independent from the format of the input data and the datatype used. Thus options.rowData is preferred way to access input data. One should't use the third parameter at all. The resulting code of the formatter will be

    var formatEnduser = function (cellValue, options) {
            var item = options.rowData;
    
            return item.so_enduser_id == undefined ?
                    '' :
                    '<a href="index.php?module=Accounts&view=Detail&record=' +
                        item.so_enduser_id + '">' + item.so_enduser_name + '</a>';
    };
    

    See http://jsfiddle.net/tztj9yn7/4/