1
0
mirror of synced 2025-02-03 21:59:24 +03:00

Added inline searching for multiple selects

This adds a search box to the main container for multiple select
boxes, similar to the what the old version had. This can still be
swapped out such that the search box displays above the results
like it previously did.

The placeholder for multiple selects will also now use the input
attribute of the search box instead of generating a custom element.

This also changes the selector for the search container to
`.select2-search`, which is consistent with the old class and
reduces the complexity of the selectors.

This fixes an issue with how decorators worked, where the constructor
from the parent class would clobber the custom constructor that is
generated for the new decorated class. This has been fixed by
excluding the constructor from the list of fields which are
transferred when decorating classes.
This commit is contained in:
Kevin Brown 2014-11-22 19:21:46 -05:00
parent 2bec6e2579
commit 217cd4cfd0
19 changed files with 730 additions and 87 deletions

30
dist/css/select2.css vendored
View File

@ -26,10 +26,16 @@
user-select: none; user-select: none;
-webkit-user-select: none; } -webkit-user-select: none; }
.select2-container .selection .multiple-select .rendered-selection { .select2-container .selection .multiple-select .rendered-selection {
display: block; display: inline-block;
overflow: hidden; overflow: hidden;
padding-left: 8px; padding-left: 8px;
text-overflow: ellipsis; } text-overflow: ellipsis; }
.select2-container .select2-search-inline {
float: left; }
.select2-container .select2-search-inline input {
border: none;
font-size: 100%;
margin-top: 5px; }
.select2-container .dropdown { .select2-container .dropdown {
background-color: white; background-color: white;
@ -41,12 +47,6 @@
left: -100000px; left: -100000px;
width: 100%; width: 100%;
z-index: 100; } z-index: 100; }
.select2-container .dropdown .search {
display: block;
padding: 4px; }
.select2-container .dropdown .search input {
padding: 4px;
width: 100%; }
.select2-container .dropdown .results { .select2-container .dropdown .results {
display: block; } display: block; }
.select2-container .dropdown .results .options { .select2-container .dropdown .results .options {
@ -59,6 +59,12 @@
-webkit-user-select: none; } -webkit-user-select: none; }
.select2-container .dropdown .results .options .option[aria-selected] { .select2-container .dropdown .results .options .option[aria-selected] {
cursor: pointer; } cursor: pointer; }
.select2-container .select2-search {
display: block;
padding: 4px; }
.select2-container .select2-search input {
padding: 4px;
width: 100%; }
.select2-container.open .dropdown { .select2-container.open .dropdown {
border-top: none; border-top: none;
border-top-left-radius: 0; border-top-left-radius: 0;
@ -81,10 +87,10 @@
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection { .select2-container.select2-theme-default .selection .multiple-select .rendered-selection {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 5px; padding: 0 5px; }
padding-bottom: 0; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .placeholder { .select2-container.select2-theme-default .selection .multiple-select .rendered-selection .placeholder {
color: #999; color: #999;
margin-top: 5px;
float: left; } float: left; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice { .select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice {
background-color: #e4e4e4; background-color: #e4e4e4;
@ -92,7 +98,7 @@
border-radius: 4px; border-radius: 4px;
float: left; float: left;
margin-right: 5px; margin-right: 5px;
margin-bottom: 5px; margin-top: 5px;
padding: 0 5px; } padding: 0 5px; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice .remove { .select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice .remove {
color: #999; color: #999;
@ -104,7 +110,7 @@
.select2-container.select2-theme-default.open .selection .single-select, .select2-container.select2-theme-default.open .selection .multiple-select { .select2-container.select2-theme-default.open .selection .single-select, .select2-container.select2-theme-default.open .selection .multiple-select {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-bottom-right-radius: 0; } border-bottom-right-radius: 0; }
.select2-container.select2-theme-default .dropdown .search input { .select2-container.select2-theme-default .select2-search input {
border: 1px solid #aaa; } border: 1px solid #aaa; }
.select2-container.select2-theme-default .dropdown .results > .options { .select2-container.select2-theme-default .dropdown .results > .options {
max-height: 200px; max-height: 200px;
@ -154,7 +160,7 @@
.select2-container.select2-theme-classic .dropdown { .select2-container.select2-theme-classic .dropdown {
background-color: white; background-color: white;
border-top: none; } border-top: none; }
.select2-container.select2-theme-classic .dropdown .search input { .select2-container.select2-theme-classic .dropdown .select2-search input {
border: 1px solid #aaa; border: 1px solid #aaa;
outline: 0; } outline: 0; }
.select2-container.select2-theme-classic .dropdown .results > .options { .select2-container.select2-theme-classic .dropdown .results > .options {

File diff suppressed because one or more lines are too long

View File

@ -33,6 +33,10 @@ window.$ = window.$ || {};(function() { if ($ && $.fn && $.fn.select2 && $.fn.se
continue; continue;
} }
if (methodName === 'constructor') {
continue;
}
methods.push(methodName); methods.push(methodName);
} }
@ -913,6 +917,15 @@ define('select2/selection/placeholder',[
return placeholder; return placeholder;
}; };
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
return $placeholder;
};
Placeholder.prototype.update = function (decorated, data) { Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = ( var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id data.length == 1 && data[0].id != this.placeholder.id
@ -925,10 +938,7 @@ define('select2/selection/placeholder',[
this.clear(); this.clear();
var $placeholder = this.selectionContainer(); var $placeholder = this.createPlaceholder(this.placeholder);
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder); this.$selection.find('.rendered-selection').append($placeholder);
}; };
@ -936,6 +946,95 @@ define('select2/selection/placeholder',[
return Placeholder; return Placeholder;
}); });
define('select2/selection/search',[
'../utils'
], function (Utils) {
function Search (decorated, $element, options) {
decorated.call(this, $element, options);
}
Search.prototype.render = function (decorated) {
var $search = $(
'<li class="select2-search-inline">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</li>'
);
this.$searchContainer = $search;
this.$search = $search.find('input');
var $rendered = decorated.call(this);
return $rendered;
};
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
this.$search.on('keyup', function (evt) {
self.handleSearch(evt);
});
container.on('open', function () {
self.$search.attr('tabindex', 0);
self.$search.focus();
});
container.on('close', function () {
self.$search.attr('tabindex', -1);
self.$search.val('');
});
this.$search.off('keydown').on('keydown', function (evt) {
evt.stopPropagation();
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
};
Search.prototype.createPlaceholder = function (decorated, placeholder) {
this.$search.attr('placeholder', placeholder.text);
};
Search.prototype.update = function (decorated, data) {
this.$search.attr('placeholder', '');
decorated.call(this, data);
this.$selection.find('.rendered-selection').append(this.$searchContainer);
};
Search.prototype.handleSearch = function (evt) {
if (!this._keyUpPrevented) {
var input = this.$search.val();
this.trigger('query', {
term: input
});
}
this._keyUpPrevented = false;
};
Search.prototype.showSearch = function (_, params) {
return true;
};
return Search;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -2404,8 +2503,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this); var $rendered = decorated.call(this);
var $search = $( var $search = $(
'<span class="search">' + '<span class="select2-search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' + '<input type="search" tabindex="-1" role="textbox" />' +
'</span>' '</span>'
); );
@ -2659,6 +2758,7 @@ define('select2/defaults',[
'./selection/single', './selection/single',
'./selection/multiple', './selection/multiple',
'./selection/placeholder', './selection/placeholder',
'./selection/search',
'./utils', './utils',
'./translation', './translation',
@ -2677,10 +2777,10 @@ define('select2/defaults',[
'./i18n/en' './i18n/en'
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength, SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll, Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) { EnglishTranslation) {
function Defaults () { function Defaults () {
this.reset(); this.reset();
@ -2730,10 +2830,14 @@ define('select2/defaults',[
} }
if (options.dropdownAdapter == null) { if (options.dropdownAdapter == null) {
var SearchableDropdown = Utils.Decorate(Dropdown, Search); if (options.multiple) {
options.dropdownAdapter = Dropdown;
} else {
var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
options.dropdownAdapter = SearchableDropdown; options.dropdownAdapter = SearchableDropdown;
} }
}
if (options.selectionAdapter == null) { if (options.selectionAdapter == null) {
if (options.multiple) { if (options.multiple) {
@ -2749,6 +2853,13 @@ define('select2/defaults',[
Placeholder Placeholder
); );
} }
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {
@ -3073,6 +3184,10 @@ define('select2/core',[
self.close(); self.close();
}); });
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) { this.selection.on('keypress', function (e) {
self.trigger('keypress', e); self.trigger('keypress', e);
}); });

133
dist/js/select2.amd.js vendored
View File

@ -33,6 +33,10 @@ window.$ = window.$ || {};(function() { if ($ && $.fn && $.fn.select2 && $.fn.se
continue; continue;
} }
if (methodName === 'constructor') {
continue;
}
methods.push(methodName); methods.push(methodName);
} }
@ -913,6 +917,15 @@ define('select2/selection/placeholder',[
return placeholder; return placeholder;
}; };
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
return $placeholder;
};
Placeholder.prototype.update = function (decorated, data) { Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = ( var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id data.length == 1 && data[0].id != this.placeholder.id
@ -925,10 +938,7 @@ define('select2/selection/placeholder',[
this.clear(); this.clear();
var $placeholder = this.selectionContainer(); var $placeholder = this.createPlaceholder(this.placeholder);
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder); this.$selection.find('.rendered-selection').append($placeholder);
}; };
@ -936,6 +946,95 @@ define('select2/selection/placeholder',[
return Placeholder; return Placeholder;
}); });
define('select2/selection/search',[
'../utils'
], function (Utils) {
function Search (decorated, $element, options) {
decorated.call(this, $element, options);
}
Search.prototype.render = function (decorated) {
var $search = $(
'<li class="select2-search-inline">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</li>'
);
this.$searchContainer = $search;
this.$search = $search.find('input');
var $rendered = decorated.call(this);
return $rendered;
};
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
this.$search.on('keyup', function (evt) {
self.handleSearch(evt);
});
container.on('open', function () {
self.$search.attr('tabindex', 0);
self.$search.focus();
});
container.on('close', function () {
self.$search.attr('tabindex', -1);
self.$search.val('');
});
this.$search.off('keydown').on('keydown', function (evt) {
evt.stopPropagation();
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
};
Search.prototype.createPlaceholder = function (decorated, placeholder) {
this.$search.attr('placeholder', placeholder.text);
};
Search.prototype.update = function (decorated, data) {
this.$search.attr('placeholder', '');
decorated.call(this, data);
this.$selection.find('.rendered-selection').append(this.$searchContainer);
};
Search.prototype.handleSearch = function (evt) {
if (!this._keyUpPrevented) {
var input = this.$search.val();
this.trigger('query', {
term: input
});
}
this._keyUpPrevented = false;
};
Search.prototype.showSearch = function (_, params) {
return true;
};
return Search;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -2404,8 +2503,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this); var $rendered = decorated.call(this);
var $search = $( var $search = $(
'<span class="search">' + '<span class="select2-search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' + '<input type="search" tabindex="-1" role="textbox" />' +
'</span>' '</span>'
); );
@ -2659,6 +2758,7 @@ define('select2/defaults',[
'./selection/single', './selection/single',
'./selection/multiple', './selection/multiple',
'./selection/placeholder', './selection/placeholder',
'./selection/search',
'./utils', './utils',
'./translation', './translation',
@ -2677,10 +2777,10 @@ define('select2/defaults',[
'./i18n/en' './i18n/en'
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength, SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll, Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) { EnglishTranslation) {
function Defaults () { function Defaults () {
this.reset(); this.reset();
@ -2730,10 +2830,14 @@ define('select2/defaults',[
} }
if (options.dropdownAdapter == null) { if (options.dropdownAdapter == null) {
var SearchableDropdown = Utils.Decorate(Dropdown, Search); if (options.multiple) {
options.dropdownAdapter = Dropdown;
} else {
var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
options.dropdownAdapter = SearchableDropdown; options.dropdownAdapter = SearchableDropdown;
} }
}
if (options.selectionAdapter == null) { if (options.selectionAdapter == null) {
if (options.multiple) { if (options.multiple) {
@ -2749,6 +2853,13 @@ define('select2/defaults',[
Placeholder Placeholder
); );
} }
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {
@ -3073,6 +3184,10 @@ define('select2/core',[
self.close(); self.close();
}); });
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) { this.selection.on('keypress', function (e) {
self.trigger('keypress', e); self.trigger('keypress', e);
}); });

View File

@ -9568,6 +9568,10 @@ define('select2/utils',[], function () {
continue; continue;
} }
if (methodName === 'constructor') {
continue;
}
methods.push(methodName); methods.push(methodName);
} }
@ -10448,6 +10452,15 @@ define('select2/selection/placeholder',[
return placeholder; return placeholder;
}; };
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
return $placeholder;
};
Placeholder.prototype.update = function (decorated, data) { Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = ( var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id data.length == 1 && data[0].id != this.placeholder.id
@ -10460,10 +10473,7 @@ define('select2/selection/placeholder',[
this.clear(); this.clear();
var $placeholder = this.selectionContainer(); var $placeholder = this.createPlaceholder(this.placeholder);
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder); this.$selection.find('.rendered-selection').append($placeholder);
}; };
@ -10471,6 +10481,95 @@ define('select2/selection/placeholder',[
return Placeholder; return Placeholder;
}); });
define('select2/selection/search',[
'../utils'
], function (Utils) {
function Search (decorated, $element, options) {
decorated.call(this, $element, options);
}
Search.prototype.render = function (decorated) {
var $search = $(
'<li class="select2-search-inline">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</li>'
);
this.$searchContainer = $search;
this.$search = $search.find('input');
var $rendered = decorated.call(this);
return $rendered;
};
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
this.$search.on('keyup', function (evt) {
self.handleSearch(evt);
});
container.on('open', function () {
self.$search.attr('tabindex', 0);
self.$search.focus();
});
container.on('close', function () {
self.$search.attr('tabindex', -1);
self.$search.val('');
});
this.$search.off('keydown').on('keydown', function (evt) {
evt.stopPropagation();
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
};
Search.prototype.createPlaceholder = function (decorated, placeholder) {
this.$search.attr('placeholder', placeholder.text);
};
Search.prototype.update = function (decorated, data) {
this.$search.attr('placeholder', '');
decorated.call(this, data);
this.$selection.find('.rendered-selection').append(this.$searchContainer);
};
Search.prototype.handleSearch = function (evt) {
if (!this._keyUpPrevented) {
var input = this.$search.val();
this.trigger('query', {
term: input
});
}
this._keyUpPrevented = false;
};
Search.prototype.showSearch = function (_, params) {
return true;
};
return Search;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -11939,8 +12038,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this); var $rendered = decorated.call(this);
var $search = $( var $search = $(
'<span class="search">' + '<span class="select2-search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' + '<input type="search" tabindex="-1" role="textbox" />' +
'</span>' '</span>'
); );
@ -12194,6 +12293,7 @@ define('select2/defaults',[
'./selection/single', './selection/single',
'./selection/multiple', './selection/multiple',
'./selection/placeholder', './selection/placeholder',
'./selection/search',
'./utils', './utils',
'./translation', './translation',
@ -12212,10 +12312,10 @@ define('select2/defaults',[
'./i18n/en' './i18n/en'
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength, SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll, Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) { EnglishTranslation) {
function Defaults () { function Defaults () {
this.reset(); this.reset();
@ -12265,10 +12365,14 @@ define('select2/defaults',[
} }
if (options.dropdownAdapter == null) { if (options.dropdownAdapter == null) {
var SearchableDropdown = Utils.Decorate(Dropdown, Search); if (options.multiple) {
options.dropdownAdapter = Dropdown;
} else {
var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
options.dropdownAdapter = SearchableDropdown; options.dropdownAdapter = SearchableDropdown;
} }
}
if (options.selectionAdapter == null) { if (options.selectionAdapter == null) {
if (options.multiple) { if (options.multiple) {
@ -12284,6 +12388,13 @@ define('select2/defaults',[
Placeholder Placeholder
); );
} }
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {
@ -12608,6 +12719,10 @@ define('select2/core',[
self.close(); self.close();
}); });
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) { this.selection.on('keypress', function (e) {
self.trigger('keypress', e); self.trigger('keypress', e);
}); });

File diff suppressed because one or more lines are too long

133
dist/js/select2.js vendored
View File

@ -461,6 +461,10 @@ define('select2/utils',[], function () {
continue; continue;
} }
if (methodName === 'constructor') {
continue;
}
methods.push(methodName); methods.push(methodName);
} }
@ -1341,6 +1345,15 @@ define('select2/selection/placeholder',[
return placeholder; return placeholder;
}; };
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
return $placeholder;
};
Placeholder.prototype.update = function (decorated, data) { Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = ( var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id data.length == 1 && data[0].id != this.placeholder.id
@ -1353,10 +1366,7 @@ define('select2/selection/placeholder',[
this.clear(); this.clear();
var $placeholder = this.selectionContainer(); var $placeholder = this.createPlaceholder(this.placeholder);
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder); this.$selection.find('.rendered-selection').append($placeholder);
}; };
@ -1364,6 +1374,95 @@ define('select2/selection/placeholder',[
return Placeholder; return Placeholder;
}); });
define('select2/selection/search',[
'../utils'
], function (Utils) {
function Search (decorated, $element, options) {
decorated.call(this, $element, options);
}
Search.prototype.render = function (decorated) {
var $search = $(
'<li class="select2-search-inline">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</li>'
);
this.$searchContainer = $search;
this.$search = $search.find('input');
var $rendered = decorated.call(this);
return $rendered;
};
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
this.$search.on('keyup', function (evt) {
self.handleSearch(evt);
});
container.on('open', function () {
self.$search.attr('tabindex', 0);
self.$search.focus();
});
container.on('close', function () {
self.$search.attr('tabindex', -1);
self.$search.val('');
});
this.$search.off('keydown').on('keydown', function (evt) {
evt.stopPropagation();
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
};
Search.prototype.createPlaceholder = function (decorated, placeholder) {
this.$search.attr('placeholder', placeholder.text);
};
Search.prototype.update = function (decorated, data) {
this.$search.attr('placeholder', '');
decorated.call(this, data);
this.$selection.find('.rendered-selection').append(this.$searchContainer);
};
Search.prototype.handleSearch = function (evt) {
if (!this._keyUpPrevented) {
var input = this.$search.val();
this.trigger('query', {
term: input
});
}
this._keyUpPrevented = false;
};
Search.prototype.showSearch = function (_, params) {
return true;
};
return Search;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -2832,8 +2931,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this); var $rendered = decorated.call(this);
var $search = $( var $search = $(
'<span class="search">' + '<span class="select2-search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' + '<input type="search" tabindex="-1" role="textbox" />' +
'</span>' '</span>'
); );
@ -3087,6 +3186,7 @@ define('select2/defaults',[
'./selection/single', './selection/single',
'./selection/multiple', './selection/multiple',
'./selection/placeholder', './selection/placeholder',
'./selection/search',
'./utils', './utils',
'./translation', './translation',
@ -3105,10 +3205,10 @@ define('select2/defaults',[
'./i18n/en' './i18n/en'
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength, SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll, Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) { EnglishTranslation) {
function Defaults () { function Defaults () {
this.reset(); this.reset();
@ -3158,10 +3258,14 @@ define('select2/defaults',[
} }
if (options.dropdownAdapter == null) { if (options.dropdownAdapter == null) {
var SearchableDropdown = Utils.Decorate(Dropdown, Search); if (options.multiple) {
options.dropdownAdapter = Dropdown;
} else {
var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
options.dropdownAdapter = SearchableDropdown; options.dropdownAdapter = SearchableDropdown;
} }
}
if (options.selectionAdapter == null) { if (options.selectionAdapter == null) {
if (options.multiple) { if (options.multiple) {
@ -3177,6 +3281,13 @@ define('select2/defaults',[
Placeholder Placeholder
); );
} }
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {
@ -3501,6 +3612,10 @@ define('select2/core',[
self.close(); self.close();
}); });
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) { this.selection.on('keypress', function (e) {
self.trigger('keypress', e); self.trigger('keypress', e);
}); });

File diff suppressed because one or more lines are too long

View File

@ -182,6 +182,10 @@ define([
self.close(); self.close();
}); });
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) { this.selection.on('keypress', function (e) {
self.trigger('keypress', e); self.trigger('keypress', e);
}); });

View File

@ -5,6 +5,7 @@ define([
'./selection/single', './selection/single',
'./selection/multiple', './selection/multiple',
'./selection/placeholder', './selection/placeholder',
'./selection/search',
'./utils', './utils',
'./translation', './translation',
@ -23,10 +24,10 @@ define([
'./i18n/en' './i18n/en'
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength, SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll, Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) { EnglishTranslation) {
function Defaults () { function Defaults () {
this.reset(); this.reset();
@ -76,10 +77,14 @@ define([
} }
if (options.dropdownAdapter == null) { if (options.dropdownAdapter == null) {
var SearchableDropdown = Utils.Decorate(Dropdown, Search); if (options.multiple) {
options.dropdownAdapter = Dropdown;
} else {
var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
options.dropdownAdapter = SearchableDropdown; options.dropdownAdapter = SearchableDropdown;
} }
}
if (options.selectionAdapter == null) { if (options.selectionAdapter == null) {
if (options.multiple) { if (options.multiple) {
@ -95,6 +100,13 @@ define([
Placeholder Placeholder
); );
} }
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {

View File

@ -7,8 +7,8 @@ define([
var $rendered = decorated.call(this); var $rendered = decorated.call(this);
var $search = $( var $search = $(
'<span class="search">' + '<span class="select2-search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' + '<input type="search" tabindex="-1" role="textbox" />' +
'</span>' '</span>'
); );

View File

@ -18,6 +18,15 @@ define([
return placeholder; return placeholder;
}; };
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
return $placeholder;
};
Placeholder.prototype.update = function (decorated, data) { Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = ( var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id data.length == 1 && data[0].id != this.placeholder.id
@ -30,10 +39,7 @@ define([
this.clear(); this.clear();
var $placeholder = this.selectionContainer(); var $placeholder = this.createPlaceholder(this.placeholder);
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder); this.$selection.find('.rendered-selection').append($placeholder);
}; };

88
src/js/select2/selection/search.js vendored Normal file
View File

@ -0,0 +1,88 @@
define([
'../utils'
], function (Utils) {
function Search (decorated, $element, options) {
decorated.call(this, $element, options);
}
Search.prototype.render = function (decorated) {
var $search = $(
'<li class="select2-search-inline">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</li>'
);
this.$searchContainer = $search;
this.$search = $search.find('input');
var $rendered = decorated.call(this);
return $rendered;
};
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
decorated.call(this, container, $container);
this.$search.on('keydown', function (evt) {
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
this.$search.on('keyup', function (evt) {
self.handleSearch(evt);
});
container.on('open', function () {
self.$search.attr('tabindex', 0);
self.$search.focus();
});
container.on('close', function () {
self.$search.attr('tabindex', -1);
self.$search.val('');
});
this.$search.off('keydown').on('keydown', function (evt) {
evt.stopPropagation();
self.trigger('keypress', evt);
self._keyUpPrevented = evt.isDefaultPrevented();
});
};
Search.prototype.createPlaceholder = function (decorated, placeholder) {
this.$search.attr('placeholder', placeholder.text);
};
Search.prototype.update = function (decorated, data) {
this.$search.attr('placeholder', '');
decorated.call(this, data);
this.$selection.find('.rendered-selection').append(this.$searchContainer);
};
Search.prototype.handleSearch = function (evt) {
if (!this._keyUpPrevented) {
var input = this.$search.val();
this.trigger('query', {
term: input
});
}
this._keyUpPrevented = false;
};
Search.prototype.showSearch = function (_, params) {
return true;
};
return Search;
});

View File

@ -33,6 +33,10 @@ define([], function () {
continue; continue;
} }
if (methodName === 'constructor') {
continue;
}
methods.push(methodName); methods.push(methodName);
} }

View File

@ -16,16 +16,6 @@
z-index: 100; z-index: 100;
.search {
display: block;
padding: 4px;
input {
padding: 4px;
width: 100%;
}
}
.results { .results {
display: block; display: block;
@ -48,6 +38,16 @@
} }
} }
.select2-search {
display: block;
padding: 4px;
input {
padding: 4px;
width: 100%;
}
}
&.open .dropdown { &.open .dropdown {
border-top: none; border-top: none;
border-top-left-radius: 0; border-top-left-radius: 0;

View File

@ -11,10 +11,20 @@
-webkit-user-select: none; -webkit-user-select: none;
.rendered-selection { .rendered-selection {
display: block; display: inline-block;
overflow: hidden; overflow: hidden;
padding-left: 8px; padding-left: 8px;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
} }
.select2-search-inline {
float: left;
input {
border: none;
font-size: 100%;
margin-top: 5px;
}
}
} }

View File

@ -49,7 +49,7 @@
background-color: $dropdown-bg-color; background-color: $dropdown-bg-color;
border-top: none; border-top: none;
.search { .select2-search {
input { input {
border: 1px solid $border-color; border: 1px solid $border-color;
outline: 0; outline: 0;

View File

@ -23,12 +23,13 @@
.rendered-selection { .rendered-selection {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 5px; padding: 0 5px;
padding-bottom: 0;
.placeholder { .placeholder {
color: #999; color: #999;
margin-top: 5px;
float: left; float: left;
} }
@ -41,7 +42,7 @@
float: left; float: left;
margin-right: 5px; margin-right: 5px;
margin-bottom: 5px; margin-top: 5px;
padding: 0 5px; padding: 0 5px;
.remove { .remove {
@ -70,13 +71,13 @@
} }
} }
.dropdown { .select2-search {
.search {
input { input {
border: 1px solid #aaa; border: 1px solid #aaa;
} }
} }
.dropdown {
.results { .results {
&> .options { &> .options {
max-height: 200px; max-height: 200px;

View File

@ -135,3 +135,55 @@ test('inherited - constructor', function (assert) {
assert.ok(inst.called); assert.ok(inst.called);
assert.ok(inst.inherited); assert.ok(inst.inherited);
}); });
test('inherited - three levels', function (assert) {
function BaseClass (testArgument) {
this.baseCalled = true;
this.baseTestArgument = testArgument;
}
BaseClass.prototype.test = function (a) {
return a + 'c';
};
function MiddleClass (decorated, testArgument) {
this.middleCalled = true;
this.middleTestArgument = testArgument;
decorated.call(this, testArgument);
}
MiddleClass.prototype.test = function (decorated, a) {
return decorated.call(this, a + 'b');
};
function DecoratorClass (decorated, testArgument) {
this.decoratorCalled = true;
this.decoratorTestArgument = testArgument;
decorated.call(this, testArgument);
}
DecoratorClass.prototype.test = function (decorated, a) {
return decorated.call(this, a + 'a');
};
var DecoratedClass = Utils.Decorate(
Utils.Decorate(BaseClass, MiddleClass),
DecoratorClass
);
var inst = new DecoratedClass('test');
assert.ok(inst.baseCalled, 'The base class contructor was called');
assert.ok(inst.middleCalled, 'The middle class constructor was called');
assert.ok(inst.decoratorCalled, 'The decorator constructor was called');
assert.strictEqual(inst.baseTestArgument, 'test');
assert.strictEqual(inst.middleTestArgument, 'test');
assert.strictEqual(inst.decoratorTestArgument, 'test');
var out = inst.test('test');
assert.strictEqual(out, 'testabc');
});