jqGrid postData.filters is undefined

2019-08-29 15:12发布

问题:

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>

回答1:

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
    });
});