I have come across the same problem recently and managed to solve the solution by writing a custom adaptor.
Here is my solution for select2 v4x
$.fn.select2.amd.define("select2/data/customArray", ['select2/data/array','select2/utils' ], function(ArrayAdapter, Utils) { function CustomArrayAdapter ($element, options) { var data = options.get("data"); var pageLength = options.get("pageLength"); this._data = data ? Array.from(data) : this._items($element); this._pageLength = pageLength || 25; CustomArrayAdapter.__super__.constructor.call(this, $element, options); }; Utils.Extend(CustomArrayAdapter, ArrayAdapter); CustomArrayAdapter.prototype.query = function (params, callback) { var pageLength = this._pageLength; var page = params.page || 1; var term = params.term; var pagedData = []; var data = this._data; if (!!term) { data = data.filter(function (elemData) { return (elemData.text.toLowerCase().indexOf(term.toLowerCase()) > -1) }); } pagedData = data.slice( (page - 1) * pageLength, page * pageLength ); callback({ results: pagedData, pagination: { more: data.length >= (page * pageLength) } }); }; CustomArrayAdapter.prototype._items = function($element) { var data = []; var self = this; var $options = $element.children(); $options.each(function () { if ( this.tagName.toLowerCase() !== 'option'&& this.tagName.toLowerCase() !== 'optgroup' ) { return; } var $option = $(this); var option = self.item($option); data.push(option); }); return data; } return CustomArrayAdapter; });
Now this one handles the pagination and searching for simple use cases. However, the
pagination would not simply work because the results should be properly handled by select2.
If we are using ajax data the default adaptors handle that, in our case we need to handle that ourselves.
So you would initialize your select2 with the following options.
$('select[name="related_cities[]"]').select2({ pageLength: 15, dataAdapter: $.fn.select2.amd.require('select2/data/customArray'), resultsAdapter: $.fn.select2.amd.require( ['select2/utils','select2/results','select2/dropdown/infiniteScroll' ], function(Utils, ResultsList, InfiniteScroll) { var CustomResultsList = ResultsList; CustomResultsList = Utils.Decorate( CustomResultsList, InfiniteScroll ); // If you want additional support functionalities // you would decorate this with the corresponding decorators. // please refer to the advanced section of select2 documentation return CustomResultsList; } )});