更新select2数据而不重建控件

mfr*_*tas 39 jquery jquery-select2

我正在转换<input type="hidden">为select2下拉列表并通过查询方法提供数据

$('#inputhidden').select2({
    query: function( query ) {
        query.callback( data ); // the data is in the format select2 expects and all works well..
    );
});
Run Code Online (Sandbox Code Playgroud)

问题是我需要破解select2用户界面并在搜索栏顶部放置两个按钮,当点击它们时,将执行ajax调用,并且必须更新select2内容.

在此输入图像描述

现在,我需要完成这些更新,而不是完全重建select2,而只是刷新下拉列表中的项目.我找不到将一组新数据传递给已创建的select2控件的方法,这可能吗?

ndp*_*dpu 44

select2 v3.x

如果你有带有选项的本地数组(通过ajax调用接收),我认为你应该使用data参数作为返回选择框结果的函数:

var pills = [{id:0, text: "red"}, {id:1, text: "blue"}]; 

$('#selectpill').select2({
    placeholder: "Select a pill",
    data: function() { return {results: pills}; }
});

$('#uppercase').click(function() {
    $.each(pills, function(idx, val) {
        pills[idx].text = val.text.toUpperCase();
    });
});
$('#newresults').click(function() {
    pills = [{id:0, text: "white"}, {id:1, text: "black"}];
});
Run Code Online (Sandbox Code Playgroud)

FIDDLE: http: //jsfiddle.net/RVnfn/576/

如果您使用按钮自定义select2接口,只需调用updateResults(此方法不允许从select2对象的外部调用,但allowedMethods如果需要,可以在select2 中将其添加到数组中)更新数据数组后的方法(例如).


select2 v4:自定义数据适配器

带有附加的自定义数据适配器updateOptions(不清楚为什么原始ArrayAdapter缺少此功能)方法可用于动态更新选项列表(此示例中的所有选项):

$.fn.select2.amd.define('select2/data/customAdapter',
    ['select2/data/array', 'select2/utils'],
    function (ArrayAdapter, Utils) {
        function CustomDataAdapter ($element, options) {
            CustomDataAdapter.__super__.constructor.call(this, $element, options);
        }
        Utils.Extend(CustomDataAdapter, ArrayAdapter);
        CustomDataAdapter.prototype.updateOptions = function (data) {
            this.$element.find('option').remove(); // remove all options
            this.addOptions(this.convertToOptions(data));
        }        
        return CustomDataAdapter;
    }
);

var customAdapter = $.fn.select2.amd.require('select2/data/customAdapter');

var sel = $('select').select2({
    dataAdapter: customAdapter,
    data: pills
});

$('#uppercase').click(function() {
    $.each(pills, function(idx, val) {
        pills[idx].text = val.text.toUpperCase();
    });
    sel.data('select2').dataAdapter.updateOptions(pills);
});
Run Code Online (Sandbox Code Playgroud)

FIDDLE: https: //jsfiddle.net/xu48n36c/1/


select2 v4:ajax传输函数

在v4中,您可以定义可以使用本地数据数组的自定义传输方法(例如,@xaleb_Kiage,我已经使用它而没有成功)

docs:https://select2.github.io/options.html#can-an-ajax-plugin-other-than-jqueryajax-be-used

Select2使用ajax.transport中定义的传输方法向API发送请求.默认情况下,此传输方法是jQuery.ajax,但可以更改.

$('select').select2({
    ajax: {
        transport: function(params, success, failure) {
            var items = pills;
            // fitering if params.data.q available
            if (params.data && params.data.q) {
                items = items.filter(function(item) {
                    return new RegExp(params.data.q).test(item.text);
                });
            }
            var promise = new Promise(function(resolve, reject) {
                resolve({results: items});
            });
            promise.then(success);
            promise.catch(failure);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

但是如果数组中的选项文本发生更改,则需要更改选项的ID - 内部select2 dom选项元素列表未修改.如果数组中的选项id保持不变 - 将显示以前保存的选项而不是从数组更新!如果仅通过向其添加新项目来修改数组,这不是问题- 对于大多数常见情况都可以.

FIDDLE: https ://jsfiddle.net/xu48n36c/3/

  • @ndpu 你太棒了,这正是我所需要的,谢谢! (2认同)

zsa*_*yer 17

我认为直接交付数据就足够了:

$("#inputhidden").select2("data", data, true);
Run Code Online (Sandbox Code Playgroud)

请注意,第二个参数似乎表明需要刷新.

由于@Bergi与帮助这个.


如果没有自动更新,您可以尝试直接调用它的updateResults方法.

$("#inputhidden").select2("updateResults");
Run Code Online (Sandbox Code Playgroud)

或者通过向"input.select2-input"发送触发器来间接触发它,如下所示:

var search = $("#inputhidden input.select2-input");
search.trigger("input");
Run Code Online (Sandbox Code Playgroud)

  • 没有名为updateResults的方法 (17认同)
  • `search.trigger("change")`似乎也运行良好. (3认同)
  • @AnuradhaJayathilaka 它是[由这里的select2定义](https://github.com/ivaynberg/select2/blob/356984d8fe447fd09a2be72728bd47f2259d638d/select2.js#L1557) (2认同)
  • 那真是怪了.该方法不在文档上,当我运行它时,它给出了错误. (2认同)
  • @AnuradhaJayathilaka 解决方案可能在@ndpu关于`allowedMethods`的回答中 (2认同)

Dat*_*ter 13

使用Select2 4.0和Meteor,您可以这样做:

Template.TemplateName.rendered = ->

  $("#select2-el").select2({
    data  : Session.get("select2Data")
  })

  @autorun ->

    # Clear the existing list options. 
    $("#select2-el").select2().empty()

    # Re-create with new options.
    $("#select2-el").select2({
      data  : Session.get("select2Data")
    })
Run Code Online (Sandbox Code Playgroud)

发生了什么:

  1. 当模板呈现时......
  2. 使用Session中的数据初始化select2控件.
  3. 每次Session.get("select2Data")的值发生变化时,@ autorun(this.autorun)函数都会运行.
  4. 每当Session更改时,清除现有的select2选项并使用新数据重新创建.

这适用于任何反应数据源 - 例如Collection.find().fetch() - 而不仅仅是Session.get().

注意:从Select2版本4.0开始,您必须在添加新的onces之前删除现有选项.有关详细信息,请参阅此GitHub问题.在没有清除现有选项的情况下,没有"更新选项"的方法.

以上是coffeescript.与Javascript非常相似.

  • 问题中没有提到流星。 (3认同)
  • @Craicerjack是真的 - 但是我在这里寻找可以与Meteor一起使用的解决方案.我按照上面的答案修改了Meteor.也许其他人也会降落在这里. (2认同)

小智 12

试试这个:

var data = [{id: 1, text: 'First'}, {id: 2, text: 'Second'}, {...}];
$('select[name="my_select"]').empty().select2({
    data: data
});
Run Code Online (Sandbox Code Playgroud)

  • 这会重建 select2,这意味着如果您有任何配置,它们都会丢失。如果您附加了任何事件,则需要先将其分离,然后重新附加。 (4认同)

kar*_*raj 6

var selBoxObj = $('#selectpill');
selBoxObj.trigger("change.select2");
Run Code Online (Sandbox Code Playgroud)