以编程方式设置Select2 ajax的值

时间:2022-11-27 19:32:33

I have a Select2 auto-complete input (built via SonataAdmin), but cannot for the life of me figure out how to programmatically set it to a known key/value pair.

我有一个Select2自动完成的输入(通过SonataAdmin构建),但是我一辈子也搞不清如何以编程方式将它设置为一个已知的键/值对。

There's a JS Fiddle here that shows roughly what I have. What I want to know is what function I can attach to the button so that

这里有个JS文件,大致显示了我的内容。我想知道的是我可以把什么函数附加到这个按钮上

  • the Select2 field shows the text "NEW VALUE" to the user, and
  • Select2字段向用户显示文本“NEW VALUE”,并
  • the Select2 field will submit a value of "1" when the form is sent to the server
  • 当表单发送到服务器时,Select2字段将提交一个值“1”

I have tried all sorts of combinations of jQuery and Select2 data and val methods, called against various inputs on the page, but nothing seems to work... surely there's some way to do this?

我尝试过jQuery、Select2数据和val方法的各种组合,针对页面上的各种输入进行调用,但似乎什么都不管用……肯定有办法做到这一点?

-- Edit --

——编辑

The accepted answer below is very useful, helps shed some light on the right way to initialise the selection and explains what initSelection is for.

下面被接受的答案非常有用,有助于阐明初始化选择的正确方法,并解释initSelection的用途。

Having said that, it seems that my biggest mistake here was the way I was trying to trigger the change.

话虽如此,我最大的错误似乎是我试图引发改变的方式。

I was using:

我用:

$(element).select2('data', newObject).trigger('change');

But this results in an empty add object inside select2's change event.

但是这会导致select2的更改事件中出现一个空的add对象。

If, instead, you use:

相反,如果你使用:

$(element).select2('data', newObject, true);

then the code works as it should, with the newObject available in select2's change event and the values being set correctly.

然后,代码可以正常工作,在select2的更改事件中可用newObject,并且正确设置值。

I hope this extra information helps somebody else!

我希望这个额外的信息能帮助别人!

11 个解决方案

#1


25  

Note: The Question and this Answer are for Select2 v3. Select2 v4 has a very different API than v3.

注意:这个问题和这个答案是关于Select2 v3的。Select2 v4与v3有非常不同的API。

I think the problem is the initSelection function. Are you using that function to set the initial value? I know the Select2 documentation makes it sound like that is it's purpose, but it also says "Essentially this is an id->object mapping function," and that is not how you have implemented it.

我认为问题在于initSelection函数。你用那个函数来设置初始值吗?我知道Select2文档让它听起来像是它的目的,但它也说“本质上这是一个id->对象映射函数”,而这不是你实现它的方式。

For some reason the call to .trigger('change') causes the initSelection function to get called, which changes the selected value back to "ENABLED_FROM_JS".

出于某种原因,对.trigger(“change”)的调用导致调用initSelection函数,该函数将选中的值更改为“ENABLED_FROM_JS”。

Try getting rid of the initSelection function and instead set the initial value using:

尝试去掉initSelection函数,使用以下方法设置初始值:

autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});

jsfiddle

jsfiddle

Note: The OP has supplied the formatResult and formatSelection options. As supplied, those callback functions expect the items to have a "label" property, rather than a "text" property. For most users, it should be:

注意:OP提供了formatResult和formatSelection选项。如前所述,这些回调函数期望项具有“label”属性,而不是“text”属性。对于大多数用户,它应该是:

autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});

More info on the initSelection function:

更多关于initSelection功能的信息:

If you search through the Select2 documentation for "initSelection", you will see that it is used when the element has an initial value and when the element's .val() function is called. That is because those values consist of only an id and Select2 needs the entire data object (partly so it can display the correct label).

如果您在Select2文档中搜索“initSelection”,您将看到,当元素具有初始值时,以及当元素的.val()函数被调用时,都会使用它。这是因为这些值只包含一个id, Select2需要整个数据对象(部分原因是它可以显示正确的标签)。

