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

DataTable: Autocomplete with Dialog on cell editing is not working #6569

Open
didix16 opened this issue May 4, 2024 · 4 comments
Open

DataTable: Autocomplete with Dialog on cell editing is not working #6569

didix16 opened this issue May 4, 2024 · 4 comments
Labels
Type: Bug Issue contains a defect related to a specific component.

Comments

@didix16
Copy link
Contributor

didix16 commented May 4, 2024

Describe the bug

Hello everyone,

Firstly, let me explain what I'm trying to achieve: I have a DataTable with a column from which you can choose a list of objects (for example, Agents) that have the properties id and name. This list is displayed with an Autocomplete cell editor. I've added functionality to this Autocomplete so that if the current value doesn't match the name of one of the objects in the list, it displays a Dialog with an error message. This forces the Autocomplete to remain focused until a correct value is entered or the Autocomplete is empty (null). To accomplish this, I handle both onBlur and onHide events, etc. You can see the implementation of the component in the EntityAutoComplete.tsx file in the provided reproducer.

The component works correctly if it's not within a BodyCell. The issue arises when you edit a cell. Given this code snippet:

const [bindDocumentClickListener, unbindDocumentClickListener] = useEventListener({
type: 'click',
listener: (e) => {
if (!selfClick.current && isOutsideClicked(e.target)) {
// #2666 for overlay components and outside is clicked
setTimeout(() => {
switchCellToViewMode(e, true);
}, 0);
}
selfClick.current = false;
},
options: true,
when: isEditable()
});

When you click outside the cell, the document's listener is triggered, causing the table cell to return to view mode. Additionally, the parameter options: true is instructing the document's addEventListener method to enable useCapture. As a result, it executes before any EventTarget and renders attempts to stop propagation to the document ineffective. This potentially prevents the cell from remaining in edit mode. It might be interesting to define options as false and have control over choosing to cancel the event, so that it doesn't reach the document and the cell doesn't return to view mode.

Furthermore, I've noticed that in version 10.6.3, the autoFocus in the button added in the Dialog's footer worked. Now, in version 10.6.4, the focus always seems to be on the Dialog's close button and the autoFocus of the button in the footer is ignored.

I have also observed that if I add the appendTo="self" property (line 188 in the EntityAutoComplete.tsx file) to the Dialog, since the Dialog is within the cell in this case, clicking the Accept button or the close button correctly returns focus to autocomplete and displays the suggested list. However, other cases still don't work, such as pressing Escape or pressing Enter focusing on the Accept button or the close button.

One last observation: if I don't add the appendTo="self" property to the Dialog, pressing Enter with focus on the Accept button or the close button triggers the onCellEditComplete callback twice in succession, once with the KeyDown event and the other with the PointerEvent:

image

If I add the property, only the KeyDown event is triggered.
image

I understand the PointerEvent case, as the 'click' listener of the document is being executed, but I don't understand the KeyDown event case, since the Dialog, instead of being added inside the cell, is added inside the body via a Portal. It's only inside the cell if I add the appendTo="self" property to the Dialog.

In any case, it should remain in cell edit mode until autocomplete has a valid value. Moreover, I should be able to force focus on autocomplete when I close the Dialog, as well as when focus is lost and there isn't a valid value (when you click outside the cell and the click is in a different place than the Dialog). I have added an example of the component outside the BodyCell in the reproduction, with instructions to understand how the component works and what is expected of it in the BodyCell.

Note: A cell validator could be used in these cases. However, as the validator only executes if submit === false and submit is true for the cases where the component fails, nothing can be done. This is shown in the following code:

const switchCellToViewMode = (event, submit) => {
const callbackParams = getCellCallbackParams(event);
setEditingRowDataState((prev) => {
const newRowData = prev;
const newValue = resolveFieldData(newRowData);
const params = { ...callbackParams, newRowData, newValue };
const onCellEditCancel = getColumnProp('onCellEditCancel');
const cellEditValidator = getColumnProp('cellEditValidator');
const onCellEditComplete = getColumnProp('onCellEditComplete');
if (!submit && onCellEditCancel) {
onCellEditCancel(params);
}
let valid = true;
if (!submit && cellEditValidator) {
valid = cellEditValidator(params);
}
if (valid) {
if (submit && onCellEditComplete) {
setTimeout(() => onCellEditComplete(params));
}
closeCell(event);
} else {
event.preventDefault();
}
return newRowData;
});
};

Reproducer

https://stackblitz.com/edit/vitejs-vite-bhs8g3?file=src%2Fmain.tsx,src%2Fcomponents%2FEntityAutoComplete.tsx,src%2FExample.tsx

PrimeReact version

10.6.4

React version

18.x

Language

TypeScript

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

  1. Open the reproducer.
  2. Experience the behavior of the component outside the BodyCell.
  3. Try to experience the same behavior inside the BodyCell.
  4. Select a cell in the Agent column.
  5. Type any text that does not start with "a" or "u". Press Enter or Tab.
  6. The Dialog appears.
  7. Close the Dialog. The cell has returned to view mode, when it should remain in edit mode and display the autocomplete suggestion list.
  8. Repeat step 4.
  9. Type anything in autocomplete. Click outside the cell. The cell returns to edit mode. The Dialog does not appear (if you type something that triggers the suggestion list to appear, the Dialog briefly appears when clicking outside, but it disappears quickly).

Expected behavior

As mentioned in the bug description, the expected behavior should be for the cell to remain in edit mode until the autocomplete has a valid value, and I should be able to force focus on the autocomplete in the following cases: when closing the Dialog and when losing focus without having a valid value (clicking outside the cell where the click is in a different place than the Dialog). There is an example of the component outside the BodyCell in the reproducer with instructions to see how the component works and what is expected of it in the BodyCell.

@didix16 didix16 added the Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible label May 4, 2024
@melloware
Copy link
Member

@didix16 yes cell editing as you have seen is quite complex, but PR's are welcome. Probably also needs showcase example in the Cell Edit example of using an AutoComplete or some other popup panel type component...

@melloware melloware added Type: Bug Issue contains a defect related to a specific component. and removed Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible labels May 4, 2024
@didix16
Copy link
Contributor Author

didix16 commented May 5, 2024

Yeah, there should be a new Cell Edit example with autocomplete and Dialog, for example.
For now, I'm gonna try to make the onClick event cancelable so a user can controll if want avoid that a cell returns to view mode while is editing. I'll try to make a PR

@melloware
Copy link
Member

That would be great!

@didix16
Copy link
Contributor Author

didix16 commented May 11, 2024

Hey @melloware, it took me a few days to investigate the source code and do some testing but finally I got something that works!

This is the PR #6611

It just add new capabilities to Dialog and Column. By default are desactivated (false value) so it ensures does not break any implementations. I also updated the api documentation.

Hope you can accept the changes and merge them to next release.

Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Issue contains a defect related to a specific component.
Projects
None yet
Development

No branches or pull requests

2 participants