Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically add item to jQuery Select2 control that uses AJAX

I have a jQuery Select2 control that uses AJAX to populate:

<input type="text" name="select2" id="select2" style='width:400px' value="999">

var initialSelection = { id: '999', text:"Some initial option"};

$("#select2").select2({
    placeholder: "Select Option",
    minimumInputLength: 2,
    ajax: { 
        url: "/servletToGetMyData",
        dataType: 'json',
        data: function (term, page) { return { term: term }; },
        results: function (data, page) {  return { results: data.results} }
    },
    initSelection : function(element, callback){ callback(initialSelection); },     
    escapeMarkup: function (m) { return m; }
}); 

The AJAX links to a database of possible options and as you can see requires two characters of input.

The problem is the user can use a dialog to add a new option if the option doesn't exist in the database. Upon return from that dialog, I try:

var o = $("<option/>", {value: newID, text: newText});
$('#select2').append(o);
$('#select2 option[value="' + newID + '"]').prop('selected',true);
$('#select2').trigger('change');

But it doesn't work. The same exact code works for non-AJAX Select2 boxes. I've tried various alternatives, like using $('#select2').select2("val", newID); but it doesn't work.

I've even tried completely deleting the Select2 control. However, $('#select2').remove() only removes the original <input> field but leaves the Select2 control lingering around. Note that the page has more than one Select2 control, so I can't use a class selector for Select2 controls as it will remove other controls that I need.

Any idea how to either a) dynamically add an option to a Select2 control that uses AJAX; or b) completely delete a Select2 control so that it can be programmatically added back? Or any other solution...

Edit I found another question that shows how to remove a select2 element, using .select2("destroy"). This works but is, in my opinion, sub-optimal. I would much prefer to be able to just add the option than to destroy and re-create the select2.

like image 904
Bumptious Q Bangwhistle Avatar asked Aug 21 '14 14:08

Bumptious Q Bangwhistle


People also ask

How do I create a Select2 dynamically?

Select2 jQuery plugin is easy to add on the <select > element. Need to call the select2() method on the selector to initialize. If you adding select2 on a class or select element and when you add an element dynamically then select2 is not initialized on that element.

How do you add a value to Select2?

New options can be added to a Select2 control programmatically by creating a new Javascript Option object and appending it to the control: var data = { id: 1, text: 'Barn owl' }; var newOption = new Option(data. text, data.id, false, false); $('#mySelect2'). append(newOption).

How do I add options to a Dropdownlist using jQuery?

Method 1: Append the option tag to the select box The option to be added is created like a normal HTML string. The select box is selected with the jQuery selector and this option is added with the append() method. The append() method inserts the specified content as the last child of the jQuery collection.

What is initSelection in Select2?

In the past, Select2 required an option called initSelection that was defined whenever a custom data source was being used, allowing for the initial selection for the component to be determined. This has been replaced by the current method on the data adapter.


9 Answers

This is a lot easier to do starting in select2 v4. You can create a new Option, and append it to the select element directly. See my codepen or the example below:

