Skip to content

Instantly share code, notes, and snippets.

@govorov
Last active December 6, 2023 23:58
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save govorov/3ee75f54170735153349b0a430581195 to your computer and use it in GitHub Desktop.
Save govorov/3ee75f54170735153349b0a430581195 to your computer and use it in GitHub Desktop.
$.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;
});
@sajumani
Copy link

not working...

can i get complete working example...??

@vanpet
Copy link

vanpet commented Dec 21, 2017

Hi Stanislav,

this looks great but I think it blocks the creation of "tags" (when using the option "tags" : true on Select2). I'm not too sure where and how it fails. Do you have an idea?

@consatan
Copy link

consatan commented Aug 11, 2018

@vanpet

just return a decorated dataAdapter

$.fn.select2.amd.define('select2/data/extended-ajax',['./ajax','./tags','../utils','jquery'], function(AjaxAdapter, Tags, Utils, $){
  // ... no modify
  return Utils.Decorate(ExtendedAjaxAdapter, Tags);
});

full code

$.fn.select2.amd.define('select2/data/extended-ajax',['./ajax', './tags', '../utils', 'module', 'jquery'], function(AjaxAdapter, Tags, Utils, module, $) {
  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);
    }
  };

  if (module.config().tags) {
    return Utils.Decorate(ExtendedAjaxAdapter, Tags);
  } else {
    return ExtendedAjaxAdapter;
  }
});

@consatan
Copy link

consatan commented Aug 11, 2018

@sajumani

base at my previous comment's full code

<script src="/js/select2.full.js"></script>
<script src="/js/select2_extended_ajax_adapter.js"></script>
<select id="myselect"></select>
<script>
(function() {
  $.fn.select2.amd.require.config({
    config: {
      'select2/data/extended-ajax': {
        tags: true
      }
    }
  });

  $('#myselect').select2({
    dataAdapter: $.fn.select2.amd.require('select2/data/extended-ajax'),
    defaultResults: [
      {id: 1, text: 'default_options_1'},
      {id: 2, text: 'default_options_2'},
      {id: 3, text: 'default_options_3'}
    ],
    tags: true,
    ajax: {
      // your ajax options
    }
  });
})();
</script>

@vitorspencer
Copy link

For anyone coming to this with the same issue I had:

when on some cases you don't have a list of default items to show. and you still want to display the default message "Please enter n or more characters", here's a small change to the query prototype in this adapter:

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

    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 data = { results: defaultResults };
            var processedResults = this.processResults(data, params);
            callback(processedResults);
        } else if (params.term && params.term.length >= this.minimumInputLength) {
            originQuery.call(this, params, callback);
        } else {
            this.trigger('results:message', {
                message: 'inputTooShort',
                args: {
                    minimum: this.minimumInputLength,
                    input: '',
                    params: params
                }
            });
        }
    };

    if (module.config().tags) {
        return Utils.Decorate(ExtendedAjaxAdapter, Tags);
    } else {
        return ExtendedAjaxAdapter;
    }
});

@destan
Copy link

destan commented May 8, 2020

For anyone coming to this with the same issue I had:

@vitorspencer thanks for the solution, working good 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment