1
0
mirror of synced 2025-02-09 16:49:24 +03:00

Added support for placeholders

Placeholder support has been implemented as a separate module, so
any selection container should be able to be decorated and get
instant placeholder support. It hooks into the updating method of
selections, and determines when to display the placeholder based
on the options that are being updated.

It works in the same way as the old placeholders. If no options
are selected and being displayed, like in the case of a multiple
select, then the placeholder will always be shown.  If one option
is being displayed, and the id of the placeholder matches the id
of the selected element, then the placeholder will be shown.  This
is similar to the functionality that was present in Select2 2.x,
where the placeholder could be passed in as an object that would
be compared to the selection.

This still requires that, for single selects, the first element
must match the placeholder id.  Because the default placeholder id
is a blank string, this will maintain backwards compatibility with
past versions where the first option should be blank.  This can
still be overridden to point at a different id, keeping support
for systems where the placeholder doesn't use a blank value.

**Note:** This does not hide the blank option for single selects,
but that will still be maintained for backwards compatibility
within the results module.  It will not depend on a placeholder
being present, but instead will hide any options with blank text.
This commit is contained in:
Kevin Brown 2014-10-16 19:59:38 -04:00
parent 5cf0dbf114
commit 3d1dc36711
14 changed files with 344 additions and 18 deletions

View File