$(document).ready(function() {
    $("#state").select2({
      tags: true
    });
      
    $("#btn-add-state").on("click", function(){
      var newStateVal = $("#new-state").val();
      // Set the value, creating a new option if necessary
      if ($("#state").find("option[value=" + newStateVal + "]").length) {
        $("#state").val(newStateVal).trigger("change");
      } else { 
        // Create the DOM option that is pre-selected by default
        var newState = new Option(newStateVal, newStateVal, true, true);
        // Append it to the select
        $("#state").append(newState).trigger('change');
      } 
    });  
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.min.css" rel="stylesheet"/>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js"></script>


<select id="state" class="js-example-basic-single" type="text" style="width:90%">
  <option value="AL">Alabama</option>
  <option value="WY">Wyoming</option>
</select>
<br>
<br>
<input id="new-state" type="text" />
<button type="button" id="btn-add-state">Set state value</button>

Hint: try entering existing values into the text box, like "AL" or "WY". Then try adding some new values.

like image 200
alexw Avatar answered Oct 14 '22 04:10

alexw


This provided a simple solution: Set data in Select2 after insert with AJAX

$("#select2").select2('data', {id: newID, text: newText});      
like image 43
Bumptious Q Bangwhistle Avatar answered Oct 14 '22 03:10

Bumptious Q Bangwhistle


In case of Select2 Version 4+

it has changed syntax and you need to write like this:

// clear all option
$('#select_with_blank_data').html('').select2({data: [{id: '', text: ''}]});

// clear and add new option
$("#select_with_data").html('').select2({data: [
 {id: '', text: ''},
 {id: '1', text: 'Facebook'},
 {id: '2', text: 'Youtube'},
 {id: '3', text: 'Instagram'},
 {id: '4', text: 'Pinterest'}]});



//  append option
$("#select_with_data").append('<option value="5">Twitter</option>');
$("#select_with_data").val('5');
$("#select_with_data").trigger('change');
like image 28
Sruit A.Suk Avatar answered Oct 14 '22 04:10

Sruit A.Suk


In Select2 4.0.2

$("#yourId").append("<option value='"+item+"' selected>"+item+"</option>");
$('#yourId').trigger('change'); 
like image 24
Digvijay Avatar answered Oct 14 '22 03:10

Digvijay


I have resolved issue with the help of this link http://www.bootply.com/122726. hopefully will help you

Add option in select2 jquery and bind your ajax call with created link id(#addNew) for new option from backend. and the code

 $.getScript('http://ivaynberg.github.io/select2/select2-3.4.5/select2.js',function(){

  $("#mySel").select2({
    width:'240px',
    allowClear:true,
    formatNoMatches: function(term) {
        /* customize the no matches output */
        return "<input class='form-control' id='newTerm' value='"+term+"'><a href='#' id='addNew' class='btn btn-default'>Create</a>"
    }
  })
  .parent().find('.select2-with-searchbox').on('click','#addNew',function(){
    /* add the new term */
    var newTerm = $('#newTerm').val();
    //alert('adding:'+newTerm);
    $('<option>'+newTerm+'</option>').appendTo('#mySel');
    $('#mySel').select2('val',newTerm); // select the new term
    $("#mySel").select2('close');       // close the dropdown
  })

});



<div class="container">
    <h3>Select2 - Add new term when no search matches</h3>
    <select id="mySel">
        <option>One</option>
        <option>Two</option>
        <option>Three</option>
        <option>Four</option>
        <option>Five</option>
        <option>Six</option>
        <option>Twenty Four</option>
    </select>
    <br>
    <br>
</div>
like image 26
Suneel Avatar answered Oct 14 '22 04:10

Suneel


Extending on Bumptious Q Bangwhistle's answer:

$('#select2').append($('<option>', { 
    value: item,
    text : item 
})).select2();

This would add the new options into the <select> tags and lets select2 re-render it.

like image 34
hareluya86 Avatar answered Oct 14 '22 03:10

hareluya86


I did it this way and it worked for me like a charm.

var data = [{ id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 2, 

    text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' }];

    $(".js-example-data-array").select2({
      data: data
    })
like image 38
Chaudhry Waqas Avatar answered Oct 14 '22 05:10

Chaudhry Waqas


$("#my_select").select2('destroy').empty().select2({data: [{id: 1, text: "new_item"}]});
like image 23
Musznik Avatar answered Oct 14 '22 04:10

Musznik


To get dynamic tagging to work with ajax, here's what I did.

Select2 version 3.5

This is easy in version 3.5 because it offers the createSearchChoice hook. It even works for multiple select, as long as multiple: true and tags: true are set.

HTML

<input type="hidden" name="locations" value="Whistler, BC" />

JS

$('input[name="locations"]').select2({
  tags: true,
  multiple: true,
  createSearchChoice: function(term, data) {
    if (!data.length)
      return { id: term, text: term };
    },
  ajax: {
    url: '/api/v1.1/locations',
    dataType: 'json'
  }
});

The idea here is to use select2's createSearchChoice hook which passes you both the term that the user entered and the ajax response (as data). If ajax returns an empty list, then tell select2 to offer the user-entered term as an option.

Demo: https://johnny.netlify.com/select2-examples/version3


Select2 version 4.X

Version 4.X doesn't have a createSearchChoice hook anymore, but here's how I did the same thing.

HTML

  <select name="locations" multiple>
    <option value="Whistler, BC" selected>Whistler, BC</option>
  </select>

JS

$('select[name="locations"]').select2({
  ajax: {
    url: '/api/v1.1/locations',
    dataType: 'json',
    data: function(params) {
      this.data('term', params.term);
      return params;
    },
    processResults: function(data) {
      if (data.length)
        return {
          results: data
        };
      else
        return {
          results: [{ id: this.$element.data('term'), text: this.$element.data('term') }]
        };
    }
  }
});

The ideas is to stash the term that the user typed into jQuery's data store inside select2's data hook. Then in select2's processResults hook, I check if the ajax response is empty. If it is, I grab the stashed term that the user typed and return it as an option to select2.

Demo: https://johnny.netlify.com/select2-examples/version4

like image 45
Johnny Oshika Avatar answered Oct 14 '22 03:10

Johnny Oshika