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

Open on focus #428

Open
turbobuilt opened this issue Nov 21, 2014 · 31 comments
Open

Open on focus #428

turbobuilt opened this issue Nov 21, 2014 · 31 comments

Comments

@turbobuilt
Copy link

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?

@NickChristensen
Copy link

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.

@m2hconsulting
Copy link

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

@gwin003
Copy link

gwin003 commented Jan 5, 2015

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

@hbostic
Copy link

hbostic commented Jan 14, 2015

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?

@brondavies
Copy link

👍

@brondavies
Copy link

I tried the options suggested here 👉 #201 but I was not able to get the open-on-focus behavior

@stefan--
Copy link

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

@elubin
Copy link

elubin commented Apr 22, 2015

👍

2 similar comments
@yaring
Copy link

yaring commented Jul 5, 2015

+1

@kpociecha
Copy link

+1

@lingqingmeng
Copy link

In 4 updates

@daveboling
Copy link

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.

@rahatarmanahmed
Copy link

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

@daveboling
Copy link

+1 ^

@fcaballero
Copy link

+1

@denis-bondarenko
Copy link

up

@ivan-brkic
Copy link

+1

4 similar comments
@jpattersonz
Copy link

+1

@syedsuhail
Copy link

+1

@IsmiKin
Copy link

IsmiKin commented Feb 16, 2016

+1

@tbandixen
Copy link

👍

@wesleycho
Copy link
Contributor

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

PRs welcome for implementing this.

@TimGeerts
Copy link

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

@travist
Copy link

travist commented Apr 7, 2016

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

@popovevgeny
Copy link

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.

@maniskasyap
Copy link

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

@Metrakit
Copy link

+1

1 similar comment
@stratisbakas
Copy link

+1

@user378230
Copy link
Contributor

@Metrakit previously stated please do not +1 issues.

@daerogami
Copy link

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

@igler
Copy link

igler commented Apr 17, 2019

Same here. Tabbing out of Firefox does not work. Chrome is fine.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests