jqGrid将多选择列过滤器添加到特定列

时间:2019-06-10 14:34:17

标签: jquery jqgrid multi-select free-jqgrid jqgrid-formatter

我正在尝试将多选过滤器添加到PROVIDER的{​​{1}}列中。我可以添加选择过滤器,但是现在我将其转换为多选过滤器。我在这里提到了一些旧帖子,并试图做同样的事情。它不会引发任何错误,但也不会创建多选过滤器。请在下面告诉我我在做什么错。 我能够获取唯一值并能够创建SELECT列表,我猜函数 dataInitMultiselect 出了点问题,因为我尝试 console.log(elem),但是它没有返回任何东西,甚至没有未定义,但是函数被调用,因为它没有引发我未定义的函数错误。

jqGrid

非常感谢您的答复,是的,我正在使用免费的jqGrid。 根据提到的评论,我试图更改代码,但仍然无法为我工作。请在下面的更新代码中查找,我尝试按照jqGrid MultiSelect Demo

中的说明进行操作

但是它抛出了错误$("#home_grid").jqGrid({ url: "/URL_TO_FETCH_DATA", datatype: "json", mtype: "GET", colNames: ["Provider", "Title","Original Publish Time", "Fetch Time"], colModel: [ { name : "PROVIDER", align : "center", width : "120%", search : true }, { name : "TITLE", align : "center", search : true, width : "250%", formatter: Title_Url_Bind }, { name : "PUBLISH_TIME", align : "center", width : "130%", search : true, sorttype : "datetime" }, { name : "DB_ENTRY_TIME", align : "center", width : "130%", sortable : true, sorttype : "datetime" } ], pager : "#home_pager", loadonce : true, shrinkToFit : true, rowNum : 10, autoHeight : true, rowList : [10, 15, 20, 25, 50], sortable : true, viewrecords : true, toolbar : [true, "top"], autowidth : true, beforeProcessing: beforeProcessingHandler1, }); function beforeProcessingHandler1(data) { initializeGridFilterValueDem(data); } initializeGridFilterValueDem = function (data) { setSearchSelect("Provider", jQuery("#home_grid"), data); } setSearchSelect = function (columnName, grid,data) { grid.jqGrid('setColProp', columnName, { searchoptions: { clearSearch: false, sopt: ['eq', 'ne'], value: buildSearchSelect(getUniqueNames(columnName, data,grid)), attr: { multiple: 'multiple', size: 7}, dataInit: dataInitMultiselect } } ); } buildSearchSelect = function (uniqueNames) { var values = ""; $.each(uniqueNames, function () { values += this + ":" + this + ";"; }); return values.substring(0, values.length - 1); } getUniqueNames = function (columnName, mydata_parm, grid) { var mydata = grid.jqGrid("getGridParam", "data"); 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; } dataInitMultiselect = function (elem) { console.log(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.multiselect(options).multiselectfilter({ placeholder: '' }); $elem.siblings('button.ui-multiselect').css({ width: inToolbar ? "98%" : "100%", marginTop: "1px", marginBottom: "1px", paddingTop: "3px" }); }, 50); }; ,请让我知道如何解决此问题。 由于他们使用本地数据加载jqgrid,因此我很难解决此问题。

Uncaught ReferenceError: multiselectTemplate is not defined

我试图在函数内和函数外声明它,但还是没有运气。请帮助我解决这个问题。

在Oleg的大力帮助下,我能够获得Multi-Select,但无法正常工作。当我单击它不会展开并显示该选项。我已经在MY JQGRID CODE @ Oleg上发布了我的代码。您能看看这个并为我提供解决方案吗。

我的jqGrid看起来像这样: JQGRID COLUMMN

1 个答案:

答案 0 :(得分:1)

从其他问题中,您可以看到您使用了免费的jqGrid fork。它支持自动生成唯一值。这样就可以使用

searchoptions: {
    generateValue: true,
    sopt: ["in"],
    attr: { multiple: "multiple", size: 7 },
    dataInit: dataInitMultiselect
}

代替

searchoptions: {
    clearSearch: false,
    sopt: ['eq', 'ne'],
    value: buildSearchSelect(getUniqueNames(columnName, data,grid)),
    attr: { multiple: 'multiple', size: 7},
    dataInit: dataInitMultiselect
}

重要的是,仅在加载数据后才填充列中数据的唯一值。然后,应该在从服务器加载数据后创建或重新创建filterToolbar。例如,可以在this.ftoolbar内测试loadComplete来检测filterToolbar是否已经存在:

