diff --git a/dist/css/select2.css b/dist/css/select2.css index 8adf29c2..8bba7414 100644 --- a/dist/css/select2.css +++ b/dist/css/select2.css @@ -18,6 +18,19 @@ padding-left: 8px; 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 { background-color: white; border: 1px solid #aaa; @@ -26,8 +39,8 @@ display: block; position: absolute; left: -100000px; - top: -100000px; - width: 100%; } + width: 100%; + z-index: 100; } .select2-container .dropdown .results { display: block; } .select2-container .dropdown .results .options { @@ -40,10 +53,10 @@ user-select: none; -webkit-user-select: none; } .select2-container.open .dropdown { + border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; - left: 0; - top: 28px; } + left: 0; } .select2-container.select2-theme-default .selection .single-select { background-color: #eee; @@ -52,8 +65,24 @@ .select2-container.select2-theme-default .selection .single-select .rendered-selection { color: #444; line-height: 28px; } -.select2-container.select2-theme-default.open .selection .single-select { - border-bottom: none; +.select2-container.select2-theme-default .selection .multiple-select { + 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-right-radius: 0; } .select2-container.select2-theme-default .dropdown .results { diff --git a/dist/js/select2.amd.full.js b/dist/js/select2.amd.full.js index 74b3b52d..cddc8bee 100644 --- a/dist/js/select2.amd.full.js +++ b/dist/js/select2.amd.full.js @@ -59,6 +59,8 @@ define('select2/utils',[], function () { calledConstructor.apply(this, arguments); } + DecoratorClass.displayName = SuperClass.displayName; + function ctr () { this.constructor = DecoratedClass; } @@ -162,29 +164,32 @@ define('select2/data/select',[ }; SelectAdapter.prototype.select = function (data) { - var val; + var self = this; if (this.$element.prop("multiple")) { - var currentData = this.current(); + this.current(function (currentData) { + var val = []; - data = [data]; - data.push(currentData); + data = [data]; + data.push.apply(data, currentData); - val = []; + for (var d = 0; d < data.length; d++) { + id = data[d].id; - for (var d = 0; d < data.length; d++) { - id = data[d].id; - - if (ids.indexOf(id) === -1) { - val.push(id); + if (val.indexOf(id) === -1) { + val.push(id); + } } - } - } else { - val = data.id; - } - this.$element.val(val); - this.$element.trigger("change"); + self.$element.val(val); + self.$element.trigger("change"); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger("change"); + } } SelectAdapter.prototype.query = function (params, callback) { @@ -361,19 +366,19 @@ define('select2/dropdown',[ return Dropdown; }) ; -define('select2/selection',[ - './utils' +define('select2/selection/single',[ + '../utils' ], function (Utils) { - function Selection ($element, options) { + function SingleSelection ($element, options) { this.$element = $element; 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 = $( '' + '' + @@ -385,7 +390,7 @@ define('select2/selection',[ return $selection; } - Selection.prototype.bind = function ($container) { + SingleSelection.prototype.bind = function ($container) { var self = this; this.$selection.on('click', function (evt) { @@ -395,15 +400,15 @@ define('select2/selection',[ }); } - Selection.prototype.clear = function () { - this.$selection.find(".rendered-selection").text(""); + SingleSelection.prototype.clear = function () { + this.$selection.find(".rendered-selection").empty(); } - Selection.prototype.display = function (data) { + SingleSelection.prototype.display = function (data) { return data.text; } - Selection.prototype.update = function (data) { + SingleSelection.prototype.update = function (data) { if (data.length == 0) { this.clear(); return; @@ -416,22 +421,102 @@ define('select2/selection',[ 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 = $( + '' + + '' + + '' + ); + + 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 = $(''); + + $selection.text(formatted); + $selection.data("data", data); + + $selections.push($selection); + } + + this.$selection.find(".rendered-selection").append($selections); + } + + return MultipleSelection; }); define('select2/options',[ './data/select', './results', './dropdown', - './selection' -], function (SelectData, ResultsList, Dropdown, Selection) { + './selection/single', + './selection/multiple' +], function (SelectData, ResultsList, Dropdown, SingleSelection, + MultipleSelection) { function Options (options) { this.options = options; this.dataAdapter = SelectData; this.resultsAdapter = ResultsList; 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; @@ -444,6 +529,11 @@ define('select2/core',[ ], function ($, Options, Utils) { var Select2 = function ($element, options) { this.$element = $element; + + options = options || {}; + + options.multiple = options.multiple || $element.prop("multiple"); + this.options = new Options(options); Select2.__super__.constructor.call(this); diff --git a/dist/js/select2.amd.js b/dist/js/select2.amd.js index 74b3b52d..cddc8bee 100644 --- a/dist/js/select2.amd.js +++ b/dist/js/select2.amd.js @@ -59,6 +59,8 @@ define('select2/utils',[], function () { calledConstructor.apply(this, arguments); } + DecoratorClass.displayName = SuperClass.displayName; + function ctr () { this.constructor = DecoratedClass; } @@ -162,29 +164,32 @@ define('select2/data/select',[ }; SelectAdapter.prototype.select = function (data) { - var val; + var self = this; if (this.$element.prop("multiple")) { - var currentData = this.current(); + this.current(function (currentData) { + var val = []; - data = [data]; - data.push(currentData); + data = [data]; + data.push.apply(data, currentData); - val = []; + for (var d = 0; d < data.length; d++) { + id = data[d].id; - for (var d = 0; d < data.length; d++) { - id = data[d].id; - - if (ids.indexOf(id) === -1) { - val.push(id); + if (val.indexOf(id) === -1) { + val.push(id); + } } - } - } else { - val = data.id; - } - this.$element.val(val); - this.$element.trigger("change"); + self.$element.val(val); + self.$element.trigger("change"); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger("change"); + } } SelectAdapter.prototype.query = function (params, callback) { @@ -361,19 +366,19 @@ define('select2/dropdown',[ return Dropdown; }) ; -define('select2/selection',[ - './utils' +define('select2/selection/single',[ + '../utils' ], function (Utils) { - function Selection ($element, options) { + function SingleSelection ($element, options) { this.$element = $element; 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 = $( '' + '' + @@ -385,7 +390,7 @@ define('select2/selection',[ return $selection; } - Selection.prototype.bind = function ($container) { + SingleSelection.prototype.bind = function ($container) { var self = this; this.$selection.on('click', function (evt) { @@ -395,15 +400,15 @@ define('select2/selection',[ }); } - Selection.prototype.clear = function () { - this.$selection.find(".rendered-selection").text(""); + SingleSelection.prototype.clear = function () { + this.$selection.find(".rendered-selection").empty(); } - Selection.prototype.display = function (data) { + SingleSelection.prototype.display = function (data) { return data.text; } - Selection.prototype.update = function (data) { + SingleSelection.prototype.update = function (data) { if (data.length == 0) { this.clear(); return; @@ -416,22 +421,102 @@ define('select2/selection',[ 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 = $( + '' + + '
    ' + + '
    ' + ); + + 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 = $(''); + + $selection.text(formatted); + $selection.data("data", data); + + $selections.push($selection); + } + + this.$selection.find(".rendered-selection").append($selections); + } + + return MultipleSelection; }); define('select2/options',[ './data/select', './results', './dropdown', - './selection' -], function (SelectData, ResultsList, Dropdown, Selection) { + './selection/single', + './selection/multiple' +], function (SelectData, ResultsList, Dropdown, SingleSelection, + MultipleSelection) { function Options (options) { this.options = options; this.dataAdapter = SelectData; this.resultsAdapter = ResultsList; 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; @@ -444,6 +529,11 @@ define('select2/core',[ ], function ($, Options, Utils) { var Select2 = function ($element, options) { this.$element = $element; + + options = options || {}; + + options.multiple = options.multiple || $element.prop("multiple"); + this.options = new Options(options); Select2.__super__.constructor.call(this); diff --git a/dist/js/select2.full.js b/dist/js/select2.full.js index f2511667..d9573e7f 100644 --- a/dist/js/select2.full.js +++ b/dist/js/select2.full.js @@ -9596,6 +9596,8 @@ define('select2/utils',[], function () { calledConstructor.apply(this, arguments); } + DecoratorClass.displayName = SuperClass.displayName; + function ctr () { this.constructor = DecoratedClass; } @@ -9699,29 +9701,32 @@ define('select2/data/select',[ }; SelectAdapter.prototype.select = function (data) { - var val; + var self = this; if (this.$element.prop("multiple")) { - var currentData = this.current(); + this.current(function (currentData) { + var val = []; - data = [data]; - data.push(currentData); + data = [data]; + data.push.apply(data, currentData); - val = []; + for (var d = 0; d < data.length; d++) { + id = data[d].id; - for (var d = 0; d < data.length; d++) { - id = data[d].id; - - if (ids.indexOf(id) === -1) { - val.push(id); + if (val.indexOf(id) === -1) { + val.push(id); + } } - } - } else { - val = data.id; - } - this.$element.val(val); - this.$element.trigger("change"); + self.$element.val(val); + self.$element.trigger("change"); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger("change"); + } } SelectAdapter.prototype.query = function (params, callback) { @@ -9898,19 +9903,19 @@ define('select2/dropdown',[ return Dropdown; }) ; -define('select2/selection',[ - './utils' +define('select2/selection/single',[ + '../utils' ], function (Utils) { - function Selection ($element, options) { + function SingleSelection ($element, options) { this.$element = $element; 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 = $( '' + '' + @@ -9922,7 +9927,7 @@ define('select2/selection',[ return $selection; } - Selection.prototype.bind = function ($container) { + SingleSelection.prototype.bind = function ($container) { var self = this; this.$selection.on('click', function (evt) { @@ -9932,15 +9937,15 @@ define('select2/selection',[ }); } - Selection.prototype.clear = function () { - this.$selection.find(".rendered-selection").text(""); + SingleSelection.prototype.clear = function () { + this.$selection.find(".rendered-selection").empty(); } - Selection.prototype.display = function (data) { + SingleSelection.prototype.display = function (data) { return data.text; } - Selection.prototype.update = function (data) { + SingleSelection.prototype.update = function (data) { if (data.length == 0) { this.clear(); return; @@ -9953,22 +9958,102 @@ define('select2/selection',[ 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 = $( + '' + + '
      ' + + '
      ' + ); + + 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 = $('
        '); + + $selection.text(formatted); + $selection.data("data", data); + + $selections.push($selection); + } + + this.$selection.find(".rendered-selection").append($selections); + } + + return MultipleSelection; }); define('select2/options',[ './data/select', './results', './dropdown', - './selection' -], function (SelectData, ResultsList, Dropdown, Selection) { + './selection/single', + './selection/multiple' +], function (SelectData, ResultsList, Dropdown, SingleSelection, + MultipleSelection) { function Options (options) { this.options = options; this.dataAdapter = SelectData; this.resultsAdapter = ResultsList; 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; @@ -9981,6 +10066,11 @@ define('select2/core',[ ], function ($, Options, Utils) { var Select2 = function ($element, options) { this.$element = $element; + + options = options || {}; + + options.multiple = options.multiple || $element.prop("multiple"); + this.options = new Options(options); Select2.__super__.constructor.call(this); diff --git a/dist/js/select2.js b/dist/js/select2.js index 06ce806e..14d04fa4 100644 --- a/dist/js/select2.js +++ b/dist/js/select2.js @@ -487,6 +487,8 @@ define('select2/utils',[], function () { calledConstructor.apply(this, arguments); } + DecoratorClass.displayName = SuperClass.displayName; + function ctr () { this.constructor = DecoratedClass; } @@ -590,29 +592,32 @@ define('select2/data/select',[ }; SelectAdapter.prototype.select = function (data) { - var val; + var self = this; if (this.$element.prop("multiple")) { - var currentData = this.current(); + this.current(function (currentData) { + var val = []; - data = [data]; - data.push(currentData); + data = [data]; + data.push.apply(data, currentData); - val = []; + for (var d = 0; d < data.length; d++) { + id = data[d].id; - for (var d = 0; d < data.length; d++) { - id = data[d].id; - - if (ids.indexOf(id) === -1) { - val.push(id); + if (val.indexOf(id) === -1) { + val.push(id); + } } - } - } else { - val = data.id; - } - this.$element.val(val); - this.$element.trigger("change"); + self.$element.val(val); + self.$element.trigger("change"); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger("change"); + } } SelectAdapter.prototype.query = function (params, callback) { @@ -789,19 +794,19 @@ define('select2/dropdown',[ return Dropdown; }) ; -define('select2/selection',[ - './utils' +define('select2/selection/single',[ + '../utils' ], function (Utils) { - function Selection ($element, options) { + function SingleSelection ($element, options) { this.$element = $element; 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 = $( '' + '' + @@ -813,7 +818,7 @@ define('select2/selection',[ return $selection; } - Selection.prototype.bind = function ($container) { + SingleSelection.prototype.bind = function ($container) { var self = this; this.$selection.on('click', function (evt) { @@ -823,15 +828,15 @@ define('select2/selection',[ }); } - Selection.prototype.clear = function () { - this.$selection.find(".rendered-selection").text(""); + SingleSelection.prototype.clear = function () { + this.$selection.find(".rendered-selection").empty(); } - Selection.prototype.display = function (data) { + SingleSelection.prototype.display = function (data) { return data.text; } - Selection.prototype.update = function (data) { + SingleSelection.prototype.update = function (data) { if (data.length == 0) { this.clear(); return; @@ -844,22 +849,102 @@ define('select2/selection',[ 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 = $( + '' + + '
          ' + + '
          ' + ); + + 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 = $('
            '); + + $selection.text(formatted); + $selection.data("data", data); + + $selections.push($selection); + } + + this.$selection.find(".rendered-selection").append($selections); + } + + return MultipleSelection; }); define('select2/options',[ './data/select', './results', './dropdown', - './selection' -], function (SelectData, ResultsList, Dropdown, Selection) { + './selection/single', + './selection/multiple' +], function (SelectData, ResultsList, Dropdown, SingleSelection, + MultipleSelection) { function Options (options) { this.options = options; this.dataAdapter = SelectData; this.resultsAdapter = ResultsList; 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; @@ -872,6 +957,11 @@ define('select2/core',[ ], function ($, Options, Utils) { var Select2 = function ($element, options) { this.$element = $element; + + options = options || {}; + + options.multiple = options.multiple || $element.prop("multiple"); + this.options = new Options(options); Select2.__super__.constructor.call(this); diff --git a/playground/basic/basic.html b/playground/basic/basic.html index 311a201f..2891cd43 100644 --- a/playground/basic/basic.html +++ b/playground/basic/basic.html @@ -12,9 +12,7 @@ - -
            - @@ -66,11 +64,10 @@
            -
            - - + @@ -122,7 +119,8 @@ diff --git a/src/js/select2/core.js b/src/js/select2/core.js index f7a3a7fd..5717c02c 100644 --- a/src/js/select2/core.js +++ b/src/js/select2/core.js @@ -5,6 +5,11 @@ define([ ], function ($, Options, Utils) { var Select2 = function ($element, options) { this.$element = $element; + + options = options || {}; + + options.multiple = options.multiple || $element.prop("multiple"); + this.options = new Options(options); Select2.__super__.constructor.call(this); diff --git a/src/js/select2/data/select.js b/src/js/select2/data/select.js index 98f7663f..804a65ee 100644 --- a/src/js/select2/data/select.js +++ b/src/js/select2/data/select.js @@ -26,29 +26,32 @@ define([ }; SelectAdapter.prototype.select = function (data) { - var val; + var self = this; if (this.$element.prop("multiple")) { - var currentData = this.current(); + this.current(function (currentData) { + var val = []; - data = [data]; - data.push(currentData); + data = [data]; + data.push.apply(data, currentData); - val = []; + for (var d = 0; d < data.length; d++) { + id = data[d].id; - for (var d = 0; d < data.length; d++) { - id = data[d].id; - - if (ids.indexOf(id) === -1) { - val.push(id); + if (val.indexOf(id) === -1) { + val.push(id); + } } - } - } else { - val = data.id; - } - this.$element.val(val); - this.$element.trigger("change"); + self.$element.val(val); + self.$element.trigger("change"); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger("change"); + } } SelectAdapter.prototype.query = function (params, callback) { diff --git a/src/js/select2/options.js b/src/js/select2/options.js index 8193cde3..1a0589c4 100644 --- a/src/js/select2/options.js +++ b/src/js/select2/options.js @@ -2,15 +2,25 @@ define([ './data/select', './results', './dropdown', - './selection' -], function (SelectData, ResultsList, Dropdown, Selection) { + './selection/single', + './selection/multiple' +], function (SelectData, ResultsList, Dropdown, SingleSelection, + MultipleSelection) { function Options (options) { this.options = options; this.dataAdapter = SelectData; this.resultsAdapter = ResultsList; 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; diff --git a/src/js/select2/selection/multiple.js b/src/js/select2/selection/multiple.js new file mode 100644 index 00000000..5cf7f6f2 --- /dev/null +++ b/src/js/select2/selection/multiple.js @@ -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 = $( + '' + + '
              ' + + '
              ' + ); + + 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 = $('
                '); + + $selection.text(formatted); + $selection.data("data", data); + + $selections.push($selection); + } + + this.$selection.find(".rendered-selection").append($selections); + } + + return MultipleSelection; +}); diff --git a/src/js/select2/selection.js b/src/js/select2/selection/single.js similarity index 57% rename from src/js/select2/selection.js rename to src/js/select2/selection/single.js index 0f8d62d5..fc8c7801 100644 --- a/src/js/select2/selection.js +++ b/src/js/select2/selection/single.js @@ -1,16 +1,16 @@ define([ - './utils' + '../utils' ], function (Utils) { - function Selection ($element, options) { + function SingleSelection ($element, options) { this.$element = $element; 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 = $( '' + '' + @@ -22,7 +22,7 @@ define([ return $selection; } - Selection.prototype.bind = function ($container) { + SingleSelection.prototype.bind = function ($container) { var self = this; this.$selection.on('click', function (evt) { @@ -32,15 +32,15 @@ define([ }); } - Selection.prototype.clear = function () { - this.$selection.find(".rendered-selection").text(""); + SingleSelection.prototype.clear = function () { + this.$selection.find(".rendered-selection").empty(); } - Selection.prototype.display = function (data) { + SingleSelection.prototype.display = function (data) { return data.text; } - Selection.prototype.update = function (data) { + SingleSelection.prototype.update = function (data) { if (data.length == 0) { this.clear(); return; @@ -53,5 +53,5 @@ define([ this.$selection.find(".rendered-selection").html(formatted); } - return Selection; + return SingleSelection; }); diff --git a/src/js/select2/utils.js b/src/js/select2/utils.js index 4e856d04..66e639b9 100644 --- a/src/js/select2/utils.js +++ b/src/js/select2/utils.js @@ -59,6 +59,8 @@ define([], function () { calledConstructor.apply(this, arguments); } + DecoratorClass.displayName = SuperClass.displayName; + function ctr () { this.constructor = DecoratedClass; } diff --git a/src/scss/_dropdown.scss b/src/scss/_dropdown.scss index e736eb74..1a0e8bb3 100644 --- a/src/scss/_dropdown.scss +++ b/src/scss/_dropdown.scss @@ -11,10 +11,11 @@ position: absolute; left: -100000px; - top: -100000px; width: 100%; + z-index: 100; + .results { display: block; @@ -35,10 +36,10 @@ } &.open .dropdown { + border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; left: 0; - top: 28px; } } diff --git a/src/scss/_multiple.scss b/src/scss/_multiple.scss new file mode 100644 index 00000000..142ec131 --- /dev/null +++ b/src/scss/_multiple.scss @@ -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; + } + } +} diff --git a/src/scss/core.scss b/src/scss/core.scss index 8a88b7d4..6fd18594 100644 --- a/src/scss/core.scss +++ b/src/scss/core.scss @@ -8,6 +8,8 @@ } @import "single"; +@import "multiple"; + @import "dropdown"; @import "theme/default/layout"; diff --git a/src/scss/theme/default/layout.scss b/src/scss/theme/default/layout.scss index f088774c..d6fffc94 100644 --- a/src/scss/theme/default/layout.scss +++ b/src/scss/theme/default/layout.scss @@ -1,20 +1,50 @@ .select2-container.select2-theme-default { - .selection .single-select { - background-color: #eee; - border: 1px solid #aaa; - border-radius: 4px; + .selection { + .single-select { + background-color: #eee; + border: 1px solid #aaa; + border-radius: 4px; - .rendered-selection { - color: #444; - line-height: 28px; + .rendered-selection { + color: #444; + line-height: 28px; + } + } + + .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 { - .selection .single-select { - border-bottom: none; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + .selection { + .single-select, + .multiple-select { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } } }