-
Notifications
You must be signed in to change notification settings - Fork 156
fix(editing): re-trigger activation clear on endedit #14842 #14894
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
Conversation
// simulate the process of focusing out of the cell so that the active element is cleared | ||
// while this should naturally happen when clicking a button (as a most likely endEdit called) | ||
// the intentional focusout ignore during edit mode prevents the expected behavior | ||
this.onFocusOut({ target: this.tbody.nativeElement } as unknown as FocusEvent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh, I think it might be a bit too risky to assume all calls to this API are coming when the Grid is focused out and clear selection.
Actually, there's a case for the opposite that currently has an issue. See Row Edit sample in dev demos, check Custom Template (it should have been using endEdit()
as exposed by the template context, but I digress). Point being the buttons on the row edit overlay are intended to call into endEdit
but loose focus breaking KB nav. Compare w/ what the default template use - the internal endRowEditTabStop
that checks for active node and returns focus to the grid tbody. Note that check is also silly and fails if the last active node is header, etc.
My thinking is for this method to handle both cases correctly, it should probably check the focused state of the grid before restoring focus or clearing active cell. Something in the lines of:
const activeNode = this.navigation.activeNode;
const document = this.nativeElement?.getRootNode() as Document | ShadowRoot;
if (!activeNode) {
return success;
}
if (this.nativeElement?.contains(document.activeElement) && activeNode.row !== -1) {
// restore focus for navigation, TODO: navigation method to handle all cases...
this.tbody.nativeElement.focus();
} else {
// grid already lost focus, clear active
this.navigation.lastActiveNode = activeNode;
this.navigation.activeNode = {} as IActiveNode;
this.notifyChanges();
}
This else can be refactored to be shared with the onFocusOut handler, but I see no reason for the additional checks - if the grid lost focus prior to end edit, might as well cleanup the active node that editing was blocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, okay, so the logic to restore the correct focus is actually baked into the focus out checks :)
if (activeNode.row >= 0 && activeNode.row < this.dataView.length) this.tbody.nativeElement.focus()
if (activeNode.row === -1) this.theadRow.nativeElement.focus();
if (activeNode.row === this.dataView.length) this.tfoot.nativeElement.focus();
eh 😶
this.inputDirective.focus(); | ||
// this avoids the grid receiving a focus out because the overlay is removed in the same execution | ||
// chain causing the browser to focus the body element first | ||
setTimeout(() => this.inputDirective.focus()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kinda sus. The grid receives multiple focus out events, most of which are from in-between focus shifting to the document body. Pretty much every cell click does that and that's why the checks on the handler are so strict about what we want to handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, the cell click traced down to IgxCellCrudState.updateCell
:
igniteui-angular/projects/igniteui-angular/src/lib/grids/common/crud.service.ts
Lines 259 to 263 in d6e7b0e
if (cellNode) { | |
const document = cellNode.getRootNode() as Document | ShadowRoot; | |
activeElement = document.activeElement as HTMLElement; | |
activeElement.blur(); | |
} |
That blur will force the focus to jump temporarily outside the grid and return, tricking the app scenario usage. This IIRC can be considered a minor bug on the Grid side and it might be better if we avoid blanket blur in general. If replaced with this.grid.tbody.nativeElement.focus()
instead it should work fine, though the fix for #14020 should be re-validated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for the Date Picker - that's another component issue. The entire KB nav of the date picker is broken:
https://www.infragistics.com/products/ignite-ui-angular/angular/components/date-picker#angular-datepicker-example Pick a value, focus does not return to the input.
Edit: Seems to be to do with the calendar stealing back focus after this handler has moved to the input, which causes the closing overlay to dump the focus to body when it's removed from the DOM. If that worked correctly, the focus should switch between the input & calendar - both within the grid container.
Yup, this seems to hit after the calendar has emitted change (also on mouse down for some reason, inner day item) and the picker has started closing and moved focus away:
igniteui-angular/projects/igniteui-angular/src/lib/calendar/calendar.component.ts
Lines 442 to 445 in d6e7b0e
protected onMouseDown(event: MouseEvent) { | |
event.stopPropagation(); | |
this.wrapper.nativeElement.focus(); | |
} |
Guessing some refactoring happened that changed the internal focus handling of the calendar in a way that didn't occur before and regressed the picker handling.
The goal is to blur the internal cell editor to cause a `change` and process the value, but should not use `blur()` directly as it throws focus on doc body, rather move the focus elsewhere in the grid and only if it already was there.
1c0d4a3
to
835fce9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And we should still add a test for the additional functionality of endEdit
- part of it is covered by the usage in the row edit templates that restores focus, but specifically calling after blur still isn't covered
Closes #14842 #14733
Additional information (check all that apply):
Checklist:
feature/README.MD
updates for the feature docsREADME.MD
CHANGELOG.MD
updates for newly added functionalityng update
migrations for the breaking changes (migrations guidelines)