2

I need to update an array data source. Using the reset/clear technique from https://stackoverflow.com/a/28271338/161457 does not clear the options; the control combines them (one, two, three, four in the code snippet). How can I clear the control and reinitialize the options?

$(function () {
  var initialData = [{ id: 1, text: 'one' }, { id: 2, text: 'two' }];
  
  $("#test").select2({
    data: initialData
  });
  
  $('#change').click(function () {
    var newData = [{ id: 3, text: 'three' }, { id: 4, text: 'four' }];
    
    $('#test').val([]);  // Attempt to clear
    
    $("#test").select2({
      data: newData
    });
  });
});
@import url('https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css');
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>

<form>
<select id="test" name="test" multiple="multiple" style="width: 50%"></select>
</form>

<button type="button" id="change">Change</button>
Community
  • 1
  • 1
TrueWill
  • 25,132
  • 10
  • 101
  • 150

2 Answers2

2

Unfortunately, this is not possible with native Select2 functionality, it has to be done somewhat manually.

See this GitHub issue: https://github.com/select2/select2/issues/2830

Essentially, you need to destroy the Select2 instance, then repopulate it again by re-initializing it. The code below is quick and dirty, I'm sure there's a better way to write it:

$(function () {
  var initialData = [{ id: 1, text: 'one' }, { id: 2, text: 'two' }];

  //good practice to cache your jquery objects:
  var $test = $("#test");
  
  $test.select2({
    allowClear: true,
    data: initialData
  });
  
  $('#change').click(function () {
    var newData = [{ id: 3, text: 'three' }, { id: 4, text: 'four' }];

    //clear chosen items
    $test.val("").change();

    //destroy select2
    $test.select2("destroy");        

    //remove options physically from the HTML
    $test.find("option").remove();

    //re-initialize with new data
    $test.select2({
      data: newData
    });
    
  });
});
@import url('https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css');
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>

<form>
<select id="test" name="test" multiple="multiple" style="width: 50%"></select>
</form>

<button type="button" id="change">Change</button>
Sean Kendle
  • 3,538
  • 1
  • 27
  • 34
  • 1
    Wow; it's astonishing that they closed the issue. – TrueWill Dec 20 '16 at 22:05
  • 1
    I thought so, too, seems like a pretty common problem given the number of comments! Although, the fix is pretty easy to accomplish. I would recommend making that a function of its own where you pass in the target object if you plan on using it over and over again in your code. Good luck! – Sean Kendle Dec 20 '16 at 22:06
  • 1
    Yes, I just accepted it. I did find that calling `$("#test").empty()` and then re-initializing it with new data (as you did) appears to clear any existing selection and options. – TrueWill Dec 20 '16 at 22:39
  • 1
    Yeah, I figured it would, just was being thorough. Although, one could argue I was being "wasteful"... good catch! I'm at work and didn't really take a whole lot of time with the code, but glad it works for you! – Sean Kendle Dec 20 '16 at 22:49
1

This is how I do it when I run an AJAX request and fill a select2 with new items:

var categoryGroups = response.data;
$.each(categoryGroups, function (key, categoryGroup) {
    $groupList.append(
        '<option value="' + categoryGroup.id + '">' +
            categoryGroup.name +
         '</option>'
    );
});

$groupList.change();

$groupList is the selector for the select element.

Updated:

An alternative would be to do something like:

$('#test').empty()

$('#test').select2({data: newData})

Davor Minchorov
  • 2,018
  • 1
  • 16
  • 20