Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

Commit 50c6273

Browse files
authored
Merge pull request #2015 from DmitryGonchar/master
fix($selectMultiple): allow user to override `getPlaceholder()` Behavior
2 parents 25c06c8 + 74fd361 commit 50c6273

File tree

6 files changed

+87
-17
lines changed

6 files changed

+87
-17
lines changed

src/bootstrap/select-multiple.tpl.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
autocapitalize="off"
99
spellcheck="false"
1010
class="ui-select-search input-xs"
11-
placeholder="{{$selectMultiple.getPlaceholder()}}"
11+
placeholder="{{$select.getPlaceholder()}}"
1212
ng-disabled="$select.disabled"
1313
ng-click="$select.activate()"
1414
ng-model="$select.search"

src/select2/select-multiple.tpl.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
aria-label="{{ $select.baseTitle }}"
1717
aria-activedescendant="ui-select-choices-row-{{ $select.generatedId }}-{{ $select.activeIndex }}"
1818
class="select2-input ui-select-search"
19-
placeholder="{{$selectMultiple.getPlaceholder()}}"
19+
placeholder="{{$select.getPlaceholder()}}"
2020
ng-disabled="$select.disabled"
2121
ng-hide="$select.disabled"
2222
ng-model="$select.search"

src/selectize/select-multiple.tpl.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<input type="search" autocomplete="off" tabindex="-1"
77
class="ui-select-search"
88
ng-class="{'ui-select-search-hidden':!$select.searchEnabled}"
9-
placeholder="{{$selectMultiple.getPlaceholder()}}"
9+
placeholder="{{$select.getPlaceholder()}}"
1010
ng-model="$select.search"
1111
ng-disabled="$select.disabled"
1212
aria-expanded="{{$select.open}}"
@@ -15,4 +15,4 @@
1515
</div>
1616
<div class="ui-select-choices"></div>
1717
<div class="ui-select-no-choice"></div>
18-
</div>
18+
</div>

src/uiSelectController.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ uis.controller('uiSelectCtrl',
6565
return isNil(ctrl.selected) || ctrl.selected === '' || (ctrl.multiple && ctrl.selected.length === 0);
6666
};
6767

68+
ctrl.getPlaceholder = function(){
69+
if(ctrl.selected && ctrl.selected.length) return;
70+
return ctrl.placeholder;
71+
};
72+
6873
function _findIndex(collection, predicate, thisArg){
6974
if (collection.findIndex){
7075
return collection.findIndex(predicate, thisArg);

src/uiSelectMultipleDirective.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,6 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
6262
return true;
6363
};
6464

65-
ctrl.getPlaceholder = function(){
66-
//Refactor single?
67-
if($select.selected && $select.selected.length) return;
68-
return $select.placeholder;
69-
};
70-
7165

7266
}],
7367
controllerAs: '$selectMultiple',

