jqGrid将多选择列过滤器添加到特定列 [英] jqGrid add multi select column filter to a specific column

查看:75
本文介绍了jqGrid将多选择列过滤器添加到特定列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to add the multi-select filter to my PROVIDER column in the jqGrid. I am able to add the select filter but now I am converting it to the multi-select filter. I referred to a few old posts here and tried to do the same. It's not throwing me any error but it is not creating the multi-select filter also. Please let me know what I am doing wrong below. I am able to get the unique values and able to create the SELECT list, I am guessing something is wrong with function dataInitMultiselect because I tried to console.log(elem) but it's not returning anything, not even undefined but the function is getting called because its not throwing me undefined function error.

$("#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演示

Thanks a lot for the response, Yes I am using the free jqGrid. As per the mentioned comment I tried to change the code but still not working for me. Please find below the updated code, I tried to do as mentioned in the jqGrid MultiSelect Demo

但是它抛出了错误Uncaught ReferenceError: multiselectTemplate is not defined,请让我知道如何解决此问题. 由于他们使用本地数据加载jqgrid,因此我很难解决此问题.

But it's throwing me the error Uncaught ReferenceError: multiselectTemplate is not defined, Please let me know how to resolve this. Since they have used the local data to load the jqgrid I am finding it difficult to resolve this issue.

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

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

I tried declaring it within the function and outside the function but still no luck. Please help me with this issue.

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

After the lot of help from Oleg I was able to get the Multi-Select but its not working. when I click on it does not expand and show the option. I have posted my code here MY JQGRID CODE@Oleg can you please look at this and provide me with solution.

我的jqGrid看起来像这样:

My jqGrid is looking something like this:

推荐答案

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

From your other questions one can see that you use free jqGrid fork. It supports generating of unique values automatically. Thus one can use

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.例如,可以在loadComplete内部测试this.ftoolbar来检测filterToolbar是否已经存在:

It's important that unique values of data in the column will be filled only after loading the data. Then one should create or recreate filterToolbar after loading the data from the server. One can test this.ftoolbar inside of loadComplete for example to detect whether filterToolbar already exist:

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中使用multiselect的可能实现.函数dataInitMultiselect具有以下实现:

The demo https://jsfiddle.net/OlegKi/ty4e68pm/2/ shows a possible implementation of usage multiselect in free jqGrid. The function dataInitMultiselect has the following implementation:

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/.它包含很多错误:

UPDATED: I analysed your demo https://jsfiddle.net/B_AV_B/7ecrmtz4/5/. It contains a lot of error:

  1. 您在多选列中缺少stype : "select".搜索字段必须具有选择类型(stype : "select")才能显示为<select>元素,以后可以根据多选控件进行转换
  2. 我多次写信给您,内容涉及仅插入一个版本的jQuery和其他JavaScript库的重要性.此外,根据依赖关系保持插入的JS文件的顺序很重要. Multiselect小部件是jQuery UI的插件.因此,必须先插入jQuery UI.简而言之,您应该替换
  1. you missing stype : "select" in multiselect column. The searching field have to have select type (stype : "select") to be able to be displayed as <select> alement, which can be converted later with respect of multiselect control
  2. I wrote you multiple times about importance inserting only one version of jQuery and other JavaScript libraries. Moreover, it's important to hold the order of inserted JS files based on dependencies. Multiselect widget is plugin to jQuery UI. Thus jQuery UI must be inserted before. In short you should replace

<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. 您应删除../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. colModelwidth属性的值应该是数字,而不是像"120%"这样的字符串.数字将被解释为像素.如果使用autowidth : true,则初始width值将按比例增加,以使网格的宽度等于外部元素的宽度.
  5. 最后,我在您的演示中添加了一些CSS规则
  1. You should remove ../bootstrap-multiselect/0.9.13/js/bootstrap-multiselect.js, which overwrite multiselect registered previously.
  2. JavaScript is case sensitive. It seems that ID property of input data specifies unique id of every input item. jqGrid uses id instead of ID by default. If you use datatype: "local" then you should include localReader: { id: "ID" } parameter. If you use datatype: "json" then you should include jsonReader: { id: "ID" }. In your case you can include both parameters.
  3. You used wrong code of open callback (compare your code, with the code from my answer). It's enough to use it as var $menu = $(".ui-multiselect-menu:visible"); $menu.width("auto"); without additional actions, which makes some other items invisible.
  4. Values of width property on colModel should be numbers and not strings like "120%". Numbers will be interpreted as pixels. If you use autowidth : true the initial width values will be proportionally increased to make the width of the grid equal to the width of outer element.
  5. Finally I added some CSS rules to your demo

.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.

You can modify the font-size on the above rule corresponds to your requirements.

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

这篇关于jqGrid将多选择列过滤器添加到特定列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