: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
var checkText = option.text === params.term;
if (checkText || checkChildren) {
var tag = self.createTag(params);
var $option = self.option(tag);
$option.attr('data-pumselect2-tag', true);
self.addOptions([$option]);
self.insertTag(data, tag);
decorated.call(this, params, wrapper);
Tags.prototype.createTag = function (decorated, params) {
var term = $.trim(params.term);
Tags.prototype.insertTag = function (_, data, tag) {
Tags.prototype._removeOldTags = function (_) {
var $options = this.$element.find('option[data-pumselect2-tag]');
$options.each(function () {
S2.define('pumselect2/data/tokenizer',[
function Tokenizer (decorated, $element, options) {
var tokenizer = options.get('tokenizer');
if (tokenizer !== undefined) {
this.tokenizer = tokenizer;
decorated.call(this, $element, options);
Tokenizer.prototype.bind = function (decorated, container, $container) {
decorated.call(this, container, $container);
this.$search = container.dropdown.$search || container.selection.$search ||
$container.find('.pumselect2-search__field');
Tokenizer.prototype.query = function (decorated, params, callback) {
params.term = params.term || '';
var tokenData = this.tokenizer(params, this.options, select);
if (tokenData.term !== params.term) {
// Replace the search term if we have the search box
if (this.$search.length) {
this.$search.val(tokenData.term);
params.term = tokenData.term;
decorated.call(this, params, callback);
Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
var separators = options.get('tokenSeparators') || [];
var createTag = this.createTag || function (params) {
while (i < term.length) {
if ($.inArray(termChar, separators) === -1) {
var part = term.substr(0, i);
var partParams = $.extend({}, params, {
var data = createTag(partParams);
// Reset the term to not include the tokenized portion
term = term.substr(i + 1) || '';
S2.define('pumselect2/data/minimumInputLength',[
function MinimumInputLength (decorated, $e, options) {
this.minimumInputLength = options.get('minimumInputLength');
decorated.call(this, $e, options);
MinimumInputLength.prototype.query = function (decorated, params, callback) {
params.term = params.term || '';
if (params.term.length < this.minimumInputLength) {
this.trigger('results:message', {
message: 'inputTooShort',
minimum: this.minimumInputLength,
decorated.call(this, params, callback);
return MinimumInputLength;
S2.define('pumselect2/data/maximumInputLength',[
function MaximumInputLength (decorated, $e, options) {
this.maximumInputLength = options.get('maximumInputLength');
decorated.call(this, $e, options);
MaximumInputLength.prototype.query = function (decorated, params, callback) {
params.term = params.term || '';
if (this.maximumInputLength > 0 &&
params.term.length > this.maximumInputLength) {
this.trigger('results:message', {
maximum: this.maximumInputLength,
decorated.call(this, params, callback);
return MaximumInputLength;
S2.define('pumselect2/data/maximumSelectionLength',[
function MaximumSelectionLength (decorated, $e, options) {
this.maximumSelectionLength = options.get('maximumSelectionLength');
decorated.call(this, $e, options);
MaximumSelectionLength.prototype.query =
function (decorated, params, callback) {
this.current(function (currentData) {
var count = currentData != null ? currentData.length : 0;
if (self.maximumSelectionLength > 0 &&
count >= self.maximumSelectionLength) {
self.trigger('results:message', {
message: 'maximumSelected',
maximum: self.maximumSelectionLength
decorated.call(self, params, callback);
return MaximumSelectionLength;
S2.define('pumselect2/dropdown',[
function Dropdown ($element, options) {
this.$element = $element;
Dropdown.__super__.constructor.call(this);
Utils.Extend(Dropdown, Utils.Observable);
Dropdown.prototype.render = function () {
'<span class="pumselect2-dropdown">' +
'<span class="pumselect2-results"></span>' +
$dropdown.attr('dir', this.options.get('dir'));
this.$dropdown = $dropdown;
Dropdown.prototype.bind = function () {
// Should be implemented in subclasses
Dropdown.prototype.position = function ($dropdown, $container) {
// Should be implmented in subclasses
Dropdown.prototype.destroy = function () {
// Remove the dropdown from the DOM
S2.define('pumselect2/dropdown/search',[
Search.prototype.render = function (decorated) {
var $rendered = decorated.call(this);
'<span class="pumselect2-search pumselect2-search--dropdown">' +
'<input class="pumselect2-search__field" type="search" tabindex="-1"' +
' autocomplete="off" autocorrect="off" autocapitalize="off"' +
' spellcheck="false" role="textbox" />' +
this.$searchContainer = $search;
this.$search = $search.find('input');
$rendered.prepend($search);
Search.prototype.bind = function (decorated, container, $container) {
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
// Workaround for browsers which do not support the `input` event
// This will prevent double-triggering of events for browsers which support
// both the `keyup` and `input` events.
this.$search.on('input', function (evt) {
// Unbind the duplicated `keyup` event
this.$search.on('keyup input', function (evt) {
container.on('open', function () {
self.$search.attr('tabindex', 0);
window.setTimeout(function () {
container.on('close', function () {
self.$search.attr('tabindex', -1);
container.on('results:all', function (params) {
if (params.query.term == null || params.query.term === '') {
var showSearch = self.showSearch(params);
self.$searchContainer.removeClass('pumselect2-search--hide');
self.$searchContainer.addClass('pumselect2-search--hide');
Search.prototype.handleSearch = function (evt) {
if (!this._keyUpPrevented) {
var input = this.$search.val();
this._keyUpPrevented = false;
Search.prototype.showSearch = function (_, params) {
S2.define('pumselect2/dropdown/hidePlaceholder',[
function HidePlaceholder (decorated, $element, options, dataAdapter) {
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
decorated.call(this, $element, options, dataAdapter);
HidePlaceholder.prototype.append = function (decorated, data) {
data.results = this.removePlaceholder(data.results);
decorated.call(this, data);
HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
if (typeof placeholder === 'string') {
HidePlaceholder.prototype.removePlaceholder = function (_, data) {
var modifiedData = data.slice(0);
for (var d = data.length - 1; d >= 0; d--) {
if (this.placeholder.id === item.id) {
modifiedData.splice(d, 1);
S2.define('pumselect2/dropdown/infiniteScroll',[
function InfiniteScroll (decorated, $element, options, dataAdapter) {
decorated.call(this, $element, options, dataAdapter);
this.$loadingMore = this.createLoadingMore();
InfiniteScroll.prototype.append = function (decorated, data) {
this.$loadingMore.remove();
decorated.call(this, data);
if (this.showLoadingMore(data)) {
this.$results.append(this.$loadingMore);
InfiniteScroll.prototype.bind = function (decorated, container, $container) {
decorated.call(this, container, $container);
container.on('query', function (params) {
self.lastParams = params;
container.on('query:append', function (params) {
self.lastParams = params;
this.$results.on('scroll', function () {
var isLoadMoreVisible = $.contains(
document.documentElement,
if (self.loading || !isLoadMoreVisible) {
var currentOffset = self.$results.offset().top +
self.$results.outerHeight(false);
var loadingMoreOffset = self.$loadingMore.offset().top +
self.$loadingMore.outerHeight(false);
if (currentOffset + 50 >= loadingMoreOffset) {