Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lookup: Close dropdown when clicking outside area #28041

Open
wants to merge 8 commits into
base: 24_2
Choose a base branch
from

Conversation

nikkithelegendarypokemonster
Copy link
Contributor

No description provided.

if (this.option('_scrollToSelectedItemEnabled')) this._popup._$arrow.remove();

this._setPopupContentId(this._popup.$content());

this._contentReadyHandler();
},

_popupFocusOutHandler($overlayContent) {
$overlayContent.get(0).addEventListener('focusout', (e) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, use eventsEngine syntax, not addEventListener.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than that, you may notice that the focus from the content has moved to the address bar, the popup has closed, but the dx-lookup element still has a focused state:

image

dropDownOptions: {
hideOnOutsideClick: false, // Ensures the dropdown does not close when clicking outside
},
opened: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
opened: true
opened: true,

const defaultOptions = {
items: ['1', '11', '111'],
value: '1',
dropDownOptions: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the scenario in which you install:

dropDownOptions: {
      hideOnOutsideClick: false,
},

you will see that Lookup doesn't close before your changes if you click outside of Lookup (see demo: https://codepen.io/marker-dao/pen/WNqWJrq??editors=1010), but with your changes it works differently - Lookup closes if you click outside of it.

this.option('focusStateEnabled') && this.focus();

if (this._isFocusOutTriggered) {
this.$element().removeClass('dx-state-focus');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[incorrect logic]
We should never manually remove/add this class, it toggles automatically on focusin/focusout.
And I don't understand the goal, now u say "when popup is closing remove focus from input element if popup was focused out"

@@ -780,6 +811,8 @@ const Lookup = DropDownList.inherit({
$searchWrapper.insertBefore(this._$list);

this._setSearchPlaceholder();
} else {
this._removeSearch();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[excess changes?]
For what? How search is related to closing popup on clicking outside of lookup?


const nextFocusableElement = $allFocusable.get(currentIndex + 1) as HTMLElement | undefined;
nextFocusableElement?.focus();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[code splitting]
This method "_toggleSearchClass" is designed for single class toggling, there should not be any other logic. Now u say "when we toggle search class we need to move focus to next focusable element or search field". Why?

const currentIndex = $allFocusable.index(activeElement);

const nextFocusableElement = $allFocusable.get(currentIndex + 1) as HTMLElement | undefined;
nextFocusableElement?.focus();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[excess code?]
I don't see a reason for this code with manual focus change. Our task is to close popup when focus goes out of component. Why do we need make all this additional stuff with focus?

JFYI for the future:

  • we cannot use document directly in our code, it should be done through domAdapter util
  • now your $allFocusable variable contains all focusable elements on a page. That's bad for performance. Focusing other element of page after tab key press is a browser behavior, we should not try do it our side

$(this.lookup._$field).trigger('dxclick');

assert.notOk(this.lookup.option('opened'), 'popup is hidden');
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[test coverage]
How it can be true to have single tests for 50+ changed code rows?

And I actually see that all target scenarios do now work at the moment: closing on outside click, moving focus out of component by pressing tab and by pressing shift+tab

QUnit.test('dropdown should close when focusout event happens outside component', function(assert) {
assert.ok(this.lookup.option('opened'), 'popup is shown');

$(this.lookup._$field).trigger('dxclick');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[not working test]
Closing lookup on its field clicking is controlled by other code. You can see that this scenario worked even before your changes

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

Successfully merging this pull request may close these issues.

3 participants