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

Commit f0190de

Browse files
committed
Merge pull request #362 from TravisTX/feat-closeOnSelect
Added closeOnSelect attribute
2 parents 6849d9a + ff227e2 commit f0190de

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

examples/demo-multi-select.html

+5-5
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ <h3>Multi select</h3>
113113
<h1>Multi Selection Demos</h1>
114114

115115
<h3>Array of strings</h3>
116-
<ui-select multiple ng-model="multipleDemo.colors" theme="bootstrap" ng-disabled="disabled" style="width: 300px;">
116+
<ui-select multiple ng-model="multipleDemo.colors" theme="bootstrap" ng-disabled="disabled" close-on-select="false" style="width: 300px;">
117117
<ui-select-match placeholder="Select colors...">{{$item}}</ui-select-match>
118118
<ui-select-choices repeat="color in availableColors | filter:$select.search">
119119
{{color}}
@@ -122,7 +122,7 @@ <h3>Array of strings</h3>
122122
<p>Selected: {{multipleDemo.colors}}</p>
123123
<hr>
124124
<h3>Array of objects</h3>
125-
<ui-select multiple ng-model="multipleDemo.selectedPeople" theme="bootstrap" ng-disabled="disabled" style="width: 800px;">
125+
<ui-select multiple ng-model="multipleDemo.selectedPeople" theme="bootstrap" ng-disabled="disabled" close-on-select="false" style="width: 800px;">
126126
<ui-select-match placeholder="Select person...">{{$item.name}} &lt;{{$item.email}}&gt;</ui-select-match>
127127
<ui-select-choices repeat="person in people | propsFilter: {name: $select.search, age: $select.search}">
128128
<div ng-bind-html="person.name | highlight: $select.search"></div>
@@ -136,7 +136,7 @@ <h3>Array of objects</h3>
136136

137137
<hr>
138138
<h3>Deselect callback with single property binding</h3>
139-
<ui-select multiple ng-model="multipleDemo.deSelectedPeople" on-remove="removed($item, $model)" theme="bootstrap" ng-disabled="disabled" style="width: 800px;">
139+
<ui-select multiple ng-model="multipleDemo.deSelectedPeople" on-remove="removed($item, $model)" theme="bootstrap" ng-disabled="disabled" close-on-select="false" style="width: 800px;">
140140
<ui-select-match placeholder="Select person...">{{$item.name}} &lt;{{$item.email}}&gt;</ui-select-match>
141141
<ui-select-choices repeat="person.email as person in people | propsFilter: {name: $select.search, age: $select.search}">
142142
<div ng-bind-html="person.name | highlight: $select.search"></div>
@@ -151,7 +151,7 @@ <h3>Deselect callback with single property binding</h3>
151151

152152
<hr>
153153
<h3>Array of objects with single property binding</h3>
154-
<ui-select multiple ng-model="multipleDemo.selectedPeopleSimple" theme="bootstrap" ng-disabled="disabled" style="width: 800px;">
154+
<ui-select multiple ng-model="multipleDemo.selectedPeopleSimple" theme="bootstrap" ng-disabled="disabled" close-on-select="false" style="width: 800px;">
155155
<ui-select-match placeholder="Select person...">{{$item.name}} &lt;{{$item.email}}&gt;</ui-select-match>
156156
<ui-select-choices repeat="person.email as person in people | propsFilter: {name: $select.search, age: $select.search}">
157157
<div ng-bind-html="person.name | highlight: $select.search"></div>
@@ -165,7 +165,7 @@ <h3>Array of objects with single property binding</h3>
165165

166166
<hr>
167167
<h3>Array of objects (with groupBy)</h3>
168-
<ui-select multiple ng-model="multipleDemo.selectedPeopleWithGroupBy" theme="bootstrap" ng-disabled="disabled" style="width: 800px;">
168+
<ui-select multiple ng-model="multipleDemo.selectedPeopleWithGroupBy" theme="bootstrap" ng-disabled="disabled" close-on-select="false" style="width: 800px;">
169169
<ui-select-match placeholder="Select person...">{{$item.name}} &lt;{{$item.email}}&gt;</ui-select-match>
170170
<ui-select-choices group-by="someGroupFn" repeat="person in people | propsFilter: {name: $select.search, age: $select.search}">
171171
<div ng-bind-html="person.name | highlight: $select.search"></div>

src/select.js

+16-8
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@
6767
theme: 'bootstrap',
6868
searchEnabled: true,
6969
placeholder: '', // Empty by default, like HTML tag <select>
70-
refreshDelay: 1000 // In milliseconds
70+
refreshDelay: 1000, // In milliseconds
71+
closeOnSelect: true
7172
})
7273