If the Select2 control was displaying a static list, the initSelection function would be easy to write (and it seems like Select2 could supply it for you). In that case, the initSelection function would just have to look up the id in the data list and return the corresponding data object. (I say "return" here, but it doesn't really return the data object; it passes it to a callback function.)

如果Select2控件显示的是静态列表,那么initSelection函数将很容易编写(似乎Select2可以为您提供它)。在这种情况下,initSelection函数只需在数据列表中查找id并返回相应的数据对象。(这里我说“return”,但它并没有返回数据对象;它将它传递给回调函数)

In your case, you probably don't need to supply the initSelection function since your element does not have an initial value (in the html) and you are not going to call its .val() method. Just keep using the .select2('data', ...) method to set values programmatically.

在您的例子中,您可能不需要提供initSelection函数,因为您的元素没有初始值(在html中),并且您不会调用它的.val()方法。只需继续使用.select2('data',…)方法以编程方式设置值。

If you were to supply an initSelection function for an autocomplete (that uses ajax), it would probably need to make an ajax call to build the data object.

如果要为自动完成(使用ajax)提供一个initSelection函数,可能需要使用ajax调用来构建数据对象。

#2


29  

Note this was tested with version 4+

注意,这是用版本4+测试的

I was finally able to make progress after finding this discussion: https://groups.google.com/forum/#!topic/select2/TOh3T0yqYr4

在找到这个讨论之后,我终于取得了进展:https://groups.google.com/forum/#!topic/select2/TOh3T0yqYr4

The last comment notes a method that I was able to use successfully.

最后的注释指出了一个我能够成功使用的方法。

Example:

例子:

$("#selectelement").select2("trigger", "select", {
    data: { id: "5" }
});

This seems to be enough information for it to match the ajax data, and set the value correctly. This helped immensely with Custom Data Adapters.

这似乎足以让它匹配ajax数据并正确设置值。这极大地帮助了定制数据适配器。

#3


10  

To set initial values you need to add the necessary options tag to the select element with jQuery, then define these options as selected with select2's val method and finally trigger select2's 'change' event.

要设置初始值,您需要使用jQuery向select元素添加必要的选项标记,然后使用select2的val方法定义这些选项,最后触发select2的“change”事件。

1.-$('#selectElement').append('<option value=someID>optionText</option>');
2.-$('#selectElement').select2('val', someID, true);

The third boolean argument tells select2 to trigger the change event.

第三个布尔参数告诉select2触发更改事件。

For more info, see https://github.com/select2/select2/issues/3057

有关更多信息,请参见https://github.com/select2/select2/es/3057。

#4


6  

Be carreful, there is a mistake in "validated" comment.

请注意,“验证”评论中有一个错误。

autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});

The correct way is

正确的方法是

autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});

Use text instead of label

使用文本而不是标签

#5


3  

from their examples https://select2.github.io/examples.html

从https://select2.github.io/examples.html的例子

Programmatic access:

编程访问:

var $example = $(".js-example-programmatic").select2();
var $exampleMulti = $(".js-example-programmatic-multi").select2();
$(".js-programmatic-set-val").on("click", function () { $example.val("CA").trigger("change"); });
$(".js-programmatic-open").on("click", function () { $example.select2("open"); });
$(".js-programmatic-close").on("click", function () { $example.select2("close"); });
$(".js-programmatic-init").on("click", function () { $example.select2(); });
$(".js-programmatic-destroy").on("click", function () { $example.select2("destroy"); });
$(".js-programmatic-multi-set-val").on("click", function () { $exampleMulti.val(["CA", "AL"]).trigger("change"); });
$(".js-programmatic-multi-clear").on("click", function () { $exampleMulti.val(null).trigger("change"); });

#6


1  

If you remove the .trigger('change') from your fiddle it logs Object {id: 1, label: "NEW VALUE"} (need to click twice since the logging is before the value change). Is that what you're looking for?

如果您从小提琴中删除.trigger(“change”),它会记录对象{id: 1,标签:“NEW VALUE”}(需要单击两次,因为日志记录在值更改之前)。这就是你要找的吗?

#7


1  

When using select2 with multiple option, use this construction:

当使用带有多个选项的select2时,使用以下结构:

$(element).select2("data", $(element).select2("data").concat(newObject), true);

jqueryselect2multiplesetconcatenation

#8


1  

this is it:

就是这样:

$("#tag").select2('data', { id:8, title: "Hello!"});

#9


1  

With Select2 version 4+, there is actually nothing special you need to do. Standard jQuery with a 'change' event trigger at the end will work.

对于Select2 version 4+,实际上不需要做什么特别的事情。带有“更改”事件触发器的标准jQuery将工作。

var $select = $("#field");
var items = {id: 1, text: "Name"}; // From AJAX etc
var data = $select.val() || [];    // If you want to merge with existing

