0

I have a requirement to customize jqGrid. But postData.Filters is undefined. As I am new to jquery and javascript I am unable to find out what exactly is the issue, even after a day of efforts.

I am using the below javascript.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.24/themes/redmond/jquery-ui.css" />
    <link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.4.1/css/ui.jqgrid.css" />
    <link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery-ui-multiselect/1.13.6/jquery.multiselect.css" />

    <style type="text/css">
        html, body {
            font-size: 75%;
        }

        .ui-multiselect-menu {
            font-size: 1.2em;
        }

        .ui-jqgrid .ui-jqgrid-htable .ui-search-toolbar th {
            height: auto;
        }
    </style>

    <script src="js/jquery-1.11.0.min.js"></script>
    <script src="js/jquery.jqGrid.min.js"></script>
    <script src="js/jquery.jqGrid.src.js"></script>
    <script src="js/i18n/grid.locale-en.js"></script>

    <script type="text/javascript">
        $.jgrid.no_legacy_api = true;
        $.jgrid.useJSON = true;
    </script>

    <script type="text/javascript">
        $(function () {
            'use strict';

            var jsonData = {
                "Employees": [
                            {
                                "Emp ID": 1.0,
                                "Name": "Anubhav",
                                "Gender": "Male",
                                "Department": "DEVELOPMENT",
                                "Company": "SOPRA",
                                "Salary": 100000
                            },
                            {
                                "Emp ID": 2.0,
                                "Name": "Shailesh",
                                "Gender": "Male",
                                "Department": "DEVELOPMENT",
                                "Company": "SOPRA",
                                "Salary": 10000
                            },
                            {
                                "Emp ID": 3.0,
                                "Name": "Deepak",
                                "Gender": "Male",
                                "Department": "SALES",
                                "Company": "ROQUETTE",
                                "Salary": 20000
                            },
                            {
                                "Emp ID": 4.0,
                                "Name": "Seema",
                                "Gender": "Female",
                                "Department": "PURCHASE",
                                "Company": "ROQUETTE",
                                "Salary": 25000
                            }
                ]},

            $grid = $("#list2"),
            myDefaultSearch = 'cn',

            getColumnIndexByName = function (columnName) {
                var cm = $(this).jqGrid('getGridParam', 'colModel'), i, l = cm.length;
                for (i = 0; i < l; i += 1) {
                    if (cm[i].name === columnName) {
                        return i; // return the index
                    }
                }
                return -1;
            },
                modifySearchingFilter = function (separator) {                    
                    var i, l, rules, rule, parts, j, group, str, iCol, cmi, cm = this.p.colModel;
                    window.alert("Hello");
                    window.alert(this.p.postData.filters);
                    var filters = $.parseJSON(this.p.postData.filters);
                    window.alert("Hello 2");
                    if (filters && filters.rules !== undefined && filters.rules.length > 0) {
                        rules = filters.rules;
                        for (i = 0; i < rules.length; i++) {                            
                            rule = rules[i];
                            iCol = getColumnIndexByName.call(this, rule.field);
                            cmi = cm[iCol];                            
                            if (iCol >= 0 &&
                                    ((cmi.searchoptions === undefined || cmi.searchoptions.sopt === undefined)
                                        && (rule.op === myDefaultSearch)) ||
                                    (typeof (cmi.searchoptions) === "object" &&
                                        $.isArray(cmi.searchoptions.sopt) &&
                                        cmi.searchoptions.sopt[0] === rule.op)) {
                                // make modifications only for the 'contains' operation
                                parts = rule.data.split(separator);
                                if (parts.length > 1) {
                                    if (filters.groups === undefined) {
                                        filters.groups = [];
                                    }
                                    group = {
                                        groupOp: 'OR',
                                        groups: [],
                                        rules: []
                                    };
                                    filters.groups.push(group);
                                    for (j = 0, l = parts.length; j < l; j++) {
                                        str = parts[j];
                                        if (str) {
                                            // skip empty '', which exist in case of two separaters of once
                                            group.rules.push({
                                                data: parts[j],
                                                op: rule.op,
                                                field: rule.field
                                            });
                                        }
                                    }
                                    rules.splice(i, 1);                                   
                                    i--; // to skip i++
                                }
                            }
                        }
                        this.p.postData.filters = JSON.stringify(filters);
                    }
                },
                dataInitMultiselect = function (elem) {
                    setTimeout(function () {
                        var $elem = $(elem), id = elem.id,
                            inToolbar = typeof id === "string" && id.substr(0, 3) === "gs_",
                            options = {
                                selectedList: 2,
                                height: "auto",
                                checkAllText: "all",
                                uncheckAllText: "no",
                                noneSelectedText: "Any",
                                open: function () {
                                    var $menu = $(".ui-multiselect-menu:visible");
                                    $menu.width("auto");
                                    return;
                                }
                            },
                            $options = $elem.find("option");
                        if ($options.length > 0 && $options[0].selected) {
                            $options[0].selected = false; // unselect the first selected option
                        }
                        if (inToolbar) {
                            options.minWidth = 'auto';
                        }
                        $elem.multiselect(options);
                        $elem.siblings('button.ui-multiselect').css({
                            width: inToolbar ? "98%" : "100%",
                            marginTop: "1px",
                            marginBottom: "1px",
                            paddingTop: "3px"
                        });
                    }, 50);
                };

            $grid.jqGrid({
                datatype: "json",
                data: jsonData,
                colNames: ["Emp ID", "Name", "Department", "Company", "Salary"],
                colModel: [
                    { name: "Emp ID", sorttype: 'integer' },
                    { name: "Name" },
                    {
                        name: "Department", width: 100, align: 'center', formatter: 'select', edittype: 'select', stype: 'select',
                        editoptions: { value: 'DEVELOPMENT;SALES;PURCHASE', defaultValue: 'DEVELOPMENT', multiple: true },
                        searchoptions: { sopt:['eq', 'ne'], value: 'DEVELOPMENT;SALES;PURCHASE', attr: { multiple: 'multiple', size: 4 }, dataInit: dataInitMultiselect }
                    },
                    { name: "Company" },
                    { name: "Salary", sorttype: 'integer' }
                ],
                cmTemplate: { editable: false },
                rowNum: 10,
                mtype: "GET",                
                rowList: [10, 20, 100],
                pager: "#pager2",
                height: "auto",
                viewrecords: true,
                gridview: true,
                ignoreCase: true,
                rownumbers: true,
                cellEdit: true,
                cellsubmit: "clientArray",
                editurl: "clientArray",
                sortname: 'Emp ID',
                caption: "CDDI Sample Grid",
                beforeRequest: function () {                    
                   modifySearchingFilter.call(this, ',');
                }
            });
            $grid.jqGrid('filterToolbar', {search:true, searchOperators: true, stringResult: true, searchOnEnter: true, defaultSearch: 'cn' });            
            $grid.jqGrid('navGrid', '#pager2', { edit: false, add: false, del: false, search: true }, {}, {}, {}, {
                multipleSearch: true,
                multipleGroup: true,
                recreateFilter: true
            });
        });
    </script>

