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;
-webkit-user-select: none; }
.select2-container .selection .multiple-select .rendered-selection {
display: block;
display: inline-block;
overflow: hidden;
padding-left: 8px;
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 {
background-color: white;
@ -41,12 +47,6 @@
left: -100000px;
width: 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 {
display: block; }
.select2-container .dropdown .results .options {
@ -59,6 +59,12 @@
-webkit-user-select: none; }
.select2-container .dropdown .results .options .option[aria-selected] {
cursor: pointer; }
.select2-container .select2-search {
display: block;
padding: 4px; }
.select2-container .select2-search input {
padding: 4px;
width: 100%; }
.select2-container.open .dropdown {
border-top: none;
border-top-left-radius: 0;
@ -81,10 +87,10 @@
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection {
list-style: none;
margin: 0;
padding: 5px;
padding-bottom: 0; }
padding: 0 5px; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .placeholder {
color: #999;
margin-top: 5px;
float: left; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice {
background-color: #e4e4e4;
@ -92,7 +98,7 @@
border-radius: 4px;
float: left;
margin-right: 5px;
margin-bottom: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice .remove {
color: #999;
@ -104,7 +110,7 @@
.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-right-radius: 0; }
.select2-container.select2-theme-default .dropdown .search input {
.select2-container.select2-theme-default .select2-search input {
border: 1px solid #aaa; }
.select2-container.select2-theme-default .dropdown .results > .options {
max-height: 200px;
@ -154,7 +160,7 @@
.select2-container.select2-theme-classic .dropdown {
background-color: white;
border-top: none; }
.select2-container.select2-theme-classic .dropdown .search input {
.select2-container.select2-theme-classic .dropdown .select2-search input {
border: 1px solid #aaa;
outline: 0; }
.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;
}
if (methodName === 'constructor') {
continue;
}
methods.push(methodName);
}
@ -913,6 +917,15 @@ define('select2/selection/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) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
@ -925,10 +938,7 @@ define('select2/selection/placeholder',[
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
var $placeholder = this.createPlaceholder(this.placeholder);
this.$selection.find('.rendered-selection').append($placeholder);
};
@ -936,6 +946,95 @@ define('select2/selection/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',[
], function () {
@ -2404,8 +2503,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this);
var $search = $(
'<span class="search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' +
'<span class="select2-search">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</span>'
);
@ -2659,6 +2758,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./selection/search',
'./utils',
'./translation',
@ -2677,10 +2777,10 @@ define('select2/defaults',[
'./i18n/en'
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder,
SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll,
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) {
function Defaults () {
this.reset();
@ -2730,9 +2830,13 @@ define('select2/defaults',[
}
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) {
@ -2749,6 +2853,13 @@ define('select2/defaults',[
Placeholder
);
}
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
}
if (typeof options.language === 'string') {
@ -3073,6 +3184,10 @@ define('select2/core',[
self.close();
});
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) {
self.trigger('keypress', e);
});

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

@ -33,6 +33,10 @@ window.$ = window.$ || {};(function() { if ($ && $.fn && $.fn.select2 && $.fn.se
continue;
}
if (methodName === 'constructor') {
continue;
}
methods.push(methodName);
}
@ -913,6 +917,15 @@ define('select2/selection/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) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
@ -925,10 +938,7 @@ define('select2/selection/placeholder',[
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
var $placeholder = this.createPlaceholder(this.placeholder);
this.$selection.find('.rendered-selection').append($placeholder);
};
@ -936,6 +946,95 @@ define('select2/selection/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',[
], function () {
@ -2404,8 +2503,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this);
var $search = $(
'<span class="search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' +
'<span class="select2-search">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</span>'
);
@ -2659,6 +2758,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./selection/search',
'./utils',
'./translation',
@ -2677,10 +2777,10 @@ define('select2/defaults',[
'./i18n/en'
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder,
SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll,
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) {
function Defaults () {
this.reset();
@ -2730,9 +2830,13 @@ define('select2/defaults',[
}
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) {
@ -2749,6 +2853,13 @@ define('select2/defaults',[
Placeholder
);
}
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
}
if (typeof options.language === 'string') {
@ -3073,6 +3184,10 @@ define('select2/core',[
self.close();
});
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) {
self.trigger('keypress', e);
});

View File

@ -9568,6 +9568,10 @@ define('select2/utils',[], function () {
continue;
}
if (methodName === 'constructor') {
continue;
}
methods.push(methodName);
}
@ -10448,6 +10452,15 @@ define('select2/selection/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) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
@ -10460,10 +10473,7 @@ define('select2/selection/placeholder',[
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
var $placeholder = this.createPlaceholder(this.placeholder);
this.$selection.find('.rendered-selection').append($placeholder);
};
@ -10471,6 +10481,95 @@ define('select2/selection/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',[
], function () {
@ -11939,8 +12038,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this);
var $search = $(
'<span class="search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' +
'<span class="select2-search">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</span>'
);
@ -12194,6 +12293,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./selection/search',
'./utils',
'./translation',
@ -12212,10 +12312,10 @@ define('select2/defaults',[
'./i18n/en'
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder,
SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll,
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) {
function Defaults () {
this.reset();
@ -12265,9 +12365,13 @@ define('select2/defaults',[
}
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) {
@ -12284,6 +12388,13 @@ define('select2/defaults',[
Placeholder
);
}
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
}
if (typeof options.language === 'string') {
@ -12608,6 +12719,10 @@ define('select2/core',[
self.close();
});
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) {
self.trigger('keypress', e);
});

File diff suppressed because one or more lines are too long

135
dist/js/select2.js vendored
View File

@ -461,6 +461,10 @@ define('select2/utils',[], function () {
continue;
}
if (methodName === 'constructor') {
continue;
}
methods.push(methodName);
}
@ -1341,6 +1345,15 @@ define('select2/selection/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) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
@ -1353,10 +1366,7 @@ define('select2/selection/placeholder',[
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
var $placeholder = this.createPlaceholder(this.placeholder);
this.$selection.find('.rendered-selection').append($placeholder);
};
@ -1364,6 +1374,95 @@ define('select2/selection/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',[
], function () {
@ -2832,8 +2931,8 @@ define('select2/dropdown/search',[
var $rendered = decorated.call(this);
var $search = $(
'<span class="search">' +
'<input type="search" name="search" tabindex="-1" role="textbox" />' +
'<span class="select2-search">' +
'<input type="search" tabindex="-1" role="textbox" />' +
'</span>'
);
@ -3087,6 +3186,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./selection/search',
'./utils',
'./translation',
@ -3105,10 +3205,10 @@ define('select2/defaults',[
'./i18n/en'
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder,
SingleSelection, MultipleSelection, Placeholder, SelectionSearch,
Utils, Translation, DIACRITICS,
SelectData, ArrayData, AjaxData, Tags, MinimumInputLength,
Dropdown, Search, HidePlaceholder, InfiniteScroll,
Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
EnglishTranslation) {
function Defaults () {
this.reset();
@ -3158,9 +3258,13 @@ define('select2/defaults',[
}
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) {
@ -3177,6 +3281,13 @@ define('select2/defaults',[
Placeholder
);
}
if (options.multiple) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
SelectionSearch
);
}
}
if (typeof options.language === 'string') {
@ -3501,6 +3612,10 @@ define('select2/core',[
self.close();
});
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (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();
});
this.selection.on('query', function (params) {
self.trigger('query', params);
});
this.selection.on('keypress', function (e) {
self.trigger('keypress', e);
});

View File

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

View File

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

View File

@ -18,6 +18,15 @@ define([
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) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
@ -30,10 +39,7 @@ define([
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
var $placeholder = this.createPlaceholder(this.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;
}
if (methodName === 'constructor') {
continue;
}
methods.push(methodName);
}

View File

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

View File

@ -11,10 +11,20 @@
-webkit-user-select: none;
.rendered-selection {
display: block;
display: inline-block;
overflow: hidden;
padding-left: 8px;
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;
border-top: none;
.search {
.select2-search {
input {
border: 1px solid $border-color;
outline: 0;

View File

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

View File

@ -135,3 +135,55 @@ test('inherited - constructor', function (assert) {
assert.ok(inst.called);
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');
});