jquery - jqGrid向特定列添加多选列过滤器

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

我正在尝试将多选过滤器添加到 jqGrid 中的 PROVIDER 列。我可以添加选择过滤器,但现在我将其转换为多选过滤器。我在这里引用了一些旧帖子并尝试做同样的事情。它没有向我抛出任何错误,但它也没有创建多选过滤器。请让我知道我在下面做错了什么。 我能够获取唯一值并能够创建 SELECT 列表,我猜测函数 dataInitMultiselect 有问题,因为我尝试 console.log(elem) 但是它没有返回任何内容,甚至没有未定义,但该函数正在被调用,因为它没有向我抛出未定义的函数错误。

$("#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。 根据提到的评论,我尝试更改代码,但仍然不适合我。请在下面找到更新的代码,我尝试按照 jqGrid MultiSelect Demo 中提到的方式进行操作

但它向我抛出错误Uncaught ReferenceError: multiselectTemplate is not Defined,请让我知道如何解决此问题。 由于他们使用本地数据加载 jqgrid 我发现很难解决这个问题。

    //FUNCTION TO POPULATE THE TABLE WITH THE DATA
function Grid_Table_Populator()
{
    //Populdate the Datatable with the WEB Feed data
    $("#home_grid").jqGrid({
        url: "/Web_Feed_Data",
        datatype: "json",
        mtype: "GET",
        colNames: ["ID", "PROVIDER", "Title"],
        colModel:
        [
            {
                name    : "ID",
                align   : "center",
                search  : true,
                hidden  : true
            },
            {
                name    : "PROVIDER",
                align   : "center",
                width   : "120%",
                type    : "text", 
                search  : true, 
                template: multiselectTemplate       
            },
            {
                name    : "TITLE",
                align   : "center",
                search  : true,
                width   : "250%",
                formatter: Title_Url_Bind 
            },
        ],
        pager       : "#home_pager",
        loadonce    : true,
        shrinkToFit : true,
        rowNum      : 10,
        autoHeight  : true,
        rowList     : [10, 15, 20, 25, 50],
        sortable    : true,
        sortname    : "TITLE",
        sortorder   : "desc",
        viewrecords : true,
        toolbar     : [true, "top"],
        autowidth   : true,
        caption     : 'Table Data',
        loadComplete: function(data)
        {
            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");
                });        
            }
        },
    }); 

    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");
                            var height = $menu.find(">ul>li").first().outerHeight();
                            $menu.find(">ul").css("maxHeight", 5 * Math.max(height, 12));
                            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";
                }
                $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);
        },    
        multiselectTemplate = {
            stype: "select", 
            searchoptions: {
                generateValue: true,
                //noFilterText: "Any",
                sopt: ["in"],
                attr: {
                    multiple: "multiple",
                    size: 3
                },
                dataInit: dataInitMultiselect
            }
    };
}

我尝试在函数内部和函数外部声明它,但仍然没有成功。请帮我解决这个问题。

在 Oleg 的大力帮助下,我能够获得多选功能,但它不起作用。当我单击它时,它不会展开并显示该选项。我已经在这里发布了我的代码MY JQGRID CODE @Oleg 你能看看这个并为我提供解决方案吗?

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

最佳答案

从您的其他问题可以看出您使用免费的 jqGrid 分支。它支持自动生成唯一值。因此可以使用

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> alement,稍后可以根据多选控件进行转换
  2. 我多次写信给您介绍插入仅一个版本的 jQuery 和其他 JavaScript 库的重要性。此外,根据依赖关系保持插入的 JS 文件的顺序也很重要。多选小部件是 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>
  • 您应该删除../bootstrap-multiselect/0.9.13/js/bootstrap-multiselect.js覆盖multiselect之前注册过。
  • JavaScript 区分大小写。看来ID输入数据的属性指定每个输入项的唯一ID。 jqGrid 使用id而不是ID默认情况下。如果您使用datatype: "local"那么你应该包括 localReader: { id: "ID" }范围。如果您使用datatype: "json"那么你应该包括 jsonReader: { id: "ID" } 。根据您的情况,您可以包含这两个参数。
  • 您使用了错误的代码open回调(将您的代码与我的答案中的代码进行比较)。将其用作 var $menu = $(".ui-multiselect-menu:visible"); $menu.width("auto"); 就足够了无需额外操作,这会使其他一些项目不可见。
  • width 的值属性 colModel应该是数字而不是像 "120%" 这样的字符串。数字将被解释为像素。如果您使用autowidth : true初始width值将按比例增加,使网格的宽度等于外部元素的宽度。
  • 最后我在您的演示中添加了一些 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/

    关于jquery - jqGrid向特定列添加多选列过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56528454/

    相关文章:

    javascript - 如何从输入值中进行多项选择?

    reactjs - 在 ANTD React 中使用全选选项进行多选

    javascript - 为窗口滚动的每 n 个像素做一些事情

    javascript - 如何重新启动动画中的循环?

    Jquery ui 可排序限制最大为 1 项

    javascript - 为什么这个 JQuery 日期选择器在第一次 ng-click 时没有加载?

    javascript - AJAX 调用在 jQGrid 中不起作用

    javascript - jqgrid 显示不在 json 中的静态列

    jquery - jqGrid 和 IE8 中的兼容性 View 模式

    javascript - 我如何在 Bootstrap 箱中使用多选