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

Commit 302e80f

Browse files
committed
feat: provide a way to skip the focusser
There was no easy way to configure if the focusser should be skipped after selecting an item. The fact that the focusser is always focused after selecting an item is especially problematic on mobile devices, since this leads to the keyboard being shown, which might not be desirable. This commit provides the skip-focusser option to configure this behavior on the ui-select directive. Fixes #869, #401, #818, #603, #432 (partially)
1 parent abf16f9 commit 302e80f

File tree

4 files changed

+19
-8
lines changed

4 files changed

+19
-8
lines changed

Diff for: src/common.js

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ var uis = angular.module('ui.select', [])
9999
placeholder: '', // Empty by default, like HTML tag <select>
100100
refreshDelay: 1000, // In milliseconds
101101
closeOnSelect: true,
102+
skipFocusser: false,
102103
dropdownPosition: 'auto',
103104
generateId: function() {
104105
return latestId++;

Diff for: src/uiSelectChoicesDirective.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ uis.directive('uiSelectChoices',
4848
.attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed
4949
if ($window.document.addEventListener) { //crude way to exclude IE8, specifically, which also cannot capture events
5050
choices.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')')
51-
.attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)');
51+
.attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',$select.skipFocusser,$event)');
5252
}
5353

5454
var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner');
5555
if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length);
5656
rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat
5757
if (!$window.document.addEventListener) { //crude way to target IE8, specifically, which also cannot capture events - so event bindings must be here
5858
rowsInner.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')')
59-
.attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)');
59+
.attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',$select.skipFocusser,$event)');
6060
}
6161

6262
$compile(element, transcludeFn)(scope); //Passing current transcludeFn to be able to append elements correctly from uisTranscludeAppend

Diff for: src/uiSelectController.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ uis.controller('uiSelectCtrl',
2020

2121
ctrl.removeSelected = false; //If selected item(s) should be removed from dropdown list
2222
ctrl.closeOnSelect = true; //Initialized inside uiSelect directive link function
23+
ctrl.skipFocusser = false; //Set to true to avoid returning focus to ctrl when item is selected
2324
ctrl.search = EMPTY_SEARCH;
2425

2526
ctrl.activeIndex = 0; //Dropdown of choices
@@ -476,7 +477,7 @@ uis.controller('uiSelectCtrl',
476477
break;
477478
case KEY.ENTER:
478479
if(ctrl.open && (ctrl.tagging.isActivated || ctrl.activeIndex >= 0)){
479-
ctrl.select(ctrl.items[ctrl.activeIndex]); // Make sure at least one dropdown item is highlighted before adding if not in tagging mode
480+
ctrl.select(ctrl.items[ctrl.activeIndex], ctrl.skipFocusser); // Make sure at least one dropdown item is highlighted before adding if not in tagging mode
480481
} else {
481482
ctrl.activate(false, true); //In case its the search input in 'multiple' mode
482483
}

Diff for: src/uiSelectDirective.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ uis.directive('uiSelect',
5252
}
5353
}();
5454

55+
scope.$watch('skipFocusser', function() {
56+
var skipFocusser = scope.$eval(attrs.skipFocusser);
57+
$select.skipFocusser = skipFocusser !== undefined ? skipFocusser : uiSelectConfig.skipFocusser;
58+
});
59+
5560
$select.onSelectCallback = $parse(attrs.onSelect);
5661
$select.onRemoveCallback = $parse(attrs.onRemove);
5762

@@ -162,11 +167,15 @@ uis.directive('uiSelect',
162167
}
163168

164169
if (!contains && !$select.clickTriggeredSelect) {
165-
//Will lose focus only with certain targets
166-
var focusableControls = ['input','button','textarea','select'];
167-
var targetController = angular.element(e.target).controller('uiSelect'); //To check if target is other ui-select
168-
var skipFocusser = targetController && targetController !== $select; //To check if target is other ui-select
169-
if (!skipFocusser) skipFocusser = ~focusableControls.indexOf(e.target.tagName.toLowerCase()); //Check if target is input, button or textarea
170+
if (!$select.skipFocusser) {
171+
//Will lose focus only with certain targets
172+
var focusableControls = ['input','button','textarea','select'];
173+
var targetController = angular.element(e.target).controller('uiSelect'); //To check if target is other ui-select
174+
var skipFocusser = targetController && targetController !== $select; //To check if target is other ui-select
175+
if (!skipFocusser) skipFocusser = ~focusableControls.indexOf(e.target.tagName.toLowerCase()); //Check if target is input, button or textarea
176+
} else {
177+
skipFocusser = true;
178+
}
170179
$select.close(skipFocusser);
171180
scope.$digest();
172181
}

0 commit comments

Comments
 (0)