jQuery 更新 select2 数据而不重建控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16480910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 17:13:15  来源:igfitidea点击:

Update select2 data without rebuilding the control

jqueryjquery-select2

提问by mfreitas

I am converting an <input type="hidden">to a select2 dropdown and feeding it data through the query method

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

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

The problem is i needed to hack the select2 UI and position two buttons on top of the search bar that, when clicked, will perform ajax calls and will have to update the select2 content.

问题是我需要破解 select2 UI 并在搜索栏顶部放置两个按钮,单击时将执行 ajax 调用并且必须更新 select2 内容。

enter image description here

在此处输入图片说明

Now, I need those updates to occur without rebuilding the select2 entirely but rather just refreshing the items on the dropdown. I cannot find a way to pass a new set of data to an already created select2 control, is that possible ?

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

回答by ndpu

select2 v3.x

选择2 v3.x

If you have local array with options (received by ajax call), i think you should use dataparameter as function returning results for select box:

如果您有带有选项的本地数组(由 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"}];
});

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

小提琴http://jsfiddle.net/RVnfn/576/

In case if you customize select2 interface with buttons, just call updateResults(this method not allowed to call from outsite of select2 object but you can add it to allowedMethodsarray in select2 if you need to) method after updateting data array(pills in example).

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



select2 v4: custom data adapter

select2 v4:自定义数据适配器

Custom data adapter with additional updateOptions(its unclear why original ArrayAdapterlacks this functionality) method can be used to dynamically update options list (all options in this example):

自定义数据适配器具有附加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);
});

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

小提琴https://jsfiddle.net/xu48n36c/1/



select2 v4: ajax transport function

select2 v4:ajax传输函数

in v4 you can define custom transport method that can work with local data array (thx @Caleb_Kiage for example, i've played with it without succes)

在 v4 中,您可以定义可以与本地数据数组一起使用的自定义传输方法(例如,感谢 @Caleb_Kiage,我玩过它但没有成功)

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

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

Select2 uses the transport method defined in ajax.transport to send requests to your API. By default, this transport method is jQuery.ajax but this can be changed.

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

BUTwith this method you need to change ids of options if text of option in array changes - internal select2 dom option element list did not modified. If id of option in array stay same - previous saved option will be displayed instead of updated from array! That is not problem if array modified only by adding new items to it- ok for most common cases.

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

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

小提琴:https ://jsfiddle.net/xu48n36c/3/

回答by zsawyer

I think it suffices to hand the data over directly:

我觉得直接把数据交出来就可以了:

$("#inputhidden").select2("data", data, true);

Note that the second parameter seems to indicate that a refresh is desired.

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

Thanks to @Bergi for help with this.

由于@Bergi与帮助这个



If that doesn't automatically update you could either try calling it's updateResults method directly.

如果这不会自动更新,您可以尝试直接调用它的 updateResults 方法。

$("#inputhidden").select2("updateResults");

Or trigger it indirectly by sending a trigger to the "input.select2-input" like so:

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

var search = $("#inputhidden input.select2-input");
search.trigger("input");

回答by Lucidity

Using Select2 4.0 with Meteor you can do something like this:

将 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")
    })

What's happening:

发生了什么:

  1. When Template is rendered...
  2. Init a select2 control with data from Session.
  3. @autorun (this.autorun) function runs every time the value of Session.get("select2Data") changes.
  4. Whenever Session changes, clear existing select2 options and re-create with new data.
  1. 当模板呈现...
  2. 使用 Session 中的数据初始化一个 select2 控件。
  3. @autorun (this.autorun) 函数在每次 Session.get("select2Data") 的值改变时运行。
  4. 每当会话更改时,清除现有的 select2 选项并使用新数据重新创建。

This works for any reactive data source - such as a Collection.find().fetch() - not just Session.get().

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

NOTE: as of Select2 version 4.0 you must remove existing options before adding new onces. See this GitHub Issue for details. There is no method to 'update the options' without clearing the existing ones.

注意:从 Select2 4.0 版开始,您必须在添加新选项之前删除现有选项。有关详细信息,请参阅此 GitHub 问题。没有清除现有选项就无法“更新选项”。

The above is coffeescript. Very similar for Javascript.

以上是咖啡脚本。与 Javascript 非常相似。

回答by SpinyMan

Try this one:

试试这个:

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

回答by karthipan raj

var selBoxObj = $('#selectpill');
selBoxObj.trigger("change.select2");

回答by Caleb Kiage

I solved this issue by using the ajax option and specifying a custom transport function.

我通过使用 ajax 选项并指定自定义传输函数解决了这个问题。

see this fiddle Select2 dynamic options demo

看这个小提琴Select2 动态选项演示

Here is the relevant js to get this to work.

这是相关的 js 来让它工作。

var $items = [];

let options = {
ajax: {
    transport: function(params, success, failure) {
    let items = $items;

    if (params.data && params.data.q) {
        items = items.filter(function(item) {
        return new RegExp(params.data.q).test(item.text);
        });
    }

    let promise = new Promise(function(resolve, reject) {
        resolve({
        results: items
        });
    });

    promise.then(success);
    promise.catch(failure);
    }
},
placeholder: 'Select item'
};

$('select').select2(options);

let count = $items.length + 1;

$('button').on('click', function() {
$items.push({
    id: count,
    text: 'Item' + count
});
count++;
});

回答by rtcherry

As best I can tell, it is not possible to update the select2 options without refreshing the entire list or entering some search text and using a query function.

据我所知,如果不刷新整个列表或输入一些搜索文本并使用查询功能,就不可能更新 select2 选项。

What are those buttons supposed to do? If they are used to determine the select options, why not put them outside of the select box, and have them programmatically set the select box data and then open it? I don't understand why you would want to put them on top of the search box. If the user is not supposed to search, you can use the minimumResultsForSearch option to hide the search feature.

这些按钮应该做什么?如果它们用于确定选择选项,为什么不将它们放在选择框之外,并让它们以编程方式设置选择框数据然后打开它?我不明白你为什么要把它们放在搜索框的顶部。如果用户不应该进行搜索,您可以使用 minimumResultsForSearch 选项来隐藏搜索功能。

Edit: How about this...

编辑:这个怎么样...

HTML:

HTML:

<input type="hidden" id="select2" class="select" />

Javascript

Javascript

var data = [{id: 0, text: "Zero"}],
    select = $('#select2');

select.select2({
  query: function(query) {
    query.callback({results: data});
  },
  width: '150px'
});

console.log('Opening select2...');
select.select2('open');

setTimeout(function() {
  console.log('Updating data...');
  data = [{id: 1, text: 'One'}];
}, 1500);

setTimeout(function() {
  console.log('Fake keyup-change...');
  select.data().select2.search.trigger('keyup-change');
}, 3000);

Example: Plunker

示例Plunker

Edit 2:That will at least get it to update the list, however there is still some weirdness if you have entered search text before triggering the keyup-changeevent.

编辑 2:这至少会让它更新列表,但是如果您在触发keyup-change事件之前输入了搜索文本,仍然会有些奇怪。

回答by Andrey Ganzevich

For Select2 4.X

对于 Select2 4.X

var instance = $('#select2Container').data('select2');
var searchVal = instance.dropdown.$search.val();
instance.trigger('query', {term:searchVal});