1
0
mirror of synced 2024-11-29 16:16:02 +03:00

Basic multiple select implementation

This commit is contained in:
Kevin Brown 2014-08-29 11:31:18 -04:00
parent 1197960a4e
commit 14d3d99868
16 changed files with 709 additions and 180 deletions

41
dist/css/select2.css vendored
View File

@ -18,6 +18,19 @@
padding-left: 8px; padding-left: 8px;
text-overflow: ellipsis; } text-overflow: ellipsis; }
.select2-container .selection .multiple-select {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 32px;
user-select: none;
-webkit-user-select: none; }
.select2-container .selection .multiple-select .rendered-selection {
display: block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis; }
.select2-container .dropdown { .select2-container .dropdown {
background-color: white; background-color: white;
border: 1px solid #aaa; border: 1px solid #aaa;
@ -26,8 +39,8 @@
display: block; display: block;
position: absolute; position: absolute;
left: -100000px; left: -100000px;
top: -100000px; width: 100%;
width: 100%; } z-index: 100; }
.select2-container .dropdown .results { .select2-container .dropdown .results {
display: block; } display: block; }
.select2-container .dropdown .results .options { .select2-container .dropdown .results .options {
@ -40,10 +53,10 @@
user-select: none; user-select: none;
-webkit-user-select: none; } -webkit-user-select: none; }
.select2-container.open .dropdown { .select2-container.open .dropdown {
border-top: none;
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
left: 0; left: 0; }
top: 28px; }
.select2-container.select2-theme-default .selection .single-select { .select2-container.select2-theme-default .selection .single-select {
background-color: #eee; background-color: #eee;
@ -52,8 +65,24 @@
.select2-container.select2-theme-default .selection .single-select .rendered-selection { .select2-container.select2-theme-default .selection .single-select .rendered-selection {
color: #444; color: #444;
line-height: 28px; } line-height: 28px; }
.select2-container.select2-theme-default.open .selection .single-select { .select2-container.select2-theme-default .selection .multiple-select {
border-bottom: none; background-color: white;
border: 1px solid #aaa;
border-radius: 4px; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection {
list-style: none;
margin: 0;
padding: 5px;
padding-bottom: 0; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
float: left;
margin-right: 5px;
margin-bottom: 5px;
padding: 0 5px; }
.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 .results { .select2-container.select2-theme-default .dropdown .results {

View File

@ -59,6 +59,8 @@ define('select2/utils',[], function () {
calledConstructor.apply(this, arguments); calledConstructor.apply(this, arguments);
} }
DecoratorClass.displayName = SuperClass.displayName;
function ctr () { function ctr () {
this.constructor = DecoratedClass; this.constructor = DecoratedClass;
} }
@ -162,30 +164,33 @@ define('select2/data/select',[
}; };
SelectAdapter.prototype.select = function (data) { SelectAdapter.prototype.select = function (data) {
var val; var self = this;
if (this.$element.prop("multiple")) { if (this.$element.prop("multiple")) {
var currentData = this.current(); this.current(function (currentData) {
var val = [];
data = [data]; data = [data];
data.push(currentData); data.push.apply(data, currentData);
val = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
id = data[d].id; id = data[d].id;
if (ids.indexOf(id) === -1) { if (val.indexOf(id) === -1) {
val.push(id); val.push(id);
} }
} }
self.$element.val(val);
self.$element.trigger("change");
});
} else { } else {
val = data.id; var val = data.id;
}
this.$element.val(val); this.$element.val(val);
this.$element.trigger("change"); this.$element.trigger("change");
} }
}
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
@ -361,19 +366,19 @@ define('select2/dropdown',[
return Dropdown; return Dropdown;
}) })
; ;
define('select2/selection',[ define('select2/selection/single',[
'./utils' '../utils'
], function (Utils) { ], function (Utils) {
function Selection ($element, options) { function SingleSelection ($element, options) {
this.$element = $element; this.$element = $element;
this.options = options; this.options = options;
Selection.__super__.constructor.call(this); SingleSelection.__super__.constructor.call(this);
} }
Utils.Extend(Selection, Utils.Observable); Utils.Extend(SingleSelection, Utils.Observable);
Selection.prototype.render = function () { SingleSelection.prototype.render = function () {
var $selection = $( var $selection = $(
'<span class="single-select">' + '<span class="single-select">' +
'<span class="rendered-selection"></span>' + '<span class="rendered-selection"></span>' +
@ -385,7 +390,7 @@ define('select2/selection',[
return $selection; return $selection;
} }
Selection.prototype.bind = function ($container) { SingleSelection.prototype.bind = function ($container) {
var self = this; var self = this;
this.$selection.on('click', function (evt) { this.$selection.on('click', function (evt) {
@ -395,15 +400,15 @@ define('select2/selection',[
}); });
} }
Selection.prototype.clear = function () { SingleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").text(""); this.$selection.find(".rendered-selection").empty();
} }
Selection.prototype.display = function (data) { SingleSelection.prototype.display = function (data) {
return data.text; return data.text;
} }
Selection.prototype.update = function (data) { SingleSelection.prototype.update = function (data) {
if (data.length == 0) { if (data.length == 0) {
this.clear(); this.clear();
return; return;
@ -416,22 +421,102 @@ define('select2/selection',[
this.$selection.find(".rendered-selection").html(formatted); this.$selection.find(".rendered-selection").html(formatted);
} }
return Selection; return SingleSelection;
});
define('select2/selection/multiple',[
'../utils'
], function (Utils) {
function MultipleSelection ($element, options) {
this.$element = $element;
this.options = options;
MultipleSelection.__super__.constructor.call(this);
}
Utils.Extend(MultipleSelection, Utils.Observable);
MultipleSelection.prototype.render = function () {
var $selection = $(
'<span class="multiple-select">' +
'<ul class="rendered-selection"></ul>' +
'</span>'
);
this.$selection = $selection;
return $selection;
}
MultipleSelection.prototype.bind = function ($container) {
var self = this;
this.$selection.on('click', function (evt) {
self.trigger("toggle", {
originalEvent: evt
});
});
}
MultipleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").empty();
}
MultipleSelection.prototype.display = function (data) {
return data.text;
}
MultipleSelection.prototype.update = function (data) {
this.clear();
if (data.length == 0) {
return;
}
var $selections = [];
for (var d = 0; d < data.length; d++) {
var selection = data[d];
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
$selection.text(formatted);
$selection.data("data", data);
$selections.push($selection);
}
this.$selection.find(".rendered-selection").append($selections);
}
return MultipleSelection;
}); });
define('select2/options',[ define('select2/options',[
'./data/select', './data/select',
'./results', './results',
'./dropdown', './dropdown',
'./selection' './selection/single',
], function (SelectData, ResultsList, Dropdown, Selection) { './selection/multiple'
], function (SelectData, ResultsList, Dropdown, SingleSelection,
MultipleSelection) {
function Options (options) { function Options (options) {
this.options = options; this.options = options;
this.dataAdapter = SelectData; this.dataAdapter = SelectData;
this.resultsAdapter = ResultsList; this.resultsAdapter = ResultsList;
this.dropdownAdapter = Dropdown; this.dropdownAdapter = Dropdown;
this.selectionAdapter = options.selectionAdapter || Selection; this.selectionAdapter = options.selectionAdapter;
if (this.selectionAdapter == null) {
if (this.options.multiple) {
this.selectionAdapter = MultipleSelection;
} else {
this.selectionAdapter = SingleSelection;
}
}
} }
return Options; return Options;
@ -444,6 +529,11 @@ define('select2/core',[
], function ($, Options, Utils) { ], function ($, Options, Utils) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
this.$element = $element; this.$element = $element;
options = options || {};
options.multiple = options.multiple || $element.prop("multiple");
this.options = new Options(options); this.options = new Options(options);
Select2.__super__.constructor.call(this); Select2.__super__.constructor.call(this);

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

@ -59,6 +59,8 @@ define('select2/utils',[], function () {
calledConstructor.apply(this, arguments); calledConstructor.apply(this, arguments);
} }
DecoratorClass.displayName = SuperClass.displayName;
function ctr () { function ctr () {
this.constructor = DecoratedClass; this.constructor = DecoratedClass;
} }
@ -162,30 +164,33 @@ define('select2/data/select',[
}; };
SelectAdapter.prototype.select = function (data) { SelectAdapter.prototype.select = function (data) {
var val; var self = this;
if (this.$element.prop("multiple")) { if (this.$element.prop("multiple")) {
var currentData = this.current(); this.current(function (currentData) {
var val = [];
data = [data]; data = [data];
data.push(currentData); data.push.apply(data, currentData);
val = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
id = data[d].id; id = data[d].id;
if (ids.indexOf(id) === -1) { if (val.indexOf(id) === -1) {
val.push(id); val.push(id);
} }
} }
self.$element.val(val);
self.$element.trigger("change");
});
} else { } else {
val = data.id; var val = data.id;
}
this.$element.val(val); this.$element.val(val);
this.$element.trigger("change"); this.$element.trigger("change");
} }
}
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
@ -361,19 +366,19 @@ define('select2/dropdown',[
return Dropdown; return Dropdown;
}) })
; ;
define('select2/selection',[ define('select2/selection/single',[
'./utils' '../utils'
], function (Utils) { ], function (Utils) {
function Selection ($element, options) { function SingleSelection ($element, options) {
this.$element = $element; this.$element = $element;
this.options = options; this.options = options;
Selection.__super__.constructor.call(this); SingleSelection.__super__.constructor.call(this);
} }
Utils.Extend(Selection, Utils.Observable); Utils.Extend(SingleSelection, Utils.Observable);
Selection.prototype.render = function () { SingleSelection.prototype.render = function () {
var $selection = $( var $selection = $(
'<span class="single-select">' + '<span class="single-select">' +
'<span class="rendered-selection"></span>' + '<span class="rendered-selection"></span>' +
@ -385,7 +390,7 @@ define('select2/selection',[
return $selection; return $selection;
} }
Selection.prototype.bind = function ($container) { SingleSelection.prototype.bind = function ($container) {
var self = this; var self = this;
this.$selection.on('click', function (evt) { this.$selection.on('click', function (evt) {
@ -395,15 +400,15 @@ define('select2/selection',[
}); });
} }
Selection.prototype.clear = function () { SingleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").text(""); this.$selection.find(".rendered-selection").empty();
} }
Selection.prototype.display = function (data) { SingleSelection.prototype.display = function (data) {
return data.text; return data.text;
} }
Selection.prototype.update = function (data) { SingleSelection.prototype.update = function (data) {
if (data.length == 0) { if (data.length == 0) {
this.clear(); this.clear();
return; return;
@ -416,22 +421,102 @@ define('select2/selection',[
this.$selection.find(".rendered-selection").html(formatted); this.$selection.find(".rendered-selection").html(formatted);
} }
return Selection; return SingleSelection;
});
define('select2/selection/multiple',[
'../utils'
], function (Utils) {
function MultipleSelection ($element, options) {
this.$element = $element;
this.options = options;
MultipleSelection.__super__.constructor.call(this);
}
Utils.Extend(MultipleSelection, Utils.Observable);
MultipleSelection.prototype.render = function () {
var $selection = $(
'<span class="multiple-select">' +
'<ul class="rendered-selection"></ul>' +
'</span>'
);
this.$selection = $selection;
return $selection;
}
MultipleSelection.prototype.bind = function ($container) {
var self = this;
this.$selection.on('click', function (evt) {
self.trigger("toggle", {
originalEvent: evt
});
});
}
MultipleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").empty();
}
MultipleSelection.prototype.display = function (data) {
return data.text;
}
MultipleSelection.prototype.update = function (data) {
this.clear();
if (data.length == 0) {
return;
}
var $selections = [];
for (var d = 0; d < data.length; d++) {
var selection = data[d];
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
$selection.text(formatted);
$selection.data("data", data);
$selections.push($selection);
}
this.$selection.find(".rendered-selection").append($selections);
}
return MultipleSelection;
}); });
define('select2/options',[ define('select2/options',[
'./data/select', './data/select',
'./results', './results',
'./dropdown', './dropdown',
'./selection' './selection/single',
], function (SelectData, ResultsList, Dropdown, Selection) { './selection/multiple'
], function (SelectData, ResultsList, Dropdown, SingleSelection,
MultipleSelection) {
function Options (options) { function Options (options) {
this.options = options; this.options = options;
this.dataAdapter = SelectData; this.dataAdapter = SelectData;
this.resultsAdapter = ResultsList; this.resultsAdapter = ResultsList;
this.dropdownAdapter = Dropdown; this.dropdownAdapter = Dropdown;
this.selectionAdapter = options.selectionAdapter || Selection; this.selectionAdapter = options.selectionAdapter;
if (this.selectionAdapter == null) {
if (this.options.multiple) {
this.selectionAdapter = MultipleSelection;
} else {
this.selectionAdapter = SingleSelection;
}
}
} }
return Options; return Options;
@ -444,6 +529,11 @@ define('select2/core',[
], function ($, Options, Utils) { ], function ($, Options, Utils) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
this.$element = $element; this.$element = $element;
options = options || {};
options.multiple = options.multiple || $element.prop("multiple");
this.options = new Options(options); this.options = new Options(options);
Select2.__super__.constructor.call(this); Select2.__super__.constructor.call(this);

View File

@ -9596,6 +9596,8 @@ define('select2/utils',[], function () {
calledConstructor.apply(this, arguments); calledConstructor.apply(this, arguments);
} }
DecoratorClass.displayName = SuperClass.displayName;
function ctr () { function ctr () {
this.constructor = DecoratedClass; this.constructor = DecoratedClass;
} }
@ -9699,30 +9701,33 @@ define('select2/data/select',[
}; };
SelectAdapter.prototype.select = function (data) { SelectAdapter.prototype.select = function (data) {
var val; var self = this;
if (this.$element.prop("multiple")) { if (this.$element.prop("multiple")) {
var currentData = this.current(); this.current(function (currentData) {
var val = [];
data = [data]; data = [data];
data.push(currentData); data.push.apply(data, currentData);
val = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
id = data[d].id; id = data[d].id;
if (ids.indexOf(id) === -1) { if (val.indexOf(id) === -1) {
val.push(id); val.push(id);
} }
} }
self.$element.val(val);
self.$element.trigger("change");
});
} else { } else {
val = data.id; var val = data.id;
}
this.$element.val(val); this.$element.val(val);
this.$element.trigger("change"); this.$element.trigger("change");
} }
}
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
@ -9898,19 +9903,19 @@ define('select2/dropdown',[
return Dropdown; return Dropdown;
}) })
; ;
define('select2/selection',[ define('select2/selection/single',[
'./utils' '../utils'
], function (Utils) { ], function (Utils) {
function Selection ($element, options) { function SingleSelection ($element, options) {
this.$element = $element; this.$element = $element;
this.options = options; this.options = options;
Selection.__super__.constructor.call(this); SingleSelection.__super__.constructor.call(this);
} }
Utils.Extend(Selection, Utils.Observable); Utils.Extend(SingleSelection, Utils.Observable);
Selection.prototype.render = function () { SingleSelection.prototype.render = function () {
var $selection = $( var $selection = $(
'<span class="single-select">' + '<span class="single-select">' +
'<span class="rendered-selection"></span>' + '<span class="rendered-selection"></span>' +
@ -9922,7 +9927,7 @@ define('select2/selection',[
return $selection; return $selection;
} }
Selection.prototype.bind = function ($container) { SingleSelection.prototype.bind = function ($container) {
var self = this; var self = this;
this.$selection.on('click', function (evt) { this.$selection.on('click', function (evt) {
@ -9932,15 +9937,15 @@ define('select2/selection',[
}); });
} }
Selection.prototype.clear = function () { SingleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").text(""); this.$selection.find(".rendered-selection").empty();
} }
Selection.prototype.display = function (data) { SingleSelection.prototype.display = function (data) {
return data.text; return data.text;
} }
Selection.prototype.update = function (data) { SingleSelection.prototype.update = function (data) {
if (data.length == 0) { if (data.length == 0) {
this.clear(); this.clear();
return; return;
@ -9953,22 +9958,102 @@ define('select2/selection',[
this.$selection.find(".rendered-selection").html(formatted); this.$selection.find(".rendered-selection").html(formatted);
} }
return Selection; return SingleSelection;
});
define('select2/selection/multiple',[
'../utils'
], function (Utils) {
function MultipleSelection ($element, options) {
this.$element = $element;
this.options = options;
MultipleSelection.__super__.constructor.call(this);
}
Utils.Extend(MultipleSelection, Utils.Observable);
MultipleSelection.prototype.render = function () {
var $selection = $(
'<span class="multiple-select">' +
'<ul class="rendered-selection"></ul>' +
'</span>'
);
this.$selection = $selection;
return $selection;
}
MultipleSelection.prototype.bind = function ($container) {
var self = this;
this.$selection.on('click', function (evt) {
self.trigger("toggle", {
originalEvent: evt
});
});
}
MultipleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").empty();
}
MultipleSelection.prototype.display = function (data) {
return data.text;
}
MultipleSelection.prototype.update = function (data) {
this.clear();
if (data.length == 0) {
return;
}
var $selections = [];
for (var d = 0; d < data.length; d++) {
var selection = data[d];
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
$selection.text(formatted);
$selection.data("data", data);
$selections.push($selection);
}
this.$selection.find(".rendered-selection").append($selections);
}
return MultipleSelection;
}); });
define('select2/options',[ define('select2/options',[
'./data/select', './data/select',
'./results', './results',
'./dropdown', './dropdown',
'./selection' './selection/single',
], function (SelectData, ResultsList, Dropdown, Selection) { './selection/multiple'
], function (SelectData, ResultsList, Dropdown, SingleSelection,
MultipleSelection) {
function Options (options) { function Options (options) {
this.options = options; this.options = options;
this.dataAdapter = SelectData; this.dataAdapter = SelectData;
this.resultsAdapter = ResultsList; this.resultsAdapter = ResultsList;
this.dropdownAdapter = Dropdown; this.dropdownAdapter = Dropdown;
this.selectionAdapter = options.selectionAdapter || Selection; this.selectionAdapter = options.selectionAdapter;
if (this.selectionAdapter == null) {
if (this.options.multiple) {
this.selectionAdapter = MultipleSelection;
} else {
this.selectionAdapter = SingleSelection;
}
}
} }
return Options; return Options;
@ -9981,6 +10066,11 @@ define('select2/core',[
], function ($, Options, Utils) { ], function ($, Options, Utils) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
this.$element = $element; this.$element = $element;
options = options || {};
options.multiple = options.multiple || $element.prop("multiple");
this.options = new Options(options); this.options = new Options(options);
Select2.__super__.constructor.call(this); Select2.__super__.constructor.call(this);

136
dist/js/select2.js vendored
View File

@ -487,6 +487,8 @@ define('select2/utils',[], function () {
calledConstructor.apply(this, arguments); calledConstructor.apply(this, arguments);
} }
DecoratorClass.displayName = SuperClass.displayName;
function ctr () { function ctr () {
this.constructor = DecoratedClass; this.constructor = DecoratedClass;
} }
@ -590,30 +592,33 @@ define('select2/data/select',[
}; };
SelectAdapter.prototype.select = function (data) { SelectAdapter.prototype.select = function (data) {
var val; var self = this;
if (this.$element.prop("multiple")) { if (this.$element.prop("multiple")) {
var currentData = this.current(); this.current(function (currentData) {
var val = [];
data = [data]; data = [data];
data.push(currentData); data.push.apply(data, currentData);
val = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
id = data[d].id; id = data[d].id;
if (ids.indexOf(id) === -1) { if (val.indexOf(id) === -1) {
val.push(id); val.push(id);
} }
} }
self.$element.val(val);
self.$element.trigger("change");
});
} else { } else {
val = data.id; var val = data.id;
}
this.$element.val(val); this.$element.val(val);
this.$element.trigger("change"); this.$element.trigger("change");
} }
}
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];
@ -789,19 +794,19 @@ define('select2/dropdown',[
return Dropdown; return Dropdown;
}) })
; ;
define('select2/selection',[ define('select2/selection/single',[
'./utils' '../utils'
], function (Utils) { ], function (Utils) {
function Selection ($element, options) { function SingleSelection ($element, options) {
this.$element = $element; this.$element = $element;
this.options = options; this.options = options;
Selection.__super__.constructor.call(this); SingleSelection.__super__.constructor.call(this);
} }
Utils.Extend(Selection, Utils.Observable); Utils.Extend(SingleSelection, Utils.Observable);
Selection.prototype.render = function () { SingleSelection.prototype.render = function () {
var $selection = $( var $selection = $(
'<span class="single-select">' + '<span class="single-select">' +
'<span class="rendered-selection"></span>' + '<span class="rendered-selection"></span>' +
@ -813,7 +818,7 @@ define('select2/selection',[
return $selection; return $selection;
} }
Selection.prototype.bind = function ($container) { SingleSelection.prototype.bind = function ($container) {
var self = this; var self = this;
this.$selection.on('click', function (evt) { this.$selection.on('click', function (evt) {
@ -823,15 +828,15 @@ define('select2/selection',[
}); });
} }
Selection.prototype.clear = function () { SingleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").text(""); this.$selection.find(".rendered-selection").empty();
} }
Selection.prototype.display = function (data) { SingleSelection.prototype.display = function (data) {
return data.text; return data.text;
} }
Selection.prototype.update = function (data) { SingleSelection.prototype.update = function (data) {
if (data.length == 0) { if (data.length == 0) {
this.clear(); this.clear();
return; return;
@ -844,22 +849,102 @@ define('select2/selection',[
this.$selection.find(".rendered-selection").html(formatted); this.$selection.find(".rendered-selection").html(formatted);
} }
return Selection; return SingleSelection;
});
define('select2/selection/multiple',[
'../utils'
], function (Utils) {
function MultipleSelection ($element, options) {
this.$element = $element;
this.options = options;
MultipleSelection.__super__.constructor.call(this);
}
Utils.Extend(MultipleSelection, Utils.Observable);
MultipleSelection.prototype.render = function () {
var $selection = $(
'<span class="multiple-select">' +
'<ul class="rendered-selection"></ul>' +
'</span>'
);
this.$selection = $selection;
return $selection;
}
MultipleSelection.prototype.bind = function ($container) {
var self = this;
this.$selection.on('click', function (evt) {
self.trigger("toggle", {
originalEvent: evt
});
});
}
MultipleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").empty();
}
MultipleSelection.prototype.display = function (data) {
return data.text;
}
MultipleSelection.prototype.update = function (data) {
this.clear();
if (data.length == 0) {
return;
}
var $selections = [];
for (var d = 0; d < data.length; d++) {
var selection = data[d];
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
$selection.text(formatted);
$selection.data("data", data);
$selections.push($selection);
}
this.$selection.find(".rendered-selection").append($selections);
}
return MultipleSelection;
}); });
define('select2/options',[ define('select2/options',[
'./data/select', './data/select',
'./results', './results',
'./dropdown', './dropdown',
'./selection' './selection/single',
], function (SelectData, ResultsList, Dropdown, Selection) { './selection/multiple'
], function (SelectData, ResultsList, Dropdown, SingleSelection,
MultipleSelection) {
function Options (options) { function Options (options) {
this.options = options; this.options = options;
this.dataAdapter = SelectData; this.dataAdapter = SelectData;
this.resultsAdapter = ResultsList; this.resultsAdapter = ResultsList;
this.dropdownAdapter = Dropdown; this.dropdownAdapter = Dropdown;
this.selectionAdapter = options.selectionAdapter || Selection; this.selectionAdapter = options.selectionAdapter;
if (this.selectionAdapter == null) {
if (this.options.multiple) {
this.selectionAdapter = MultipleSelection;
} else {
this.selectionAdapter = SingleSelection;
}
}
} }
return Options; return Options;
@ -872,6 +957,11 @@ define('select2/core',[
], function ($, Options, Utils) { ], function ($, Options, Utils) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
this.$element = $element; this.$element = $element;
options = options || {};
options.multiple = options.multiple || $element.prop("multiple");
this.options = new Options(options); this.options = new Options(options);
Select2.__super__.constructor.call(this); Select2.__super__.constructor.call(this);

View File

@ -12,9 +12,7 @@
</head> </head>
<body> <body>
<select style="width:300px" id="single">
<input type="text" style="width:300px" autofocus/><br/>
<select style="width:300px" id="source">
<option value="AK">Alaska</option> <option value="AK">Alaska</option>
<option value="HI">Hawaii</option> <option value="HI">Hawaii</option>
<option value="CA">California</option> <option value="CA">California</option>
@ -66,11 +64,10 @@
<option value="VA">Virginia</option> <option value="VA">Virginia</option>
<option value="WV">West Virginia</option> <option value="WV">West Virginia</option>
</select><br/> </select><br/>
<input type="text" style="width:300px" /><br/> <select style="width:300px" id="multiple" multiple="multiple">
<select style="width:300px">
<option value="AK">Alaska</option> <option value="AK">Alaska</option>
<option value="HI">Hawaii</option> <option value="HI">Hawaii</option>
<option value="CA">California</option> <option value="CA" selected="selected">California</option>
<option value="NV">Nevada</option> <option value="NV">Nevada</option>
<option value="OR">Oregon</option> <option value="OR">Oregon</option>
<option value="WA">Washington</option> <option value="WA">Washington</option>
@ -122,7 +119,8 @@
<script> <script>
require(["select2/core"], function (Select2) { require(["select2/core"], function (Select2) {
var s2 = new Select2($("#source")); var single = new Select2($("#single"));
var multiple = new Select2($("#multiple"));
}); });
</script> </script>

View File

@ -5,6 +5,11 @@ define([
], function ($, Options, Utils) { ], function ($, Options, Utils) {
var Select2 = function ($element, options) { var Select2 = function ($element, options) {
this.$element = $element; this.$element = $element;
options = options || {};
options.multiple = options.multiple || $element.prop("multiple");
this.options = new Options(options); this.options = new Options(options);
Select2.__super__.constructor.call(this); Select2.__super__.constructor.call(this);

View File

@ -26,30 +26,33 @@ define([
}; };
SelectAdapter.prototype.select = function (data) { SelectAdapter.prototype.select = function (data) {
var val; var self = this;
if (this.$element.prop("multiple")) { if (this.$element.prop("multiple")) {
var currentData = this.current(); this.current(function (currentData) {
var val = [];
data = [data]; data = [data];
data.push(currentData); data.push.apply(data, currentData);
val = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
id = data[d].id; id = data[d].id;
if (ids.indexOf(id) === -1) { if (val.indexOf(id) === -1) {
val.push(id); val.push(id);
} }
} }
self.$element.val(val);
self.$element.trigger("change");
});
} else { } else {
val = data.id; var val = data.id;
}
this.$element.val(val); this.$element.val(val);
this.$element.trigger("change"); this.$element.trigger("change");
} }
}
SelectAdapter.prototype.query = function (params, callback) { SelectAdapter.prototype.query = function (params, callback) {
var data = []; var data = [];

View File

@ -2,15 +2,25 @@ define([
'./data/select', './data/select',
'./results', './results',
'./dropdown', './dropdown',
'./selection' './selection/single',
], function (SelectData, ResultsList, Dropdown, Selection) { './selection/multiple'
], function (SelectData, ResultsList, Dropdown, SingleSelection,
MultipleSelection) {
function Options (options) { function Options (options) {
this.options = options; this.options = options;
this.dataAdapter = SelectData; this.dataAdapter = SelectData;
this.resultsAdapter = ResultsList; this.resultsAdapter = ResultsList;
this.dropdownAdapter = Dropdown; this.dropdownAdapter = Dropdown;
this.selectionAdapter = options.selectionAdapter || Selection; this.selectionAdapter = options.selectionAdapter;
if (this.selectionAdapter == null) {
if (this.options.multiple) {
this.selectionAdapter = MultipleSelection;
} else {
this.selectionAdapter = SingleSelection;
}
}
} }
return Options; return Options;

69
src/js/select2/selection/multiple.js vendored Normal file
View File

@ -0,0 +1,69 @@
define([
'../utils'
], function (Utils) {
function MultipleSelection ($element, options) {
this.$element = $element;
this.options = options;
MultipleSelection.__super__.constructor.call(this);
}
Utils.Extend(MultipleSelection, Utils.Observable);
MultipleSelection.prototype.render = function () {
var $selection = $(
'<span class="multiple-select">' +
'<ul class="rendered-selection"></ul>' +
'</span>'
);
this.$selection = $selection;
return $selection;
}
MultipleSelection.prototype.bind = function ($container) {
var self = this;
this.$selection.on('click', function (evt) {
self.trigger("toggle", {
originalEvent: evt
});
});
}
MultipleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").empty();
}
MultipleSelection.prototype.display = function (data) {
return data.text;
}
MultipleSelection.prototype.update = function (data) {
this.clear();
if (data.length == 0) {
return;
}
var $selections = [];
for (var d = 0; d < data.length; d++) {
var selection = data[d];
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
$selection.text(formatted);
$selection.data("data", data);
$selections.push($selection);
}
this.$selection.find(".rendered-selection").append($selections);
}
return MultipleSelection;
});

View File

@ -1,16 +1,16 @@
define([ define([
'./utils' '../utils'
], function (Utils) { ], function (Utils) {
function Selection ($element, options) { function SingleSelection ($element, options) {
this.$element = $element; this.$element = $element;
this.options = options; this.options = options;
Selection.__super__.constructor.call(this); SingleSelection.__super__.constructor.call(this);
} }
Utils.Extend(Selection, Utils.Observable); Utils.Extend(SingleSelection, Utils.Observable);
Selection.prototype.render = function () { SingleSelection.prototype.render = function () {
var $selection = $( var $selection = $(
'<span class="single-select">' + '<span class="single-select">' +
'<span class="rendered-selection"></span>' + '<span class="rendered-selection"></span>' +
@ -22,7 +22,7 @@ define([
return $selection; return $selection;
} }
Selection.prototype.bind = function ($container) { SingleSelection.prototype.bind = function ($container) {
var self = this; var self = this;
this.$selection.on('click', function (evt) { this.$selection.on('click', function (evt) {
@ -32,15 +32,15 @@ define([
}); });
} }
Selection.prototype.clear = function () { SingleSelection.prototype.clear = function () {
this.$selection.find(".rendered-selection").text(""); this.$selection.find(".rendered-selection").empty();
} }
Selection.prototype.display = function (data) { SingleSelection.prototype.display = function (data) {
return data.text; return data.text;
} }
Selection.prototype.update = function (data) { SingleSelection.prototype.update = function (data) {
if (data.length == 0) { if (data.length == 0) {
this.clear(); this.clear();
return; return;
@ -53,5 +53,5 @@ define([
this.$selection.find(".rendered-selection").html(formatted); this.$selection.find(".rendered-selection").html(formatted);
} }
return Selection; return SingleSelection;
}); });

View File

@ -59,6 +59,8 @@ define([], function () {
calledConstructor.apply(this, arguments); calledConstructor.apply(this, arguments);
} }
DecoratorClass.displayName = SuperClass.displayName;
function ctr () { function ctr () {
this.constructor = DecoratedClass; this.constructor = DecoratedClass;
} }

View File

@ -11,10 +11,11 @@
position: absolute; position: absolute;
left: -100000px; left: -100000px;
top: -100000px;
width: 100%; width: 100%;
z-index: 100;
.results { .results {
display: block; display: block;
@ -35,10 +36,10 @@
} }
&.open .dropdown { &.open .dropdown {
border-top: none;
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
left: 0; left: 0;
top: 28px;
} }
} }

20
src/scss/_multiple.scss Normal file
View File

@ -0,0 +1,20 @@
.select2-container {
.selection .multiple-select {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 32px;
user-select: none;
-webkit-user-select: none;
.rendered-selection {
display: block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
}
}
}

View File

@ -8,6 +8,8 @@
} }
@import "single"; @import "single";
@import "multiple";
@import "dropdown"; @import "dropdown";
@import "theme/default/layout"; @import "theme/default/layout";

View File

@ -1,5 +1,6 @@
.select2-container.select2-theme-default { .select2-container.select2-theme-default {
.selection .single-select { .selection {
.single-select {
background-color: #eee; background-color: #eee;
border: 1px solid #aaa; border: 1px solid #aaa;
border-radius: 4px; border-radius: 4px;
@ -10,13 +11,42 @@
} }
} }
.multiple-select {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
.rendered-selection {
list-style: none;
margin: 0;
padding: 5px;
padding-bottom: 0;
.choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
float: left;
margin-right: 5px;
margin-bottom: 5px;
padding: 0 5px;
}
}
}
}
&.open { &.open {
.selection .single-select { .selection {
border-bottom: none; .single-select,
.multiple-select {
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
} }
} }
}
.dropdown { .dropdown {
.results { .results {