【问题标题】:free-jqGrid 4.13.4 multiselect toolbar filter not workingfree-jqGrid 4.13.4 多选工具栏过滤器不起作用
【发布时间】:2016-10-25 02:30:18
【问题描述】:

我查看了所有关于 jqGrid 过滤器工具栏中多选小部件使用的问答。我注意到在几乎所有的解决方案中,jqGrid 版本和 jquery 版本都不是当前的。我正在使用 jqGrid (4.13.4) 和 jquery (3.1.1) 和 jqueryUI (1.12.1) 的最新版本。

我已经在我的 javascript 中尝试了来自 here 的示例代码。它加载得很好,但是当我尝试从多选中选择任何值时,即使从多选中取消选择值,网格也会清除并保持清除状态。

我只是想确保此解决方案适用于我正在使用的最新版本的 free-jqGrid、jquery 和 jqueryUI。

【问题讨论】:

    标签: jquery multi-select free-jqgrid


    【解决方案1】:

    我在the old answer 中发布了一个在免费 jqGrid 中使用 Multiselect 小部件的示例。免费jqGrid后期版本支持"in"操作,在使用Multiselect widget的情况下非常实用。

    我为你创建了the new demo,如下图所示。

    它从testJsonData.json 加载输入数据,找到beforeProcessingship_via 列的所有唯一值,并设置基于这些值构建的searchoptions.value。该演示使用来自 GitHub 的免费 jqGrid 的最新代码(更新为 4.13.4)。我计划很快将来自 GitHub 的当前代码发布为 4.13.5 或 4.14.0。该演示使用 Eric Hyndse 创建的当前 v1.17 版本的 Multiselect widget。演示的代码是

    var getUniqueNames = function (columnName, mydata) {
            var texts = $.map(mydata, function (item) {
                return item[columnName];
            }),
              uniqueTexts = [], textsLength = texts.length, text, textsMap = {}, i;
    
            for (i = 0; i < textsLength; i++) {
                text = texts[i];
                if (text !== undefined && textsMap[text] === undefined) {
                    // to test whether the texts is unique we place it in the map.
                    textsMap[text] = true;
                    uniqueTexts.push(text);
                }
            }
            return uniqueTexts;
        },
        buildSearchSelect = function (uniqueNames) {
            var values = "";
            $.each(uniqueNames, function () {
                values += this + ":" + this + ";";
            });
            return values.slice(0, -1);
        },
        initMultiselect = function (searchOptions) {
            var $elem = $(searchOptions.elem),
            options = {
                selectedList: 2,
                height: "auto",
                checkAllText: "all",
                uncheckAllText: "no",
                noneSelectedText: "Any",
                open: function () {
                    var $menu = $(".ui-multiselect-menu:visible");
                    $menu.addClass("ui-jqdialog").width("auto");
                    $menu.find(">ul").css("maxHeight", "200px");
                }
            };
            if (searchOptions.mode === "filter") {
                options.minWidth = "auto";
            }
            $elem.multiselect(options);
            $elem.siblings("button.ui-multiselect").css({
                width: "100%",
                margin: "1px 0",
                paddingTop: ".3em",
                paddingBottom: "0"
            });
        },
        setSearchSelect = function (columnName, data) {
            var values = buildSearchSelect(getUniqueNames.call(this, columnName, data));
            $(this).jqGrid("setColProp", columnName, {
                stype: "select",
                searchoptions: {
                    value: values,
                    sopt: ["in"],
                    attr: {
                        multiple: "multiple",
                        size: 4
                    },
                    selectFilled: initMultiselect
                }
            });
        },
        myDefaultSearch = "cn",
        beforeProcessingHandler1 = function (data) {
            var $this = $(this), p = $this.jqGrid("getGridParam");
            // !!! it will be called only after loading from the server
            // datatype is always "json" here
            setSearchSelect.call(this, "ship_via", data);
    
            if (this.ftoolbar === true) {
                // if the filter toolbar is not already created
                $("#gs_" + this.id + "ship_via").multiselect("destroy");
                $this.jqGrid('destroyFilterToolbar');
            }
    
            if (p.postData.filters) {
                p.search = true;
            }
    
            $this.jqGrid("filterToolbar", {
                //stringResult: true,
                defaultSearch: myDefaultSearch,
                beforeClear: function () {
                    $(this.grid.hDiv)
                    .find(".ui-search-toolbar button.ui-multiselect")
                    .each(function () {
                        $(this).prev("select[multiple]").multiselect("refresh");
                    });
                }
            });
        };
    
    $("#list").jqGrid({
        url: "testJsonData.json",
        datatype: "json",
        colNames: ["Client", "Amount", "Tax", "Total", "Shipped via", "Notes"],
        colModel: [
            { name: "name", width: 65 },
            { name: "amount", width: 75, template: "number" },
            { name: "tax", width: 52, template: "number" },
            { name: "total", width: 65, template: "number" },
            { name: "ship_via", width: 85, align: "center" },
            { name: "note", width: 100, sortable: false }
        ],
        rowNum: 5,
        sortname: "name",
        iconSet: "fontAwesome",
        autoencode: true,
        loadonce: true,
        forceClientSorting: true, // local sorting and filtering data loaded from the server
        beforeProcessing: beforeProcessingHandler1,
        rowList: [5, 10, 20, 30, 100],
        pager: true,
        pagerRightWidth: 120, // fix wrapping or right part of the pager
        viewrecords: true,
        sortable: true
    }).jqGrid("navGrid", { add: false, edit: false, del: false, search: false });
    

    【讨论】:

    • 感谢您的快速回复。这解决了我在代码中看到的问题。我现在唯一需要做的就是能够在我选择的多选中显示值列表而不是列中的现有值,并且还可以显示标签而不是多选中的值,因为我正在使用当行处于编辑模式时,选择选项的值对。是否可以使用我在编辑模式选择选项中使用的现有值列表来提供给多选其值?
    • @JerryP:是的。 setSearchSelect 首先调用buildSearchSelect(getUniqueNames.call(this, columnName, data)); 生成searchoptions.value,然后使用setColProp 更改列属性。您可以直接在需要设置多选 wigdet 的列中使用属性{ stype: "select", searchoptions: { value: values, sopt: ["in"], attr: { multiple: "multiple", size: 4 }, selectFilled: initMultiselect }
    • 在您上面提供的代码中,当清除所有复选框后选择“任何”时,网格不返回任何内容而不是所有记录。我在我的代码中遇到了同样的问题。
    • @JerryP:如果选择“全部”,则将选择所有可能的条目,并且网格将显示所有数据。 "all" 生成过滤器 "ship_via" IN ["TN", "FE", "ABR", "CNC"]。通过单击“否”,可以使用过滤器“ship_via”IN []。没有行对应于过滤器,因此将显示空网格。可以通过使用filterToolbarbeforeSearch 回调来稍微更改过滤器。见the answer
    • @JerryP:此外,您可以使用自定义过滤器操作代替"IN"。见the answerthis onethe wiki article
    【解决方案2】:

    这里修复了下拉菜单中的“任何”选项以返回选择控件中的所有选项。

    修改这部分代码:

    modifySearchingFilter = function (separator) {
    var i, l, rules, rule, parts, j, group, str,
        filters = $.parseJSON(this.p.postData.filters);
    console.log(filters);
    rules = filters.rules;
    console.log(rules.length)
    for (i = 0; i < rules.length; i++) {
        rule = rules[i];
        if (rule.data == "") {
            rule.op = "ne"; //this will return anything not equal to ""
        }
    }
    console.log("after splicing: " + JSON.stringify(filters))
    this.p.postData.filters = JSON.stringify(filters);},
    

    如果添加规则检查并为运算符返回不等于(“ne”),则重要部分。这将创建一个规则,过滤掉所有不等于空字符串的选项。这应该返回所有选择选项,换句话说,将选择重置为初始状态,显示选择中的所有选项,并将返回网格中的所有记录。希望这对将来有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-14
      • 1970-01-01
      • 2015-05-22
      • 2014-08-24
      相关资源
      最近更新 更多