ui-select
ui-select copied to clipboard
Open on focus
Hello,
I have a simple thing I want to do - when someone tabs over to my ui-select, I want it to drop down automatically. Unfortunately, the ng-focus doesn't seem to fire when the focus changes to the ui-select. Is there a workaround?
I'd like help on this too.
Currently, the behavior is different when you click into the form field vs. when you tab in.
I'd expect them to behave the same.
I'd like help on this too. please update here if you guys found the solution
Just what I was looking for as well. I am looking into it and will report back with what I find.
Any ideas? My issue is that the border or the select control gets focus when tabbed, but I'd rather the input get the focus. Any ideas?
:+1:
I tried the options suggested here :point_right: https://github.com/angular-ui/ui-select/issues/201 but I was not able to get the open-on-focus behavior
+1 absolutely agree with @NickChristensen, I also expect the behaviour to be the same.
:+1:
+1
+1
In 4 updates
For anyone interested in a temporary work around.
HTML:
<span tabindex="3" ng-focus="vm.setFocus(3)"></span>
<div>
<ui-select class="form-control input-lg focus-input-3" ng-model="vm.shippingAddress.postal_code" on-select="vm.selectLocation($item, 'SHIPPING')" name="zip" theme="select2" ng-disabled="!vm.isAddingNewShipAddress || vm.processing" reset-search-input="false">
<ui-select-match placeholder="ZIP Code">{{vm.shippingAddress.postal_code}}</ui-select-match>
<ui-select-choices repeat="address in vm.googlePlaces track by $index" refresh="vm.refreshAddresses($select.search, 'SHIPPING')" refresh-delay="0">
<div ng-bind-html="address.formatted_address | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
Controller:
this.setFocus = (tabIndexNumber) => {
var element = '.focus-input-' + tabIndexNumber +' a';
// Might have issues with $digest/$apply, this will ensure it goes on the next cycle
$timeout(() => {
angular.element(element).click();
});
};
This may/may not work on older browsers, but works well enough for what I need. The takeaway here is that you simply add a 'focus-input-tab_index_here' class onto to the ui-select you wish to focus/click on. The span has the tab index of the next input. Once it gets focus, it runs the function to select the anchor tag inside the ui-select. Luckily, once it's click, the input inside the ui-select will get the actual focus and be fairly seamless.
I tried using ui-select's 'focus-on' attribute in a similar way, but failed to get it just how I wanted it.
Here's a ~~cleaner~~ different temporary workaround than @kadowki's workaround (albiet pulling on the internal guts of ui-select a little):
// Use the ui-select-open-on-focus directive on the ui-select element
app.directive('uiSelectOpenOnFocus', ['$timeout', function($timeout){
return {
require: 'uiSelect',
restrict: 'A',
link: function($scope, el, attrs, uiSelect) {
var closing = false;
angular.element(uiSelect.focusser).on('focus', function() {
if(!closing) {
uiSelect.activate();
}
});
// Because ui-select immediately focuses the focusser after closing
// we need to not re-activate after closing
$scope.$on('uis:close', function() {
closing = true;
$timeout(function() { // I'm so sorry
closing = false;
});
});
}
};
}]);
+1 ^
+1
up
+1
+1
+1
+1
:+1:
Please don't post any more +1s - use the new GitHub reactions.
PRs welcome for implementing this.
@rahatarmanahmed That directive works perfect, ... but not in IE (at least tested in 11 and Edge). After you've selected an item, the dropdown just opens itself again (probably cause IE sets the focus again after select). Using the skip-focusser option of ui-select doesn't change this behaviour sadly.
edit Should've tried some stuff before posting, adding a delay to the timeout function does the trick. Last bit should look like this (tested in IE11 and Chrome, I guess Edge will work too):
$scope.$on('uis:close', function () {
closing = true;
$timeout(function () { // I'm so sorry
closing = false;
}, 250);
});
It looks like the code still may have a race condition possible where it gets in a bad state. If for any reason, the 'focus' event is handled before the 'uis:close' event, then this directive will not work. I made some modifications to the code that uses the 'uis:activate' event to also disable the autoopen. I also took some liberties with variable names since closing is no longer applicable.
For those who are interested, we have implemented this functionality into the Form.io JSON form renderer found here https://github.com/formio/ngFormio
// A directive to have ui-select open on focus
app.directive('uiSelectOpenOnFocus', ['$timeout', function($timeout) {
return {
require: 'uiSelect',
restrict: 'A',
link: function($scope, el, attrs, uiSelect) {
var autoopen = true;
angular.element(uiSelect.focusser).on('focus', function() {
if (autoopen) {
uiSelect.activate();
}
});
// Disable the auto open when this select element has been activated.
$scope.$on('uis:activate', function() {
autoopen = false;
});
// Re-enable the auto open after the select element has been closed
$scope.$on('uis:close', function() {
autoopen = false;
$timeout(function() {
autoopen = true;
}, 250);
});
}
};
}]);
not sure about the latest version, but for old one this solution doesn't work for multi selection, focusser is undefined in this case.
angular.element(uiSelect.focusser || uiSelect.focusInput).on('focus'...
works for me.
I am facing a similar issue #1827 Please see if someone can help
+1
+1
@Metrakit previously stated please do not +1 issues.
Using the solution posted by @travist works in latest Chrome and Edge; however, I cannot tab out of the field in Firefox.