test/select.spec.js

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ describe('ui-select tests', function () {
1515
Escape: 27
1616
};
1717

18+
var defaultPlaceholder = 'Pick one...';
19+
1820
function isNil(value) {
1921
return angular.isUndefined(value) || value === null;
2022
}
@@ -191,6 +193,10 @@ describe('ui-select tests', function () {
191193
return $(el).find('.ui-select-match > span:first > span[ng-transclude]:not(.ng-hide)').text();
192194
}
193195

196+
function getMatchPlaceholder(el) {
197+
return el.find('.ui-select-search').attr('placeholder')
198+
}
199+
194200
function clickItem(el, text) {
195201

196202
if (!isDropdownOpened(el)) {
@@ -1874,7 +1880,9 @@ describe('ui-select tests', function () {
18741880
function createUiSelectMultiple(attrs) {
18751881
var attrsHtml = '',
18761882
choicesAttrsHtml = '',
1877-
matchesAttrsHtml = '';
1883+
matchesAttrsHtml = '',
1884+
matchesPlaceholder = defaultPlaceholder;
1885+
18781886
if (attrs !== undefined) {
18791887
if (attrs.disabled !== undefined) { attrsHtml += ' ng-disabled="' + attrs.disabled + '"'; }
18801888
if (attrs.required !== undefined) { attrsHtml += ' ng-required="' + attrs.required + '"'; }
@@ -1884,23 +1892,27 @@ describe('ui-select tests', function () {
18841892
if (attrs.taggingTokens !== undefined) { attrsHtml += ' tagging-tokens="' + attrs.taggingTokens + '"'; }
18851893
if (attrs.taggingLabel !== undefined) { attrsHtml += ' tagging-label="' + attrs.taggingLabel + '"'; }
18861894
if (attrs.inputId !== undefined) { attrsHtml += ' input-id="' + attrs.inputId + '"'; }
1887-
if (attrs.groupBy !== undefined) { choicesAttrsHtml += ' group-by="' + attrs.groupBy + '"'; }
1888-
if (attrs.uiDisableChoice !== undefined) { choicesAttrsHtml += ' ui-disable-choice="' + attrs.uiDisableChoice + '"'; }
1889-
if (attrs.lockChoice !== undefined) { matchesAttrsHtml += ' ui-lock-choice="' + attrs.lockChoice + '"'; }
18901895
if (attrs.removeSelected !== undefined) { attrsHtml += ' remove-selected="' + attrs.removeSelected + '"'; }
18911896
if (attrs.resetSearchInput !== undefined) { attrsHtml += ' reset-search-input="' + attrs.resetSearchInput + '"'; }
18921897
if (attrs.limit !== undefined) { attrsHtml += ' limit="' + attrs.limit + '"'; }
18931898
if (attrs.onSelect !== undefined) { attrsHtml += ' on-select="' + attrs.onSelect + '"'; }
18941899
if (attrs.removeSelected !== undefined) { attrsHtml += ' remove-selected="' + attrs.removeSelected + '"'; }
1895-
if (attrs.refresh !== undefined) { choicesAttrsHtml += ' refresh="' + attrs.refresh + '"'; }
1896-
if (attrs.refreshDelay !== undefined) { choicesAttrsHtml += ' refresh-delay="' + attrs.refreshDelay + '"'; }
18971900
if (attrs.spinnerEnabled !== undefined) { attrsHtml += ' spinner-enabled="' + attrs.spinnerEnabled + '"'; }
18981901
if (attrs.spinnerClass !== undefined) { attrsHtml += ' spinner-class="' + attrs.spinnerClass + '"'; }
1902+
1903+
if (attrs.groupBy !== undefined) { choicesAttrsHtml += ' group-by="' + attrs.groupBy + '"'; }
1904+
if (attrs.uiDisableChoice !== undefined) { choicesAttrsHtml += ' ui-disable-choice="' + attrs.uiDisableChoice + '"'; }
1905+
if (attrs.refresh !== undefined) { choicesAttrsHtml += ' refresh="' + attrs.refresh + '"'; }
1906+
if (attrs.refreshDelay !== undefined) { choicesAttrsHtml += ' refresh-delay="' + attrs.refreshDelay + '"'; }
1907+
1908+
if (attrs.lockChoice !== undefined) { matchesAttrsHtml += ' ui-lock-choice="' + attrs.lockChoice + '"'; }
18991909
}
19001910

1911+
matchesAttrsHtml += ' placeholder="' + matchesPlaceholder + '"';
1912+
19011913
return compileTemplate(
19021914
'<ui-select multiple ng-model="selection.selectedMultiple"' + attrsHtml + ' theme="bootstrap" style="width: 800px;"> \
1903-
<ui-select-match "' + matchesAttrsHtml + ' placeholder="Pick one...">{{$item.name}} &lt;{{$item.email}}&gt;</ui-select-match> \
1915+
<ui-select-match ' + matchesAttrsHtml + '>{{$item.name}} &lt;{{$item.email}}&gt;</ui-select-match> \
19041916
<ui-select-choices repeat="person in people | filter: $select.search"' + choicesAttrsHtml + '> \
19051917
<div ng-bind-html="person.name | highlight: $select.search"></div> \
19061918
<div ng-bind-html="person.email | highlight: $select.search"></div> \
@@ -2971,6 +2983,65 @@ describe('ui-select tests', function () {
29712983
triggerKeydown(searchInput, Key.Enter);
29722984
expect(el.scope().$select.activeIndex).toBe(2);
29732985
});
2986+
2987+
it('should not display the placeholder when tag is selected (by default)', function () {
2988+
var placeholderText = defaultPlaceholder;
2989+
2990+
var el = createUiSelectMultiple({
2991+
tagging: '',
2992+
taggingLabel: ''
2993+
});
2994+
2995+
var $select = el.scope().$select; // uiSelectCtrl
2996+
2997+
expect($select.selected).toEqual([]);
2998+
expect($select.getPlaceholder()).toEqual(placeholderText);
2999+
expect(getMatchPlaceholder(el)).toEqual(placeholderText); // get placeholder
3000+
3001+
clickItem(el, scope.people[0].name);
3002+
expect($select.selected).toEqual([scope.people[0]]);
3003+
expect(getMatchLabel(el)).toEqual(''); // empty text
3004+
expect(getMatchPlaceholder(el)).toEqual(''); // empty placeholder
3005+
3006+
clickItem(el, scope.people[1].name);
3007+
expect($select.selected).toEqual([scope.people[0], scope.people[1]]);
3008+
expect(getMatchLabel(el)).toEqual('');
3009+
expect(getMatchPlaceholder(el)).toEqual('');
3010+
});
3011+
3012+
// Could be needed when e.g. tag is shown below the input
3013+
it('should display the placeholder when tag is selected (if user overrides .getPlaceholder())', function () {
3014+
var placeholderText = defaultPlaceholder;
3015+
3016+
var el = createUiSelectMultiple({
3017+
tagging: '',
3018+
taggingLabel: ''
3019+
});
3020+
var $select = el.scope().$select;
3021+
3022+
/**
3023+
* In case user wants to show placeholder when the text is empty - they can override $select.getPlaceholder.
3024+
* Cannot do this with $selectMultiple, bc <ui-select-multiple is appended inside the library
3025+
* This override closes #1796
3026+
*/
3027+
$select.getPlaceholder = function() {
3028+
return $select.placeholder;
3029+
};
3030+
3031+
expect($select.selected).toEqual([]);
3032+
expect(getMatchLabel(el)).toEqual('');
3033+
expect(getMatchPlaceholder(el)).toEqual(placeholderText);
3034+
3035+
clickItem(el, scope.people[0].name);
3036+
expect($select.selected).toEqual([scope.people[0]]);
3037+
expect(getMatchLabel(el)).toEqual(''); // empty text
3038+
expect(getMatchPlaceholder(el)).toEqual(placeholderText); // show placeholder
3039+
3040+
clickItem(el, scope.people[1].name);
3041+
expect($select.selected).toEqual([scope.people[0], scope.people[1]]);
3042+
expect(getMatchLabel(el)).toEqual('');
3043+
expect(getMatchPlaceholder(el)).toEqual(placeholderText);
3044+
});
29743045
});
29753046

29763047
describe('resetSearchInput option multiple', function () {

0 commit comments

Comments
 (0)