$(items).each(function () {
  if(!$select.find("option[value='" + this.id + "']").length) {
    $select.append(new Option(this.text, this.id, true, true));
  }
  data.push(this.id);
});

$select.val(data).trigger('change'); // Standard event notifies select2

There is a basic example in the Select2 documentation: https://select2.org/programmatic-control/add-select-clear-items

Select2文档中有一个基本示例:https://select2.org/programmaticcontrol/add -select-clear-items

#10


0  

FOR VERSION 3.5.3

版本3.5.3

    $(".select2").select2('data',{id:taskid,text:taskname}).trigger('change');

Based on John S' answer . Just the the above will work however only if while initializing the select2 the initSelection option is not initialized.

根据约翰的回答。但是,只有在初始化select2时,initSelection选项没有初始化时,上述操作才能生效。

$(".select2").select2({
      //some setup
})

#11


0  

All you have to do is set the value and then execute: $ ('#myselect').select2 (); or $ ('select').select2 ();. And everything is updated very well.

您只需设置值,然后执行:$ ('#myselect')。select2();美元(的选择)。select2();。一切都更新得很好。

#1


25  

Note: The Question and this Answer are for Select2 v3. Select2 v4 has a very different API than v3.

注意:这个问题和这个答案是关于Select2 v3的。Select2 v4与v3有非常不同的API。

I think the problem is the initSelection function. Are you using that function to set the initial value? I know the Select2 documentation makes it sound like that is it's purpose, but it also says "Essentially this is an id->object mapping function," and that is not how you have implemented it.

我认为问题在于initSelection函数。你用那个函数来设置初始值吗?我知道Select2文档让它听起来像是它的目的,但它也说“本质上这是一个id->对象映射函数”,而这不是你实现它的方式。

For some reason the call to .trigger('change') causes the initSelection function to get called, which changes the selected value back to "ENABLED_FROM_JS".

出于某种原因,对.trigger(“change”)的调用导致调用initSelection函数,该函数将选中的值更改为“ENABLED_FROM_JS”。

Try getting rid of the initSelection function and instead set the initial value using:

尝试去掉initSelection函数,使用以下方法设置初始值:

autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});

jsfiddle

jsfiddle

Note: The OP has supplied the formatResult and formatSelection options. As supplied, those callback functions expect the items to have a "label" property, rather than a "text" property. For most users, it should be:

注意:OP提供了formatResult和formatSelection选项。如前所述,这些回调函数期望项具有“label”属性,而不是“text”属性。对于大多数用户,它应该是:

autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});

More info on the initSelection function:

更多关于initSelection功能的信息:

If you search through the Select2 documentation for "initSelection", you will see that it is used when the element has an initial value and when the element's .val() function is called. That is because those values consist of only an id and Select2 needs the entire data object (partly so it can display the correct label).

如果您在Select2文档中搜索“initSelection”,您将看到,当元素具有初始值时,以及当元素的.val()函数被调用时,都会使用它。这是因为这些值只包含一个id, Select2需要整个数据对象(部分原因是它可以显示正确的标签)。

If the Select2 control was displaying a static list, the initSelection function would be easy to write (and it seems like Select2 could supply it for you). In that case, the initSelection function would just have to look up the id in the data list and return the corresponding data object. (I say "return" here, but it doesn't really return the data object; it passes it to a callback function.)

如果Select2控件显示的是静态列表,那么initSelection函数将很容易编写(似乎Select2可以为您提供它)。在这种情况下,initSelection函数只需在数据列表中查找id并返回相应的数据对象。(这里我说“return”,但它并没有返回数据对象;它将它传递给回调函数)

In your case, you probably don't need to supply the initSelection function since your element does not have an initial value (in the html) and you are not going to call its .val() method. Just keep using the .select2('data', ...) method to set values programmatically.

在您的例子中,您可能不需要提供initSelection函数,因为您的元素没有初始值(在html中),并且您不会调用它的.val()方法。只需继续使用.select2('data',…)方法以编程方式设置值。

If you were to supply an initSelection function for an autocomplete (that uses ajax), it would probably need to make an ajax call to build the data object.

如果要为自动完成(使用ajax)提供一个initSelection函数,可能需要使用ajax调用来构建数据对象。

#2


29  

Note this was tested with version 4+

注意,这是用版本4+测试的

I was finally able to make progress after finding this discussion: https://groups.google.com/forum/#!topic/select2/TOh3T0yqYr4

在找到这个讨论之后,我终于取得了进展:https://groups.google.com/forum/#!topic/select2/TOh3T0yqYr4

The last comment notes a method that I was able to use successfully.

最后的注释指出了一个我能够成功使用的方法。

Example:

例子:

$("#selectelement").select2("trigger", "select", {
    data: { id: "5" }
});

This seems to be enough information for it to match the ajax data, and set the value correctly. This helped immensely with Custom Data Adapters.

这似乎足以让它匹配ajax数据并正确设置值。这极大地帮助了定制数据适配器。

#3


10  

To set initial values you need to add the necessary options tag to the select element with jQuery, then define these options as selected with select2's val method and finally trigger select2's 'change' event.

要设置初始值,您需要使用jQuery向select元素添加必要的选项标记,然后使用select2的val方法定义这些选项,最后触发select2的“change”事件。

1.-$('#selectElement').append('<option value=someID>optionText</option>');
2.-$('#selectElement').select2('val', someID, true);

The third boolean argument tells select2 to trigger the change event.

第三个布尔参数告诉select2触发更改事件。

For more info, see https://github.com/select2/select2/issues/3057

有关更多信息,请参见https://github.com/select2/select2/es/3057。

#4


6  

Be carreful, there is a mistake in "validated" comment.

请注意,“验证”评论中有一个错误。

autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});