</head>
<body>
    <table id="list2"></table>
    <div id="pager2"></div>    
</body>
</html>
SmartDev
  • 3
  • 4

1 Answers1

0

I see that you use the code from my old answer.

The error "jqGrid postData.filters is undefined" undefined can be easy fixed by adding the lines

if (postData.filters == null) {
    return;
}

inside of modifySearchingFilter before the line var filters = $.parseJSON(postData.filters);.

Additional important error in your code is the usage of datatype: "json" instead of datatype: "local". The option datatype: "json" means that the data fro the grid will be loaded via Ajax request to the URL specified by url parameter.

One more error is the usage of data: jsonData instead of data: jsonData.Employees. It's important to understand that the value of data parameter have to be an array.

One more remark: I strictly recommend you to use no special characters in the name property of colModel (currently you have name: "Emp ID"). The value of name property will be used as id of some internal elements of the grid, but space will by used by jQuery and by CSS as delimiter and as meta-character (see here for example). So I would recommend you to change name: "Emp ID" to name: "EmpId" for example to have in the future less problems.

The fixed demo you will fined here. It uses the following code

$(function () {
    "use strict";
    var jsonData = {
            "Employees": [
                {
                    "EmpId": 1.0,
                    "Name": "Anubhav",
                    "Gender": "Male",
                    "Department": "DEVELOPMENT",
                    "Company": "SOPRA",
                    "Salary": 100000
                },
                {
                    "EmpId": 2.0,
                    "Name": "Shailesh",
                    "Gender": "Male",
                    "Department": "DEVELOPMENT",
                    "Company": "SOPRA",
                    "Salary": 10000
                },
                {
                    "EmpId": 3.0,
                    "Name": "Deepak",
                    "Gender": "Male",
                    "Department": "SALES",
                    "Company": "ROQUETTE",
                    "Salary": 20000
                },
                {
                    "EmpId": 4.0,
                    "Name": "Seema",
                    "Gender": "Female",
                    "Department": "PURCHASE",
                    "Company": "ROQUETTE",
                    "Salary": 25000
                }
            ]
        },
        $grid = $("#list2"),
        myDefaultSearch = "cn",
        getColumnIndexByName = function (columnName) {
            var cm = $(this).jqGrid("getGridParam", "colModel"), i, l = cm.length;
            for (i = 0; i < l; i += 1) {
                if (cm[i].name === columnName) {
                    return i; // return the index
                }
            }
            return -1;
        },
        modifySearchingFilter = function (separator) {
            var i, l, rules, rule, parts, j, group, str, iCol, cmi, filters,
                cm = $(this).jqGrid("getGridParam", "colModel"),
                postData = $(this).jqGrid("getGridParam", "postData");
            if (postData.filters == null) {
                return;
            }
            filters = $.parseJSON(postData.filters);
            if (filters && filters.rules !== undefined && filters.rules.length > 0) {
                rules = filters.rules;
                for (i = 0; i < rules.length; i++) {
                    rule = rules[i];
                    iCol = getColumnIndexByName.call(this, rule.field);
                    cmi = cm[iCol];
                    if (iCol >= 0 &&
                            (((cmi.searchoptions === undefined || cmi.searchoptions.sopt === undefined) &&
                                rule.op === myDefaultSearch) ||
                            (typeof (cmi.searchoptions) === "object" &&
                                $.isArray(cmi.searchoptions.sopt) &&
                                cmi.searchoptions.sopt.length > 0 &&
                                cmi.searchoptions.sopt[0] === rule.op))) {
                        // make modifications only for the "contains" operation
                        parts = rule.data.split(separator);
                        if (parts.length > 1) {
                            if (filters.groups === undefined) {
                                filters.groups = [];
                            }
                            group = {
                                groupOp: "OR",
                                groups: [],
                                rules: []
                            };
                            filters.groups.push(group);
                            for (j = 0, l = parts.length; j < l; j++) {
                                str = parts[j];
                                if (str) {
                                    // skip empty "", which exist in case of two separaters of once
                                    group.rules.push({
                                        data: parts[j],
                                        op: rule.op,
                                        field: rule.field
                                    });
                                }
                            }
                            rules.splice(i, 1);
                            i--; // to skip i++
                        }
                    }
                }
                postData.filters = JSON.stringify(filters);
            }
        },
        dataInitMultiselect = function (elem) {
            setTimeout(function () {
                var $elem = $(elem), id = elem.id,
                    inToolbar = typeof id === "string" && id.substr(0, 3) === "gs_",
                    options = {
                        selectedList: 2,
                        height: "auto",
                        checkAllText: "all",
                        uncheckAllText: "no",
                        noneSelectedText: "Any",
                        open: function () {
                            var $menu = $(".ui-multiselect-menu:visible");
                            $menu.width("auto");
                            return;
                        }
                    },
                    $options = $elem.find("option");
                if ($options.length > 0 && $options[0].selected) {
                    $options[0].selected = false; // unselect the first selected option
                }
                if (inToolbar) {
                    options.minWidth = "auto";
                }
                $elem.multiselect(options);
                $elem.siblings("button.ui-multiselect").css({
                    width: inToolbar ? "98%" : "100%",
                    marginTop: "1px",
                    marginBottom: "1px",
                    paddingTop: "3px"
                });
            }, 50);
        };

    $grid.jqGrid({
        datatype: "local",
        data: jsonData.Employees,
        colNames: ["Emp ID", "Name", "Department", "Company", "Salary"],
        colModel: [
            { name: "EmpId", sorttype: "integer", key: true },
            { name: "Name" },
            {
                name: "Department",
                width: 160,
                align: "center",
                edittype: "select",
                editoptions: {
                    value: "DEVELOPMENT:DEVELOPMENT;SALES:SALES;PURCHASE:PURCHASE",
                    defaultValue: "DEVELOPMENT",
                    multiple: true
                },
                stype: "select",
                searchoptions: {
                    sopt: ["eq", "ne"],
                    value: "DEVELOPMENT:DEVELOPMENT;SALES:SALES;PURCHASE:PURCHASE",
                    attr: { multiple: "multiple", size: 4 },
                    dataInit: dataInitMultiselect
                }
            },
            { name: "Company" },
            { name: "Salary", sorttype: "integer", formatter: "integer" }
        ],
        cmTemplate: { editable: false },
        rowNum: 10,
        rowList: [10, 20, 100],
        pager: "#pager2",
        height: "auto",
        viewrecords: true,
        gridview: true,
        ignoreCase: true,
        rownumbers: true,
        cellEdit: true,
        cellsubmit: "clientArray",
        editurl: "clientArray",
        sortname: "EmpId",
        caption: "CDDI Sample Grid",
        beforeRequest: function () {
            modifySearchingFilter.call(this, ",");
        }
    });
    $grid.jqGrid("filterToolbar", {
        searchOperators: true,
        stringResult: true,
        searchOnEnter: true,
        defaultSearch: myDefaultSearch
    });
    $grid.jqGrid("navGrid", "#pager2", { edit: false, add: false, del: false }, {}, {}, {}, {
        multipleSearch: true,
        multipleGroup: true,
        recreateFilter: true
    });
});
Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks for the answers Oleg. I found your solution fairly descriptive and helpful. Infact the additional comments that you have provided saved me another day. I really appreciate the support. Thanks. – SmartDev Aug 28 '14 at 13:46
  • @Oleg: I am using your code but the filter UI is not responding to close/all/none button clicks. jQuery.min and ui libs already included. Console complaints of r.easings is not a function. Any idea? – ujjwalesri Jan 07 '18 at 10:21
  • @ujjwalesri: Typically, the error in your code exists not where you expect. You can prepare the demo (in JSFiddle for example), which reproduce your problem and post new question with the demo and the detailed description of the problem. – Oleg Jan 07 '18 at 11:35
  • @ujjwalesri: By the way, the most parts of the code used in the answer are unneeded in [free jqGrid](https://github.com/free-jqgrid/jqGrid) fork of jqGrid, which I develop last years. It supports `sopt: ["in"]`. See https://jsfiddle.net/OlegKi/aa5b9wn7/6/. The demo could be simplified more because last versions support `createColumnIndex: true` and `generateValue: true` options. See https://jsfiddle.net/OlegKi/yvbt6w54/, which don't use multiselect, but use unique index which can be generated and supported by free jqGrid. – Oleg Jan 07 '18 at 11:43