Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select2 default options with ajax

I have next html structure

<select class="change_item_dropdown_ajax form-control" id="item_id" name="item_id" onchange="updateData(this, this.value, 16)" >
<optgroup label="System Data">
  <option value="17">Test</option>
  <option selected="selected" value="18">System</option>
</optgroup>
</select>

Javascript

 $(".change_item_dropdown_ajax").select2({
        ajax: {
            url: "get_user_items",
            dataType: 'json',
            delay: 250,
            theme: "classic",
            data: function (params) {
                return {
                    q: { name_contains: params.term } // search term
                };
            },
            processResults: function (data) {
                return {
                    results: data
                };
            },
            cache: true
        },
        allowClear: true,
        placeholder: '--- Please select item ---',
        minimumInputLength: 1
    });

I want to make possibility for customer to see some default system options with items <optgroup label="System Data">, but also add ability to make search ajax queries by his own items.

However after binding select2 it doesn't show <optgroup label="System Data">...</optgroup>,

select2 options are empty and it only displays hint "Please enter 1 or more characters".

It's not even clear if it is possible to do, thanks.

UPD Related to select2 removes default options when using ajax

Select-2 removes options when using ajax adapter.

UPD2 github issue https://github.com/select2/select2/issues/3828

like image 633
Fivell Avatar asked Oct 12 '15 12:10

Fivell


People also ask

How do I add options in 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).trigger('change');

What does Select2 () do?

Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options.

What Select2 dropdown?

By default, Select2 will attach the dropdown to the end of the body and will absolutely position it to appear above or below the selection container. Select2 will display the dropdown above the container if there is not enough space below the container, but there is enough space above it.

Why Select2 is not working?

select2 is not a function" jQuery error occurs for multiple reasons: Forgetting to include the select2 library. Loading the select2 library before the jQuery library. Loading the jQuery library twice.


1 Answers

Possible (and, unfortunately, I think the only) solution in this case is to write custom adapter. Something like this:

$.fn.select2.amd.define('select2/data/extended-ajax',['./ajax','../utils','jquery'], function(AjaxAdapter, Utils, $){

  function ExtendedAjaxAdapter ($element,options) {
    //we need explicitly process minimumInputLength value 
    //to decide should we use AjaxAdapter or return defaultResults,
    //so it is impossible to use MinimumLength decorator here
    this.minimumInputLength = options.get('minimumInputLength');
    this.defaultResults     = options.get('defaultResults');

    ExtendedAjaxAdapter.__super__.constructor.call(this,$element,options);
  }

  Utils.Extend(ExtendedAjaxAdapter,AjaxAdapter);

  //override original query function to support default results
  var originQuery = AjaxAdapter.prototype.query;

  ExtendedAjaxAdapter.prototype.query = function (params, callback) {
    var defaultResults = (typeof this.defaultResults == 'function') ? this.defaultResults.call(this) : this.defaultResults;
    if (defaultResults && defaultResults.length && (!params.term || params.term.length < this.minimumInputLength)){
      var processedResults = this.processResults(defaultResults,params.term);
      callback(processedResults);
    }
    else {
      originQuery.call(this, params, callback);
    }
  };

  return ExtendedAjaxAdapter;
});

https://gist.github.com/govorov/3ee75f54170735153349b0a430581195

This adapter first analyzes query term. AjaxAdapter will be kicked in if term is longer than minimumInputValue. Otherwise, defaultResults will be passed to the callback.

To use this adapter, just pass this to select2 options:

dataAdapter: $.fn.select2.amd.require('select2/data/extended-ajax')

I'm not using requireJS or AMD, if you do, use it to require adapter.

like image 108
Stanislav E. Govorov Avatar answered Sep 22 '22 14:09

Stanislav E. Govorov