angular-ui / bootstrap

PLEASE READ THE PROJECT STATUS BELOW. Native AngularJS (Angular) directives for Bootstrap. Smaller footprint (20kB gzipped), no 3rd party JS dependencies (jQuery, bootstrap JS) required. Please read the README.md file before submitting an issue!
http://angular-ui.github.io/bootstrap/
MIT License
14.27k stars 6.73k forks source link

Arrow key listeners for dropdown not reset, causing dropdown to skip records #6314

Closed sxgrant closed 7 years ago

sxgrant commented 8 years ago

Bug description:

Dropdown (with keyboard-nav) does not remove key-listeners on $document if the user navigates directly between several dropdowns. This results in duplicate arrow-key listen events making the control skip x entries where x is the number of times the user has navigated between dropdowns.

This is especially problematic for users trying to use a form with multiple dropdowns with keyboard only, but if the issue still presents if the user clicks directly between dropdowns and then uses keys to select.

Link to minimally-working plunker that reproduces the issue:

Can be reproduced on the examples page; https://angular-ui.github.io/bootstrap/#/dropdown Steps:

  1. Click the keyboard-navigable dropdown
  2. Use the arrows and observe normal behaviour
  3. Without closing the dropdown, select another dropdown (e.g. "dropdown on body")
  4. Without closing the dropdown, return to the keyboard-navigable dropdown
  5. Arrow keys no longer work one-at-a-time

Version of Angular, UIBS, and Bootstrap

Angular: 1.5.8 UIBS: 2.2.0 Bootstrap: 3.3.7

(Chome: 54.0.2840.71)

I'm working around it at the moment by deliberately removing the keydown event on toggle, as below;

this.toggle = function(open) {
    scope.isOpen = arguments.length ? !!open : !scope.isOpen;
    if(scope.isOpen) {
      $document.off('keydown', this.keybindFilter);
    }
    if (angular.isFunction(setIsOpen)) {
      setIsOpen(scope, scope.isOpen);
    }
    return scope.isOpen;
  };
patricksmms commented 7 years ago

I was also looking for a solution for this issue.

patricksmms commented 7 years ago

The code fix is actually pretty simple, just adding to the file dropdown.js, line 275 this: $document.off('keydown', uibDropdownService.keybindFilter);