Skip to content

Commit 3b36b0a

Browse files
committed
fix($selectMultiple): allow user to override getPlaceholder() Behavior
User can provide their custom `getPlaceholder()` function. E.g. to keep placeholder activated in multipleSelect component, you can use this one: ``` angular.module('myApp').directive('myAppUiSelectPlaceholderAlwaysVisible', function() { return { require: 'uiSelect', link: function($scope, $element, attrs, $select) { $select.getPlaceholder = function () { return $select.placeholder; } } } }); ``` And then add this directive to the `<ui-select>` html element closes angular-ui#1796
1 parent d62cac2 commit 3b36b0a

6 files changed

+76
-10
lines changed

src/bootstrap/select-multiple.tpl.html

+1-1
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

+1-1
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

+2-2
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

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

68+
ctrl.getPlaceholder = function(){
69+
//Refactor single?
70+
if(ctrl.selected && ctrl.selected.length) return;
71+
return ctrl.placeholder;
72+
};
73+
6874
function _findIndex(collection, predicate, thisArg){
6975
if (collection.findIndex){
7076
return collection.findIndex(predicate, thisArg);

src/uiSelectMultipleDirective.js

-6
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

+66
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ describe('ui-select tests', function () {
1515
Escape: 27
1616
};
1717

18+
var multipleTagsTmpl =
19+
'<ui-select multiple tagging tagging-label="" ng-model="selection.selected"> \
20+
<ui-select-match ng-attr-placeholder="{{::placeholderText}}">{{$select.selected}}</ui-select-match> \
21+
<ui-select-choices repeat="item in items | filter: $select.search"> \
22+
<div ng-bind-html="item | highlight: $select.search"></div> \
23+
</ui-select-choices> \
24+
</ui-select>';
25+
1826
function isNil(value) {
1927
return angular.isUndefined(value) || value === null;
2028
}
@@ -191,6 +199,10 @@ describe('ui-select tests', function () {
191199
return $(el).find('.ui-select-match > span:first > span[ng-transclude]:not(.ng-hide)').text();
192200
}
193201

202+
function getMatchPlaceholder(el) {
203+
return el.find('.ui-select-search').attr('placeholder')
204+
}
205+
194206
function clickItem(el, text) {
195207

196208
if (!isDropdownOpened(el)) {
@@ -721,6 +733,60 @@ describe('ui-select tests', function () {
721733
expect(getMatchLabel(el)).toEqual('false');
722734
});
723735

736+
it('should not display the placeholder when tag is selected (by default)', function () {
737+
scope.items = ['tag1', 'tag2', 'tag3'];
738+
scope.placeholderText = 'placeholder text';
739+
740+
var el = compileTemplate(multipleTagsTmpl);
741+
var $select = el.scope().$select; // uiSelectCtrl
742+
743+
expect($select.selected).toEqual([]);
744+
expect($select.getPlaceholder()).toEqual(scope.placeholderText);
745+
expect(getMatchPlaceholder(el)).toEqual(scope.placeholderText); // get placeholder
746+
747+
clickItem(el, 'tag1');
748+
expect($select.selected).toEqual(['tag1']);
749+
expect(getMatchLabel(el)).toEqual(''); // empty text
750+
expect(getMatchPlaceholder(el)).toEqual(''); // empty placeholder
751+
752+
clickItem(el, 'tag2');
753+
expect($select.selected).toEqual(['tag1', 'tag2']);
754+
expect(getMatchLabel(el)).toEqual('');
755+
expect(getMatchPlaceholder(el)).toEqual('');
756+
});
757+
758+
// Could be needed when e.g. tag is shown below the input
759+
it('should display the placeholder when tag is selected (if user overrides .getPlaceholder())', function () {
760+
scope.items = ['tag1', 'tag2', 'tag3'];
761+
scope.placeholderText = 'placeholder text';
762+
763+
var el = compileTemplate(multipleTagsTmpl);
764+
var $select = el.scope().$select;
765+
766+
/**
767+
* In case user wants to show placeholder when the text is empty - they can override $select.getPlaceholder.
768+
* Cannot do this with $selectMultiple, bc <ui-select-multiple is appended inside the library
769+
* This override closes #1796
770+
*/
771+
$select.getPlaceholder = function() {
772+
return $select.placeholder;
773+
};
774+
775+
expect($select.selected).toEqual([]);
776+
expect(getMatchLabel(el)).toEqual('');
777+
expect(getMatchPlaceholder(el)).toEqual(scope.placeholderText);
778+
779+
clickItem(el, 'tag1');
780+
expect($select.selected).toEqual(['tag1']);
781+
expect(getMatchLabel(el)).toEqual(''); // empty text
782+
expect(getMatchPlaceholder(el)).toEqual(scope.placeholderText); // show placeholder
783+
784+
clickItem(el, 'tag2');
785+
expect($select.selected).toEqual(['tag1', 'tag2']);
786+
expect(getMatchLabel(el)).toEqual('');
787+
expect(getMatchPlaceholder(el)).toEqual(scope.placeholderText);
788+
});
789+
724790
it('should close an opened select when another one is opened', function () {
725791
var el1 = createUiSelect();
726792
var el2 = createUiSelect();

0 commit comments

Comments
 (0)