The correct way is

正确的方法是

autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});

Use text instead of label

使用文本而不是标签

#5


3  

from their examples https://select2.github.io/examples.html

从https://select2.github.io/examples.html的例子

Programmatic access:

编程访问:

var $example = $(".js-example-programmatic").select2();
var $exampleMulti = $(".js-example-programmatic-multi").select2();
$(".js-programmatic-set-val").on("click", function () { $example.val("CA").trigger("change"); });
$(".js-programmatic-open").on("click", function () { $example.select2("open"); });
$(".js-programmatic-close").on("click", function () { $example.select2("close"); });
$(".js-programmatic-init").on("click", function () { $example.select2(); });
$(".js-programmatic-destroy").on("click", function () { $example.select2("destroy"); });
$(".js-programmatic-multi-set-val").on("click", function () { $exampleMulti.val(["CA", "AL"]).trigger("change"); });
$(".js-programmatic-multi-clear").on("click", function () { $exampleMulti.val(null).trigger("change"); });

#6


1  

If you remove the .trigger('change') from your fiddle it logs Object {id: 1, label: "NEW VALUE"} (need to click twice since the logging is before the value change). Is that what you're looking for?

如果您从小提琴中删除.trigger(“change”),它会记录对象{id: 1,标签:“NEW VALUE”}(需要单击两次,因为日志记录在值更改之前)。这就是你要找的吗?

#7


1  

When using select2 with multiple option, use this construction:

当使用带有多个选项的select2时,使用以下结构:

$(element).select2("data", $(element).select2("data").concat(newObject), true);

jqueryselect2multiplesetconcatenation

#8


1  

this is it:

就是这样:

$("#tag").select2('data', { id:8, title: "Hello!"});

#9


1  

With Select2 version 4+, there is actually nothing special you need to do. Standard jQuery with a 'change' event trigger at the end will work.

对于Select2 version 4+,实际上不需要做什么特别的事情。带有“更改”事件触发器的标准jQuery将工作。

var $select = $("#field");
var items = {id: 1, text: "Name"}; // From AJAX etc
var data = $select.val() || [];    // If you want to merge with existing

$(items).each(function () {
  if(!$select.find("option[value='" + this.id + "']").length) {
    $select.append(new Option(this.text, this.id, true, true));
  }
  data.push(this.id);
});

$select.val(data).trigger('change'); // Standard event notifies select2

There is a basic example in the Select2 documentation: https://select2.org/programmatic-control/add-select-clear-items

Select2文档中有一个基本示例:https://select2.org/programmaticcontrol/add -select-clear-items

#10


0  

FOR VERSION 3.5.3

版本3.5.3

    $(".select2").select2('data',{id:taskid,text:taskname}).trigger('change');

Based on John S' answer . Just the the above will work however only if while initializing the select2 the initSelection option is not initialized.

根据约翰的回答。但是,只有在初始化select2时,initSelection选项没有初始化时,上述操作才能生效。

$(".select2").select2({
      //some setup
})

#11


0  

All you have to do is set the value and then execute: $ ('#myselect').select2 (); or $ ('select').select2 ();. And everything is updated very well.

您只需设置值,然后执行:$ ('#myselect')。select2();美元(的选择)。select2();。一切都更新得很好。