具有select2现有值的JqGrid搜索选项

时间:2018-03-14 16:28:24

标签: asp.net-mvc jqgrid jquery-select2-4

我试图将select2集成到JqGrid过滤器表单中。我使用的是JqGrid min 4.6&选择2分钟4.0.1。过滤器工作正常但我无法检索过滤器窗体关闭并重新打开后通过select2设置的值。即dataInit e1不返回选择输入的现有值。我一定做错了什么?

JqGrid列模型:

        {
            name: 'CurrencyID', hidden: true, search: true, stype: 'select', searchtype: 'number', searchoptions: {
                searchhidden: true,
                sopt: ['eq', 'ne'],
                dataInit: function (el) {
                    intiGridFilterSelecr2Field(el, paramFromView.CurrencyOptions);
                }
            },
            searchrules: { required: true }
        },

参数:

@section scripts{
<script>
   var paramFromView = {
        CurrencyOptions: {
            searchURL: '@Url.Action("GetCurrency", "Controller")',
            detailURL: '@Url.Action("CurrencyDetailsJson", "Controller")',
            idField: 'CurrencyID',
            txtField: 'Description'
        }
   };
</script>
}

Select2 Helper:

function intiGridFilterSelecr2Field(element, options) {
var comboPageSize = 15;
var quietMillis = 200;
var placeHolderText = 'Choose...'

var defaults = {
    searchURL: '',
    detailURL: '',
    idField: '',
    txtField: ''
};
var options = $.extend({}, defaults, options);
var select2Element = $(element);

select2Element.select2({
    width: 'element',
    minimumInputLength: 1,
    placeholder: placeHolderText,
    ajax: {
        url: options.searchURL,
        dataType: 'json',
        quietMillis: quietMillis,
        cache: false,
        data: function (params) {
            return {
                name: params.term,
                page: params.page,
                pageSize: comboPageSize
            };
        },
        processResults: function (data) {
            var more = (data.page * comboPageSize) < data.total;

            var resultsArr = [];
            for (var i = 0; i < data.result.length; i++) {
                resultsArr.push({ id: data.result[i][options.idField], text: data.result[i][options.txtField] });
            }
            return { results: resultsArr, more: more };
        }
    },
}).each(function (index, element) {
    var idCombo = $(this);
     // The problem is that idCombo.val() is always empty.
     // element:select2-hidden-accessible
    if (idCombo.val() != null && idCombo.val().length > 0) {
        $.ajax(options.detailURL, {
            data: {
                id: idCombo.val()
            },
            dataType: 'json',
            cache: false
        }).done(function (data) {
            var optselected = select2Element.find('option').filter(function () { return this.value == data[idField] && this.text == data[txtField] && this.selected })
            if (optselected == undefined || optselected.length == 0) {
                var $optionContact = $("<option selected></option>").val(data[idField].toString()).text(data[txtField]);
                var toBeRemoved = select2Element.find('option').filter(function () { return this.value == data[idField] });
                if (toBeRemoved != undefined) {
                    toBeRemoved.remove();
                }
                select2Element.append($optionContact).trigger('change.select2');
            }
        });
    }

  });
}

设置过滤器时... When the filter is being set...

加载现有过滤器时。如何将此CurrencyID = 1传递给select2助手? When Loading the existing filter

更新

根据Oleg的回答,我更新了我的代码如下。

            {
            name: 'CurrencyID', hidden: true, searchtype: 'number', search: true,
            stype: "select", searchoptions: {
                searchhidden: true,
                sopt: ["eq", "ne"],
                dataUrl: paramFromView.CurrencyOptions.searchURL,
                buildSelect: function (data) {
                    var obj = jQuery.parseJSON(data);
                    var i, options = [];
                    for (i = 0; i < obj.result.length; i++) {
                        options.push("<option value='" + obj.result[i][paramFromView.CurrencyOptions.idField] + "'>" +
                            obj.result[i][paramFromView.CurrencyOptions.txtField] + "</option>");
                    }
                    return "<select>" + options.join("") + "</select>";
                },
                noFilterText: "Any",
                selectFilled: function (options) {
                    setTimeout(function () {
                        $(options.elem).select2({
                            width: 'element',
                        });
                    }, 0);
                }
            },
            searchrules: { required: true }
        },

我几乎与我想要达到的目标一致。但是,我仍然面临一些困难。

  1. 初始加载过滤器时,会在下拉列表中选择值,但查询值为空。即如果用户在加载过滤器表单后立即单击“查找”按钮,则不会设置过滤器。

  2. 我仍然无法使用select2样式。

  3. enter image description here

1 个答案:

答案 0 :(得分:1)

我可以演示如何在我开发的jqGrid的free jqGrid分叉中使用select2。我从旧版本4.14.1的README获取演示(当前发布的版本是4.15.3)并对其进行了修改以演示select2的用法。

代码的主要部分可能是

stype: "select",
searchoptions: {
    sopt: ["eq", "ne"],
    ...
    selectFilled: function (options) {
        setTimeout(function () {
            $(options.elem).select2({
                width: "100%"
            });
        }, 0);
    }
}

https://jsfiddle.net/Lae6kee7/2/。您可以尝试在“Shipped via”列中的过滤器工具栏中选择一个选项,然后打开搜索对话框。您将看到select2将选择相同的选项。

如果您要通过select2发布的Ajax请求加载数据,那么您的代码将会更加复杂。重要的是要理解这种方式实际上只需要非常大的可能值。我的意思是项目数量大于100000项目。另一方面,大多数用例需要少于1000个选项。在这种情况下,将所有数据作为select选项加载然后将select转换为select2会更有效。 select2,从用户的角度来看,使用本地选择的工作要快得多。

如果您使用dataUrl代替ajax select2选项,我认为代码会更容易。您可以使用dataUrl从服务器返回所有不同的值,这些值可以在select2中使用,并使用buildSelect从服务器返回的JSON数据构建<select>。演示https://jsfiddle.net/Lae6kee7/23/证明了这一点。我为JSFiddle做了演示,它支持Echo服务(参见here),它允许模拟服务器响应。您的真实代码应该只包含dataUrlbuildSelectselectFilled的代码,我在上面包含这些代码。

此外,我建议您考虑使用<datalist>(例如,请参阅here),这可能是选择2的好替代。所有现代Web浏览器都包含<datalist>原生支持,因此<datalist>可以非常快速地运行。尝试搜索我演示的第一个Client列。你会看到控制,它将非常接近select2。 <datalist>的其他优势:我们无法仅搜索test10test11test12等精确预定义值,而是搜索1等子字符串。比较

enter image description here

enter image description here

enter image description here

enter image description here