loadComplete: function () {
    if (!this.ftoolbar) {
        // create filter toolbar if it isn't exist 
        $(this).jqGrid("filterToolbar", {
            defaultSearch: "cn",
            beforeClear: function() {
                $(this.grid.hDiv)
                    .find(".ui-search-toolbar button.ui-multiselect")
                    .each(function() {
                    $(this).prev("select[multiple]").multiselect("refresh");
                });
            }
        });
        $(this).triggerHandler("jqGridRefreshFilterValues");
        $(this.grid.hDiv)
            .find(".ui-search-toolbar button.ui-multiselect")
            .each(function() {
            $(this).prev("select[multiple]")
                .multiselect("refresh");
        });        
    }
}

演示https://jsfiddle.net/OlegKi/ty4e68pm/2/显示了在免费jqGrid中使用多重选择的可能实现。函数dataInitMultiselect具有以下实现:

var dataInitMultiselect = function (elem, searchOptions) {
        var $grid = $(this);
        setTimeout(function() {
            var $elem = $(elem),
                id = elem.id,
                inToolbar = searchOptions.mode === "filter",
                options = {
                    selectedList: 2,
                    height: "auto",
                    checkAllText: "all",
                    uncheckAllText: "no",
                    noneSelectedText: "Any",
                    open: function() {
                        var $menu = $(".ui-multiselect-menu:visible");
                        $menu.width("auto");
                    }
                },
                $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";
            }
            $grid.triggerHandler("jqGridRefreshFilterValues");
            $elem.multiselect(options);
            // replace icons ui-icon-check, ui-icon-closethick, ui-icon-circle-close
            // and ui-icon-triangle-1-s to font awesome icons
            var $header = $elem.data("echMultiselect").header;
            $header.find("span.ui-icon.ui-icon-check")
                .removeClass("ui-icon ui-icon-check")
                .addClass("fa fa-fw fa-check");
            $header.find("span.ui-icon.ui-icon-closethick")
                .removeClass("ui-icon ui-icon-closethick")
                .addClass("fa fa-fw fa-times");
            $header.find("span.ui-icon.ui-icon-circle-close")
                .removeClass("ui-icon ui-icon-circle-close")
                .addClass("fa fa-times-circle");
            $elem.data("echMultiselect")
                .button
                .find("span.ui-icon.ui-icon-triangle-1-s")
                .removeClass("ui-icon ui-icon-triangle-1-s")
                .addClass("fa fa-caret-down")
                .css({
                    float: "right",
                    marginRight: "5px"
                });

            $elem.siblings("button.ui-multiselect").css({
                width: "100%",
                margin: "1px 0",
                paddingTop: ".3em",
                paddingBottom: ".3em"
            });
        }, 50);
    };

更新:我分析了您的演示https://jsfiddle.net/B_AV_B/7ecrmtz4/5/。它包含很多错误:

  1. 您在多选列中缺少stype : "select"。搜索字段必须具有选择类型(stype : "select")才能显示为<select>元素,以后可以根据多选控件进行转换
  2. 我多次写信给您,涉及只插入一个版本的jQuery和其他JavaScript库的重要性。此外,根据依赖关系保持插入的JS文件的顺序很重要。 Multiselect小部件是jQuery UI的插件。因此,必须先插入jQuery UI。简而言之,您应该替换
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-multiselect-widget/2.0.2/jquery.multiselect.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>   

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-multiselect-widget/2.0.2/jquery.multiselect.js"></script>
  1. 您应该删除{strong>覆盖 ../bootstrap-multiselect/0.9.13/js/bootstrap-multiselect.js先前注册的multiselect
  2. JavaScript区分大小写。似乎输入数据的ID属性指定了每个输入项的唯一ID。 jqGrid默认使用id而不是ID。如果使用datatype: "local",则应包含localReader: { id: "ID" }参数。如果使用datatype: "json",则应包括jsonReader: { id: "ID" }。您可以同时包含两个参数。
  3. 您使用了错误的open回调代码(将您的代码与我的答案中的代码进行比较)。无需其他操作就可以将其用作var $menu = $(".ui-multiselect-menu:visible"); $menu.width("auto");,这使得其他一些项目不可见。
  4. widthcolModel属性的值应该是数字,而不是"120%"之类的字符串。数字将被解释为像素。如果使用autowidth : true,则初始width值将按比例增加,以使网格的宽度等于外部元素的宽度。
  5. 最后,我在您的演示中添加了一些CSS规则
.ui-multiselect-menu .ui-multiselect-header ul,
.ui-multiselect-menu .ui-multiselect-checkboxes li {
    font-size: 12px;
}

.ui-multiselect-menu .ui-multiselect-header a:hover {
    text-decoration: none;
}
.ui-multiselect-menu .ui-multiselect-close {
    margin-right: 3px;
}

您可以根据自己的要求修改上述规则上的font-size

修改后的演示为https://jsfiddle.net/OlegKi/teLja6z3/25/