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

Commit f711ec2

Browse files
Andrei Varabeijrbotros
Andrei Varabei
authored andcommitted
fix(uiSelectMatch): set model value to null when cleared
Closes #863
1 parent 3f097e0 commit f711ec2

5 files changed

+58
-16
lines changed

src/common.js

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ var KEY = {
5454
}
5555
};
5656

57+
function isNil(value) {
58+
return angular.isUndefined(value) || value === null;
59+
}
60+
5761
/**
5862
* Add querySelectorAll() to jqLite.
5963
*

src/uiSelectController.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ uis.controller('uiSelectCtrl',
6262
}
6363

6464
ctrl.isEmpty = function() {
65-
return angular.isUndefined(ctrl.selected) || ctrl.selected === null || ctrl.selected === '' || (ctrl.multiple && ctrl.selected.length === 0);
65+
return isNil(ctrl.selected) || ctrl.selected === '' || (ctrl.multiple && ctrl.selected.length === 0);
6666
};
6767

6868
function _findIndex(collection, predicate, thisArg){
@@ -379,7 +379,7 @@ uis.controller('uiSelectCtrl',
379379

380380
// When the user selects an item with ENTER or clicks the dropdown
381381
ctrl.select = function(item, skipFocusser, $event) {
382-
if (item === undefined || !_isItemDisabled(item)) {
382+
if (isNil(item) || !_isItemDisabled(item)) {
383383

384384
if ( ! ctrl.items && ! ctrl.search && ! ctrl.tagging.isActivated) return;
385385

@@ -454,7 +454,7 @@ uis.controller('uiSelectCtrl',
454454
};
455455

456456
ctrl.clear = function($event) {
457-
ctrl.select(undefined);
457+
ctrl.select(null);
458458
$event.stopPropagation();
459459
$timeout(function() {
460460
ctrl.focusser[0].focus();

src/uiSelectMultipleDirective.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
162162
// Make sure that model value is array
163163
if(!angular.isArray(ngModel.$viewValue)){
164164
// Have tolerance for null or undefined values
165-
if(angular.isUndefined(ngModel.$viewValue) || ngModel.$viewValue === null){
165+
if (isNil(ngModel.$viewValue)){
166166
ngModel.$viewValue = [];
167167
} else {
168168
throw uiSelectMinErr('multiarr', "Expected model value to be array but got '{0}'", ngModel.$viewValue);
@@ -178,7 +178,7 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
178178
return;
179179
}
180180
$select.selected.push(item);
181-
var locals = {};
181+
var locals = {};
182182
locals[$select.parserResult.itemName] = item;
183183

184184
$timeout(function(){
@@ -261,11 +261,11 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
261261
} else {
262262
return curr;
263263
}
264-
264+
265265
} else {
266266
// If nothing yet selected, select last item
267-
return last;
268-
}
267+
return last;
268+
}
269269
break;
270270
case KEY.DELETE:
271271
// Remove selected item and select next item

src/uiSelectSingleDirective.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ uis.directive('uiSelectSingle', ['$timeout','$compile', function($timeout, $comp
99

1010
//From view --> model
1111
ngModel.$parsers.unshift(function (inputValue) {
12+
// Keep original value for undefined and null
13+
if (isNil(inputValue)) {
14+
return inputValue;
15+
}
16+
1217
var locals = {},
1318
result;
1419
locals[$select.parserResult.itemName] = inputValue;
@@ -18,6 +23,11 @@ uis.directive('uiSelectSingle', ['$timeout','$compile', function($timeout, $comp
1823

1924
//From model --> view
2025
ngModel.$formatters.unshift(function (inputValue) {
26+
// Keep original value for undefined and null
27+
if (isNil(inputValue)) {
28+
return inputValue;
29+
}
30+
2131
var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search
2232
locals = {},
2333
result;
@@ -51,13 +61,13 @@ uis.directive('uiSelectSingle', ['$timeout','$compile', function($timeout, $comp
5161

5262
scope.$on('uis:select', function (event, item) {
5363
$select.selected = item;
54-
var locals = {};
64+
var locals = {};
5565
locals[$select.parserResult.itemName] = item;
5666

57-
$timeout(function(){
67+
$timeout(function() {
5868
$select.onSelectCallback(scope, {
5969
$item: item,
60-
$model: $select.parserResult.modelMapper(scope, locals)
70+
$model: isNil(item) ? item : $select.parserResult.modelMapper(scope, locals)
6171
});
6272
});
6373
});

test/select.spec.js

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

18+
function isNil(value) {
19+
return angular.isUndefined(value) || value === null;
20+
}
21+
1822
//create a directive that wraps ui-select
1923
angular.module('wrapperDirective', ['ui.select']);
2024
angular.module('wrapperDirective').directive('wrapperUiSelect', function () {
@@ -49,8 +53,8 @@ describe('ui-select tests', function () {
4953
restrict: 'A',
5054
require: 'ngModel',
5155
link: function (scope, element, attrs, ngModel) {
52-
ngModel.$validators.testValidator = function (modelValue, viewValue) {
53-
if (angular.isUndefined(modelValue) || modelValue === null) {
56+
ngModel.$validators.testValidator = function(modelValue, viewValue) {
57+
if (isNil(modelValue)) {
5458
return true;
5559
} else if (angular.isArray(modelValue)) {
5660
var allValid = true, idx = modelValue.length;
@@ -611,11 +615,10 @@ describe('ui-select tests', function () {
611615

612616
// Trigger clear.
613617
el.find('.select2-search-choice-close').click();
614-
expect(scope.selection.selected).toEqual(undefined);
618+
expect(scope.selection.selected).toEqual(null);
615619

616-
// If there is no selection it the X icon should be gone.
620+
// If there is no selection the X icon should be gone.
617621
expect(el.find('.select2-search-choice-close').length).toEqual(0);
618-
619622
});
620623

621624
it('should toggle allow-clear directive', function () {
@@ -636,6 +639,31 @@ describe('ui-select tests', function () {
636639
expect(el.find('.select2-search-choice-close').length).toEqual(1);
637640
});
638641

642+
it('should clear selection (with object as source)', function() {
643+
var el = compileTemplate(
644+
'<ui-select ng-model="selection.selected" theme="select2"> \
645+
<ui-select-match placeholder="Pick one..." allow-clear="true">{{$select.selected.value.name}}</ui-select-match> \
646+
<ui-select-choices repeat="person.value.name as (key,person) in peopleObj | filter: $select.search"> \
647+
<div ng-bind-html="person.value.name | highlight: $select.search"></div> \
648+
<div ng-bind-html="person.value.email | highlight: $select.search"></div> \
649+
</ui-select-choices> \
650+
</ui-select>'
651+
);
652+
var $select = el.scope().$select;
653+
654+
clickItem(el, 'Samantha');
655+
expect(scope.selection.selected).toEqual('Samantha');
656+
657+
// allowClear should be true.
658+
expect($select.allowClear).toEqual(true);
659+
660+
// Trigger clear.
661+
el.find('.select2-search-choice-close').click();
662+
expect(scope.selection.selected).toEqual(null);
663+
664+
// If there is no selection the X icon should be gone.
665+
expect(el.find('.select2-search-choice-close').length).toEqual(0);
666+
});
639667

640668
it('should pass tabindex to focusser', function () {
641669
var el = createUiSelect({tabindex: 5});

0 commit comments

Comments
 (0)