7374
// See Rename minErr and make it accessible from outside https://github.com/angular/angular.js/issues/6913
@@ -160,6 +161,8 @@
160161
ctrl.multiple = false; // Initialized inside uiSelect directive link function
161162
ctrl.disableChoiceExpression = undefined; // Initialized inside uiSelect directive link function
162163
ctrl.lockChoiceExpression = undefined; // Initialized inside uiSelect directive link function
164+
ctrl.closeOnSelect = true; // Initialized inside uiSelect directive link function
165+
ctrl.clickTriggeredSelect = false;
163166

164167
ctrl.isEmpty = function() {
165168
return angular.isUndefined(ctrl.selected) || ctrl.selected === null || ctrl.selected === '';
@@ -332,8 +335,7 @@
332335
};
333336

334337
// When the user clicks on an item inside the dropdown
335-
ctrl.select = function(item, skipFocusser) {
336-
338+
ctrl.select = function(item, skipFocusser, $event) {
337339
if (item === undefined || !item._uiSelectChoiceDisabled) {
338340
var locals = {};
339341
locals[ctrl.parserResult.itemName] = item;
@@ -343,13 +345,18 @@
343345
$model: ctrl.parserResult.modelMapper($scope, locals)
344346
});
345347

346-
if(ctrl.multiple){
348+
if(ctrl.multiple) {
347349
ctrl.selected.push(item);
348350
ctrl.sizeSearchInput();
349351
} else {
350352
ctrl.selected = item;
351353
}
352-
ctrl.close(skipFocusser);
354+
if (!ctrl.multiple || ctrl.closeOnSelect) {
355+
ctrl.close(skipFocusser);
356+
}
357+
if ($event && $event.type === 'click') {
358+
ctrl.clickTriggeredSelect = true;
359+
}
353360
}
354361
};
355362

@@ -624,7 +631,7 @@
624631
var searchInput = element.querySelectorAll('input.ui-select-search');
625632

626633
$select.multiple = (angular.isDefined(attrs.multiple)) ? (attrs.multiple === '') ? true : (attrs.multiple.toLowerCase() === 'true') : false;
627-
634+
$select.closeOnSelect = (angular.isDefined(attrs.closeOnSelect) && attrs.closeOnSelect.toLowerCase() === 'false') ? false : uiSelectConfig.closeOnSelect;
628635
$select.onSelectCallback = $parse(attrs.onSelect);
629636
$select.onRemoveCallback = $parse(attrs.onRemove);
630637

@@ -827,10 +834,11 @@
827834
contains = element[0].contains(e.target);
828835
}
829836

830-
if (!contains) {
837+
if (!contains && !$select.clickTriggeredSelect) {
831838
$select.close();
832839
scope.$digest();
833840
}
841+
$select.clickTriggeredSelect = false;
834842
}
835843

836844
// See Click everywhere but here event http://stackoverflow.com/questions/12931369
@@ -910,7 +918,7 @@
910918
choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp))
911919
.attr('ng-if', '$select.open') //Prevent unnecessary watches when dropdown is closed
912920
.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')')
913-
.attr('ng-click', '$select.select(' + $select.parserResult.itemName + ')');
921+
.attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)');
914922

915923
var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner');
916924
if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length);

test/select.spec.js

+17
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,7 @@ describe('ui-select tests', function() {
10431043
if (attrs.disabled !== undefined) { attrsHtml += ' ng-disabled="' + attrs.disabled + '"'; }
10441044
if (attrs.required !== undefined) { attrsHtml += ' ng-required="' + attrs.required + '"'; }
10451045
if (attrs.tabindex !== undefined) { attrsHtml += ' tabindex="' + attrs.tabindex + '"'; }
1046+
if (attrs.closeOnSelect !== undefined) { attrsHtml += ' close-on-select="' + attrs.closeOnSelect + '"'; }
10461047
}
10471048

10481049
return compileTemplate(
@@ -1278,6 +1279,22 @@ describe('ui-select tests', function() {
12781279

12791280
});
12801281

1282+
it('should not close dropdown after selecting if closeOnSelect=false', function() {
1283+
1284+
scope.selection.selectedMultiple = [scope.people[5]]; //Samantha
1285+
var el = createUiSelectMultiple({closeOnSelect: false});
1286+
var searchInput = el.find('.ui-select-search');
1287+
1288+
expect(isDropdownOpened(el)).toEqual(false);
1289+
triggerKeydown(searchInput, Key.Down)
1290+
expect(isDropdownOpened(el)).toEqual(true);
1291+
1292+
clickItem(el, 'Wladimir');
1293+
1294+
expect(isDropdownOpened(el)).toEqual(true);
1295+
1296+
});
1297+
12811298
it('should closes dropdown when pressing ESC key from search input', function() {
12821299

12831300
scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; //Wladimir, Samantha & Nicole

0 commit comments

Comments
 (0)