@ -66,12 +66,14 @@
left: 0; }
.select2-container.select2-theme-default .selection .single-select {
background-color: #eee;
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px; }
.select2-container.select2-theme-default .selection .single-select .rendered-selection {
color: #444;
line-height: 28px; }
.select2-container.select2-theme-default .selection .single-select .rendered-selection .placeholder {
color: #999; }
.select2-container.select2-theme-default .selection .multiple-select {
background-color: white;
border: 1px solid #aaa;
@ -81,6 +83,9 @@
margin: 0;
padding: 5px;
padding-bottom: 0; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .placeholder {
color: #999;
float: left; }
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice {
background-color: #e4e4e4;
border: 1px solid #aaa;

File diff suppressed because one or more lines are too long

View File

@ -353,6 +353,10 @@ define('select2/selection/single',[
return data.text;
};
SingleSelection.prototype.selectionContainer = function () {
return $('<span></span>');
};
SingleSelection.prototype.update = function (data) {
if (data.length === 0) {
this.clear();
@ -415,6 +419,10 @@ define('select2/selection/multiple',[
return data.text;
};
MultipleSelection.prototype.selectionContainer = function () {
return $('<li class="choice"></li>');
};
MultipleSelection.prototype.update = function (data) {
this.clear();
@ -429,7 +437,7 @@ define('select2/selection/multiple',[
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
var $selection = this.selectionContainer();
$selection.text(formatted);
$selection.data('data', data);
@ -443,6 +451,49 @@ define('select2/selection/multiple',[
return MultipleSelection;
});
define('select2/selection/placeholder',[
'../utils'
], function (Utils) {
function Placeholder (decorated, $element, options) {
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
decorated.call(this, $element, options);
}
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
if (typeof placeholder === 'string') {
placeholder = {
id: '',
text: placeholder
};
}
return placeholder;
};
Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
);
var multipleSelections = data.length > 1;
if (multipleSelections || singlePlaceholder) {
return decorated.call(this, data);
}
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder);
};
return Placeholder;
});
define('select2/data/base',[
'../utils'
], function (Utils) {
@ -840,6 +891,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./utils',
@ -849,7 +901,9 @@ define('select2/defaults',[
'./dropdown',
'./dropdown/search'
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
Dropdown, Search) {
function Defaults () {
@ -885,6 +939,14 @@ define('select2/defaults',[
} else {
options.selectionAdapter = SingleSelection;
}
// Add the placeholder mixin if a placeholder was specified
if (options.placeholder != null) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
Placeholder
);
}
}
return options;

View File

@ -353,6 +353,10 @@ define('select2/selection/single',[
return data.text;
};
SingleSelection.prototype.selectionContainer = function () {
return $('<span></span>');
};
SingleSelection.prototype.update = function (data) {
if (data.length === 0) {
this.clear();
@ -415,6 +419,10 @@ define('select2/selection/multiple',[
return data.text;
};
MultipleSelection.prototype.selectionContainer = function () {
return $('<li class="choice"></li>');
};
MultipleSelection.prototype.update = function (data) {
this.clear();
@ -429,7 +437,7 @@ define('select2/selection/multiple',[
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
var $selection = this.selectionContainer();
$selection.text(formatted);
$selection.data('data', data);
@ -443,6 +451,49 @@ define('select2/selection/multiple',[
return MultipleSelection;
});
define('select2/selection/placeholder',[
'../utils'
], function (Utils) {
function Placeholder (decorated, $element, options) {
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
decorated.call(this, $element, options);
}
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
if (typeof placeholder === 'string') {
placeholder = {
id: '',
text: placeholder
};
}
return placeholder;
};
Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
);
var multipleSelections = data.length > 1;
if (multipleSelections || singlePlaceholder) {
return decorated.call(this, data);
}
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder);
};
return Placeholder;
});
define('select2/data/base',[
'../utils'
], function (Utils) {
@ -840,6 +891,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./utils',
@ -849,7 +901,9 @@ define('select2/defaults',[
'./dropdown',
'./dropdown/search'
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
Dropdown, Search) {
function Defaults () {
@ -885,6 +939,14 @@ define('select2/defaults',[
} else {
options.selectionAdapter = SingleSelection;
}
// Add the placeholder mixin if a placeholder was specified
if (options.placeholder != null) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
Placeholder
);
}
}
return options;

View File

@ -9891,6 +9891,10 @@ define('select2/selection/single',[
return data.text;
};
SingleSelection.prototype.selectionContainer = function () {
return $('<span></span>');
};
SingleSelection.prototype.update = function (data) {
if (data.length === 0) {
this.clear();
@ -9953,6 +9957,10 @@ define('select2/selection/multiple',[
return data.text;
};
MultipleSelection.prototype.selectionContainer = function () {
return $('<li class="choice"></li>');
};
MultipleSelection.prototype.update = function (data) {
this.clear();
@ -9967,7 +9975,7 @@ define('select2/selection/multiple',[
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
var $selection = this.selectionContainer();
$selection.text(formatted);
$selection.data('data', data);
@ -9981,6 +9989,49 @@ define('select2/selection/multiple',[
return MultipleSelection;
});
define('select2/selection/placeholder',[
'../utils'
], function (Utils) {
function Placeholder (decorated, $element, options) {
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
decorated.call(this, $element, options);
}
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
if (typeof placeholder === 'string') {
placeholder = {
id: '',
text: placeholder
};
}
return placeholder;
};
Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
);
var multipleSelections = data.length > 1;
if (multipleSelections || singlePlaceholder) {
return decorated.call(this, data);
}
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder);
};
return Placeholder;
});
define('select2/data/base',[
'../utils'
], function (Utils) {
@ -10378,6 +10429,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./utils',
@ -10387,7 +10439,9 @@ define('select2/defaults',[
'./dropdown',
'./dropdown/search'
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
Dropdown, Search) {
function Defaults () {
@ -10423,6 +10477,14 @@ define('select2/defaults',[
} else {
options.selectionAdapter = SingleSelection;
}
// Add the placeholder mixin if a placeholder was specified
if (options.placeholder != null) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
Placeholder
);
}
}
return options;

File diff suppressed because one or more lines are too long

66
dist/js/select2.js vendored
View File

@ -782,6 +782,10 @@ define('select2/selection/single',[
return data.text;
};
SingleSelection.prototype.selectionContainer = function () {
return $('<span></span>');
};
SingleSelection.prototype.update = function (data) {
if (data.length === 0) {
this.clear();
@ -844,6 +848,10 @@ define('select2/selection/multiple',[
return data.text;
};
MultipleSelection.prototype.selectionContainer = function () {
return $('<li class="choice"></li>');
};
MultipleSelection.prototype.update = function (data) {
this.clear();
@ -858,7 +866,7 @@ define('select2/selection/multiple',[
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
var $selection = this.selectionContainer();
$selection.text(formatted);
$selection.data('data', data);
@ -872,6 +880,49 @@ define('select2/selection/multiple',[
return MultipleSelection;
});
define('select2/selection/placeholder',[
'../utils'
], function (Utils) {
function Placeholder (decorated, $element, options) {
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
decorated.call(this, $element, options);
}
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
if (typeof placeholder === 'string') {
placeholder = {
id: '',
text: placeholder
};
}
return placeholder;
};
Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
);
var multipleSelections = data.length > 1;
if (multipleSelections || singlePlaceholder) {
return decorated.call(this, data);
}
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder);
};
return Placeholder;
});
define('select2/data/base',[
'../utils'
], function (Utils) {
@ -1269,6 +1320,7 @@ define('select2/defaults',[
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./utils',
@ -1278,7 +1330,9 @@ define('select2/defaults',[
'./dropdown',
'./dropdown/search'
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
Dropdown, Search) {
function Defaults () {
@ -1314,6 +1368,14 @@ define('select2/defaults',[
} else {
options.selectionAdapter = SingleSelection;
}
// Add the placeholder mixin if a placeholder was specified
if (options.placeholder != null) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
Placeholder
);
}
}
return options;

File diff suppressed because one or more lines are too long

View File

@ -76,7 +76,9 @@ $(".js-example-basic-multiple").select2();
</p>
<p>
<select class="js-example-placeholder-single js-states form-control"></select>
<select class="js-example-placeholder-single js-states form-control">
<option></option>
</select>
</p>
<p>
@ -273,7 +275,7 @@ var $states = $(".js-source-states");
var statesOptions = $states.html();
$states.remove();
$(".js-states").html(statesOptions);
$(".js-states").append(statesOptions);
$("[data-fill-from]").each(function () {
var $this = $(this);

View File

@ -3,6 +3,7 @@ define([
'./selection/single',
'./selection/multiple',
'./selection/placeholder',
'./utils',
@ -12,7 +13,9 @@ define([
'./dropdown',
'./dropdown/search'
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
Dropdown, Search) {
function Defaults () {
@ -48,6 +51,14 @@ define([
} else {
options.selectionAdapter = SingleSelection;
}
// Add the placeholder mixin if a placeholder was specified
if (options.placeholder != null) {
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
Placeholder
);
}
}
return options;

View File

@ -44,6 +44,10 @@ define([
return data.text;
};
MultipleSelection.prototype.selectionContainer = function () {
return $('<li class="choice"></li>');
};
MultipleSelection.prototype.update = function (data) {
this.clear();
@ -58,7 +62,7 @@ define([
var formatted = this.display(selection);
var $selection = $('<ul class="choice"></ul>');
var $selection = this.selectionContainer();
$selection.text(formatted);
$selection.data('data', data);

42
src/js/select2/selection/placeholder.js vendored Normal file
View File

@ -0,0 +1,42 @@
define([
'../utils'
], function (Utils) {
function Placeholder (decorated, $element, options) {
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
decorated.call(this, $element, options);
}
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
if (typeof placeholder === 'string') {
placeholder = {
id: '',
text: placeholder
};
}
return placeholder;
};
Placeholder.prototype.update = function (decorated, data) {
var singlePlaceholder = (
data.length == 1 && data[0].id != this.placeholder.id
);
var multipleSelections = data.length > 1;
if (multipleSelections || singlePlaceholder) {
return decorated.call(this, data);
}
this.clear();
var $placeholder = this.selectionContainer();
$placeholder.html(this.display(this.placeholder));
$placeholder.addClass('placeholder').removeClass('choice');
this.$selection.find('.rendered-selection').append($placeholder);
};
return Placeholder;
});

View File

@ -49,6 +49,10 @@ define([
return data.text;
};
SingleSelection.prototype.selectionContainer = function () {
return $('<span></span>');
};
SingleSelection.prototype.update = function (data) {
if (data.length === 0) {
this.clear();

View File

@ -1,13 +1,17 @@
.select2-container.select2-theme-default {
.selection {
.single-select {
background-color: #eee;
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px;
.rendered-selection {
color: #444;
line-height: 28px;
.placeholder {
color: #999;
}
}
}
@ -22,6 +26,12 @@
padding: 5px;
padding-bottom: 0;
.placeholder {
color: #999;
float: left;
}
.choice {
background-color: #e4e4e4;