Using select2 version 4
  • Custom data loader
  • Infinite scrolling
  • Setting values programmatically

$.fn.select2.amd.require([
                'select2/data/array',
                'select2/utils'], function(select2ArrayData, select2Utils) {

  var CustomData = function($element, options) {
    CustomData.__super__.constructor.call(this, $element, options);
  };

  select2Utils.Extend(CustomData, select2ArrayData);

  CustomData.prototype.current = function(callback) {
    var $element = this.$element;
    var currentVal = $element.val();
    // - do whatever you need to load the data needed to create data objects

    // callback with array of data objects
    callback([{id: '1', text: 'result 1'}, {id: '3', text: 'result 3'}]); 
  };

  CustomData.prototype.query = function(params, callback) {
    var searchTerm = params.term;
    var page = params.page || 1;

    // - do whatever you need to get your data -

    var resp = {
      // these are your results
      results: [
        {id: '1', text: 'result 1'}, 
        {id: '2', text: 'result 2'}
      ],
      pagination: {
        // this means there are additional pages to load, set to false if not
        more: true 
      }
    };

    callback(resp);
  };

  var attrs = {};

  attrs.dataAdapter = CustomData;
  attrs.ajax = {}; // this trick is important to allow for infinite scrolling

  attrs.multiple = true;


  // the $('.some-select') should return a SELECT element
  var $select = $('.some-select').select2(attrs); 


  // Now suppose you want to set some values on your select2
  // don't forget to add 'option' tags

  var values = ['1', '3'];

  // this step is really important!
  $select.find('option').remove();
  for(var i = 0, len = values.length; i < len; i++) {
    $select.append('<option value="' + values[i] + '" selected="selected"></option>');
  }
  
  // set the values and trigger the change event to select2 knows about it
  $select.val(values).trigger("change"); 

});