ui-select icon indicating copy to clipboard operation
ui-select copied to clipboard

Open on focus

Open ghost opened this issue 11 years ago • 31 comments
trafficstars

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?

ghost avatar Nov 21 '14 00:11 ghost

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.

NickChristensen avatar Dec 01 '14 16:12 NickChristensen

I'd like help on this too. please update here if you guys found the solution

m2hconsulting avatar Dec 31 '14 17:12 m2hconsulting

Just what I was looking for as well. I am looking into it and will report back with what I find.

gwin003 avatar Jan 05 '15 19:01 gwin003

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?

hbostic avatar Jan 14 '15 08:01 hbostic

:+1:

brondavies avatar Jan 27 '15 21:01 brondavies

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

brondavies avatar Jan 27 '15 21:01 brondavies

+1 absolutely agree with @NickChristensen, I also expect the behaviour to be the same.

stefan-- avatar Jan 28 '15 09:01 stefan--

:+1:

elubin avatar Apr 22 '15 21:04 elubin

+1

yaring avatar Jul 05 '15 13:07 yaring

+1

kpociecha avatar Jul 07 '15 12:07 kpociecha

In 4 updates

lingqingmeng avatar Jul 14 '15 16:07 lingqingmeng

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.

daveboling avatar Aug 18 '15 21:08 daveboling

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;
        });
      });
    }
  };
}]);

rahatarmanahmed avatar Aug 31 '15 18:08 rahatarmanahmed

+1 ^

daveboling avatar Aug 31 '15 18:08 daveboling

+1

fcaballero avatar Sep 11 '15 10:09 fcaballero

up

denis-bondarenko avatar Sep 22 '15 14:09 denis-bondarenko

+1

ivan-brkic avatar Dec 01 '15 12:12 ivan-brkic

+1

jpattersonz avatar Dec 14 '15 14:12 jpattersonz

+1

syedsuhail avatar Dec 22 '15 07:12 syedsuhail

+1

IsmiKin avatar Feb 16 '16 13:02 IsmiKin

:+1:

tbandixen avatar Feb 24 '16 14:02 tbandixen

Please don't post any more +1s - use the new GitHub reactions.

PRs welcome for implementing this.

wesleycho avatar Mar 27 '16 15:03 wesleycho

@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);
            });

TimGeerts avatar Mar 31 '16 11:03 TimGeerts

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);
      });
    }
  };
}]);

travist avatar Apr 07 '16 03:04 travist

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.

popovevgeny avatar Oct 11 '16 15:10 popovevgeny

I am facing a similar issue #1827 Please see if someone can help

maniskasyap avatar Oct 13 '16 18:10 maniskasyap

+1

Metrakit avatar Nov 16 '16 09:11 Metrakit

+1

stratisbakas avatar Nov 16 '16 09:11 stratisbakas

@Metrakit previously stated please do not +1 issues.

user378230 avatar Nov 16 '16 10:11 user378230

Using the solution posted by @travist works in latest Chrome and Edge; however, I cannot tab out of the field in Firefox.

daerogami avatar Feb 05 '19 20:02 daerogami