Skip to content

Commit 3d1dc36

Browse files
committed
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.
1 parent 5cf0dbf commit 3d1dc36

14 files changed

Lines changed: 344 additions & 18 deletions

File tree

dist/css/select2.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@
6666
left: 0; }
6767

6868
.select2-container.select2-theme-default .selection .single-select {
69-
background-color: #eee;
69+
background-color: #fff;
7070
border: 1px solid #aaa;
7171
border-radius: 4px; }
7272
.select2-container.select2-theme-default .selection .single-select .rendered-selection {
7373
color: #444;
7474
line-height: 28px; }
75+
.select2-container.select2-theme-default .selection .single-select .rendered-selection .placeholder {
76+
color: #999; }
7577
.select2-container.select2-theme-default .selection .multiple-select {
7678
background-color: white;
7779
border: 1px solid #aaa;
@@ -81,6 +83,9 @@
8183
margin: 0;
8284
padding: 5px;
8385
padding-bottom: 0; }
86+
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .placeholder {
87+
color: #999;
88+
float: left; }
8489
.select2-container.select2-theme-default .selection .multiple-select .rendered-selection .choice {
8590
background-color: #e4e4e4;
8691
border: 1px solid #aaa;

dist/css/select2.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/js/select2.amd.full.js

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ define('select2/selection/single',[
353353
return data.text;
354354
};
355355

356+
SingleSelection.prototype.selectionContainer = function () {
357+
return $('<span></span>');
358+
};
359+
356360
SingleSelection.prototype.update = function (data) {
357361
if (data.length === 0) {
358362
this.clear();
@@ -415,6 +419,10 @@ define('select2/selection/multiple',[
415419
return data.text;
416420
};
417421

422+
MultipleSelection.prototype.selectionContainer = function () {
423+
return $('<li class="choice"></li>');
424+
};
425+
418426
MultipleSelection.prototype.update = function (data) {
419427
this.clear();
420428

@@ -429,7 +437,7 @@ define('select2/selection/multiple',[
429437

430438
var formatted = this.display(selection);
431439

432-
var $selection = $('<ul class="choice"></ul>');
440+
var $selection = this.selectionContainer();
433441

434442
$selection.text(formatted);
435443
$selection.data('data', data);
@@ -443,6 +451,49 @@ define('select2/selection/multiple',[
443451
return MultipleSelection;
444452
});
445453

454+
define('select2/selection/placeholder',[
455+
'../utils'
456+
], function (Utils) {
457+
function Placeholder (decorated, $element, options) {
458+
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
459+
460+
decorated.call(this, $element, options);
461+
}
462+
463+
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
464+
if (typeof placeholder === 'string') {
465+
placeholder = {
466+
id: '',
467+
text: placeholder
468+
};
469+
}
470+
471+
return placeholder;
472+
};
473+
474+
Placeholder.prototype.update = function (decorated, data) {
475+
var singlePlaceholder = (
476+
data.length == 1 && data[0].id != this.placeholder.id
477+
);
478+
var multipleSelections = data.length > 1;
479+
480+
if (multipleSelections || singlePlaceholder) {
481+
return decorated.call(this, data);
482+
}
483+
484+
this.clear();
485+
486+
var $placeholder = this.selectionContainer();
487+
488+
$placeholder.html(this.display(this.placeholder));
489+
$placeholder.addClass('placeholder').removeClass('choice');
490+
491+
this.$selection.find('.rendered-selection').append($placeholder);
492+
};
493+
494+
return Placeholder;
495+
});
496+
446497
define('select2/data/base',[
447498
'../utils'
448499
], function (Utils) {
@@ -840,6 +891,7 @@ define('select2/defaults',[
840891

841892
'./selection/single',
842893
'./selection/multiple',
894+
'./selection/placeholder',
843895

844896
'./utils',
845897

@@ -849,7 +901,9 @@ define('select2/defaults',[
849901

850902
'./dropdown',
851903
'./dropdown/search'
852-
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
904+
], function (ResultsList,
905+
SingleSelection, MultipleSelection, Placeholder,
906+
Utils,
853907
SelectData, ArrayData, AjaxData,
854908
Dropdown, Search) {
855909
function Defaults () {
@@ -885,6 +939,14 @@ define('select2/defaults',[
885939
} else {
886940
options.selectionAdapter = SingleSelection;
887941
}
942+
943+
// Add the placeholder mixin if a placeholder was specified
944+
if (options.placeholder != null) {
945+
options.selectionAdapter = Utils.Decorate(
946+
options.selectionAdapter,
947+
Placeholder
948+
);
949+
}
888950
}
889951

890952
return options;

dist/js/select2.amd.js

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ define('select2/selection/single',[
353353
return data.text;
354354
};
355355

356+
SingleSelection.prototype.selectionContainer = function () {
357+
return $('<span></span>');
358+
};
359+
356360
SingleSelection.prototype.update = function (data) {
357361
if (data.length === 0) {
358362
this.clear();
@@ -415,6 +419,10 @@ define('select2/selection/multiple',[
415419
return data.text;
416420
};
417421

422+
MultipleSelection.prototype.selectionContainer = function () {
423+
return $('<li class="choice"></li>');
424+
};
425+
418426
MultipleSelection.prototype.update = function (data) {
419427
this.clear();
420428

@@ -429,7 +437,7 @@ define('select2/selection/multiple',[
429437

430438
var formatted = this.display(selection);
431439

432-
var $selection = $('<ul class="choice"></ul>');
440+
var $selection = this.selectionContainer();
433441

434442
$selection.text(formatted);
435443
$selection.data('data', data);
@@ -443,6 +451,49 @@ define('select2/selection/multiple',[
443451
return MultipleSelection;
444452
});
445453

454+
define('select2/selection/placeholder',[
455+
'../utils'
456+
], function (Utils) {
457+
function Placeholder (decorated, $element, options) {
458+
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
459+
460+
decorated.call(this, $element, options);
461+
}
462+
463+
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
464+
if (typeof placeholder === 'string') {
465+
placeholder = {
466+
id: '',
467+
text: placeholder
468+
};
469+
}
470+
471+
return placeholder;
472+
};
473+
474+
Placeholder.prototype.update = function (decorated, data) {
475+
var singlePlaceholder = (
476+
data.length == 1 && data[0].id != this.placeholder.id
477+
);
478+
var multipleSelections = data.length > 1;
479+
480+
if (multipleSelections || singlePlaceholder) {
481+
return decorated.call(this, data);
482+
}
483+
484+
this.clear();
485+
486+
var $placeholder = this.selectionContainer();
487+
488+
$placeholder.html(this.display(this.placeholder));
489+
$placeholder.addClass('placeholder').removeClass('choice');
490+
491+
this.$selection.find('.rendered-selection').append($placeholder);
492+
};
493+
494+
return Placeholder;
495+
});
496+
446497
define('select2/data/base',[
447498
'../utils'
448499
], function (Utils) {
@@ -840,6 +891,7 @@ define('select2/defaults',[
840891

841892
'./selection/single',
842893
'./selection/multiple',
894+
'./selection/placeholder',
843895

844896
'./utils',
845897

@@ -849,7 +901,9 @@ define('select2/defaults',[
849901

850902
'./dropdown',
851903
'./dropdown/search'
852-
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
904+
], function (ResultsList,
905+
SingleSelection, MultipleSelection, Placeholder,
906+
Utils,
853907
SelectData, ArrayData, AjaxData,
854908
Dropdown, Search) {
855909
function Defaults () {
@@ -885,6 +939,14 @@ define('select2/defaults',[
885939
} else {
886940
options.selectionAdapter = SingleSelection;
887941
}
942+
943+
// Add the placeholder mixin if a placeholder was specified
944+
if (options.placeholder != null) {
945+
options.selectionAdapter = Utils.Decorate(
946+
options.selectionAdapter,
947+
Placeholder
948+
);
949+
}
888950
}
889951

890952
return options;

dist/js/select2.full.js

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9891,6 +9891,10 @@ define('select2/selection/single',[
98919891
return data.text;
98929892
};
98939893

9894+
SingleSelection.prototype.selectionContainer = function () {
9895+
return $('<span></span>');
9896+
};
9897+
98949898
SingleSelection.prototype.update = function (data) {
98959899
if (data.length === 0) {
98969900
this.clear();
@@ -9953,6 +9957,10 @@ define('select2/selection/multiple',[
99539957
return data.text;
99549958
};
99559959

9960+
MultipleSelection.prototype.selectionContainer = function () {
9961+
return $('<li class="choice"></li>');
9962+
};
9963+
99569964
MultipleSelection.prototype.update = function (data) {
99579965
this.clear();
99589966

@@ -9967,7 +9975,7 @@ define('select2/selection/multiple',[
99679975

99689976
var formatted = this.display(selection);
99699977

9970-
var $selection = $('<ul class="choice"></ul>');
9978+
var $selection = this.selectionContainer();
99719979

99729980
$selection.text(formatted);
99739981
$selection.data('data', data);
@@ -9981,6 +9989,49 @@ define('select2/selection/multiple',[
99819989
return MultipleSelection;
99829990
});
99839991

9992+
define('select2/selection/placeholder',[
9993+
'../utils'
9994+
], function (Utils) {
9995+
function Placeholder (decorated, $element, options) {
9996+
this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
9997+
9998+
decorated.call(this, $element, options);
9999+
}
10000+
10001+
Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
10002+
if (typeof placeholder === 'string') {
10003+
placeholder = {
10004+
id: '',
10005+
text: placeholder
10006+
};
10007+
}
10008+
10009+
return placeholder;
10010+
};
10011+
10012+
Placeholder.prototype.update = function (decorated, data) {
10013+
var singlePlaceholder = (
10014+
data.length == 1 && data[0].id != this.placeholder.id
10015+
);
10016+
var multipleSelections = data.length > 1;
10017+
10018+
if (multipleSelections || singlePlaceholder) {
10019+
return decorated.call(this, data);
10020+
}
10021+
10022+
this.clear();
10023+
10024+
var $placeholder = this.selectionContainer();
10025+
10026+
$placeholder.html(this.display(this.placeholder));
10027+
$placeholder.addClass('placeholder').removeClass('choice');
10028+
10029+
this.$selection.find('.rendered-selection').append($placeholder);
10030+
};
10031+
10032+
return Placeholder;
10033+
});
10034+
998410035
define('select2/data/base',[
998510036
'../utils'
998610037
], function (Utils) {
@@ -10378,6 +10429,7 @@ define('select2/defaults',[
1037810429

1037910430
'./selection/single',
1038010431
'./selection/multiple',
10432+
'./selection/placeholder',
1038110433

1038210434
'./utils',
1038310435

@@ -10387,7 +10439,9 @@ define('select2/defaults',[
1038710439

1038810440
'./dropdown',
1038910441
'./dropdown/search'
10390-
], function (ResultsList, SingleSelection, MultipleSelection, Utils,
10442+
], function (ResultsList,
10443+
SingleSelection, MultipleSelection, Placeholder,
10444+
Utils,
1039110445
SelectData, ArrayData, AjaxData,
1039210446
Dropdown, Search) {
1039310447
function Defaults () {
@@ -10423,6 +10477,14 @@ define('select2/defaults',[
1042310477
} else {
1042410478
options.selectionAdapter = SingleSelection;
1042510479
}
10480+
10481+
// Add the placeholder mixin if a placeholder was specified
10482+
if (options.placeholder != null) {
10483+
options.selectionAdapter = Utils.Decorate(
10484+
options.selectionAdapter,
10485+
Placeholder
10486+
);
10487+
}
1042610488
}
1042710489

1042810490
return options;

dist/js/select2.full.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)