select2 changing items dynamically
Asked Answered
J

9

72

I have two selects that are linked: Each value of the first select determines which items will be displayed in the second select.

The values of the second select are stored in a two-dimension array:

[ [{"id":1,"text":"a"}, {"id":2,"text":"b"},...],
  [{"id":"1a","text":"aa"},{"id":"1b","text":"ba"},...],
  ...
]

The first select value determines the index to be used to populate the second select. So in a 'change' event on the first I should be able to modify the items select-two contains.

Reading documentation I think I need to use the "data" option... but not shure how as the example loads the array data on initialization and it seems to don't work if I try to do the same after initialization.

HTML

Attribute:
<select name="attribute" id="attribute">
    <option value="0">Color</option>
    <option value="1">Size</option>
</select>

Value:
<select name="value" id="value"></select>

<script>
   var data = [ [{"id":1,"text":"black"}, {"id":2,"text":"blue"},...],
                [{"id":"1","text":"9"},{"id":"1","text":"10"},...],
              ];
   $('#attribute').select2().bind('change', function(){
      // Here I need to change `#value` items.
      $('#value').select2('data',data[$(this).val()]);  // This does not work
   );

   $('#value').select2();
</script>
Julissajulita answered 7/11, 2012 at 10:46 Comment(3)
Show us the code you have already.Adz
Example added, In the comment I tried the $('#value').select2('data',data[$(this).val()]);Julissajulita
#16481410Atrabilious
P
67

I've made an example for you showing how this could be done.

Notice the js but also that I changed #value into an input element

<input id="value" type="hidden" style="width:300px"/>

and that I am triggering the change event for getting the initial values

$('#attribute').select2().on('change', function() {
    $('#value').select2({data:data[$(this).val()]});
}).trigger('change');

Code Example

Edit:

In the current version of select2 the class attribute is being transferred from the hidden input into the root element created by select2, even the select2-offscreen class which positions the element way outside the page limits.

To fix this problem all that's needed is to add removeClass('select2-offscreen') before applying select2 a second time on the same element.

$('#attribute').select2().on('change', function() {
    $('#value').removeClass('select2-offscreen').select2({data:data[$(this).val()]});
}).trigger('change');

I've added a new Code Example to address this issue.

Pelage answered 7/11, 2012 at 12:19 Comment(6)
Simply updating your jsfiddle to current select2 and jquery sources breaks it. (jsfiddle.net/pFY9Z) Do you have an example that would work with the current versions?Photophobia
Why does this not work with multiple select inputs using the same data set? (http://jsfiddle.net/eGXPe/58/)Indra
If you set allowClear: true on dynamically updated select2 fields, the clear button is never enabled.(jsfiddle.net/eGXPe/116) Any ideas how to get about this?Prophet
From the official documentation: "This option only works when the placeholder is specified". This should do it: jsfiddle.net/eGXPe/117 and I've also fixed a minor bug by reseting the value of the second select box whenever the data list changes.Pelage
THIS RESETS YOUR OTHER SELECT2 OPTIONS! In this way you reinitialize select2 with only the data option. I suggest using my answerMalayopolynesian
https://mcmap.net/q/273803/-select2-changing-items-dynamicallyMalayopolynesian
P
37

I'm successfully using the following to update options dynamically:

$control.select2('destroy').empty().select2({data: [{id: 1, text: 'new text'}]});

Palmy answered 30/6, 2016 at 16:21 Comment(2)
One problem I encountered with this is answer is that it will overwrite the empty option/placeholder.Alignment
it does not work if you have initially set your data in html tag with "data-data="Seethrough
P
10

Try using the trigger property for this:

$('select').select2().trigger('change');
Predestinate answered 27/4, 2015 at 1:14 Comment(2)
Please explain what this does and why it answers the question.Granddaughter
first assign new value to select and then trigger change like $('select').select2().trigger('change'); $('select').select2().trigger('change');Caltanissetta
A
7

I fix the lack of example's library here:

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.js">

http://jsfiddle.net/bbAU9/328/

Allpurpose answered 18/3, 2015 at 2:59 Comment(0)
V
4

For v4 this is a known issue that won't be addressed in 4.0 but there is a workaround. Check https://github.com/select2/select2/issues/2830

Vankirk answered 22/6, 2015 at 7:31 Comment(0)
B
4

In my project I use following code:

$('#attribute').select2();
$('#attribute').bind('change', function(){
    var $options = $();
    for (var i in data) {
        $options = $options.add(
            $('<option>').attr('value', data[i].id).html(data[i].text)
        );
    }
    $('#value').html($options).trigger('change');
});

Try to comment out the select2 part. The rest of the code will still work.

Bluetongue answered 24/8, 2015 at 8:51 Comment(0)
P
1
var data = [
    {
        id: 0,
        text: 'enhancement'
    },
    {
        id: 1,
        text: 'bug'
    },
    {
        id: 2,
        text: 'duplicate'
    },
    {
        id: 3,
        text: 'invalid'
    },
    {
        id: 4,
        text: 'wontfix'
    }
];

$('#attribute').select2({
    data: data
});

$("#attribute").select2().val(1).trigger('change');
Purgative answered 12/3, 2023 at 3:39 Comment(1)
This resets the previous select2 options, reinitializing it with only dataMalayopolynesian
S
0

if you are looking a code that is changing another dropdown data by fetching data from server side(Api). You should try this one.

$('#attribute').on('change', function (e) {
        $.post("../api", { id: e.val }).done(resp => {
            $("#value").select2('destroy').empty();
            resp.map(o => $("#value").append("<option value=\"" + o.Value + "\">" + o.Text + "</option>"));
            $("#value").select2();
        });
    });
Silage answered 15/2, 2023 at 9:46 Comment(0)
M
0

You need to add the options to the HTML select, then use .val() to set them

HTML:

<select id="test-select" class="select2">
    <option value="test-value-static">test-value-static</option>
</select>

JS:

const selector = $('#test-select');
//options to be added at runtime
const defaultOptions = ['test-value-1', 'test-value-2']; 
selector.append(
        defaultOptions
            .filter((str) => { //only if not already present
                return !selector.find("option[value=\"" + str + "\"]").length;
            })
            .map((str) => { //generate options html 
                return "<option value=\"" + str + "\">" + str + "</option>";
            })
);
selector
    .val(defaultOptions)
    .trigger('change');
Malayopolynesian answered 24/5 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.