Skip to content

Commit

Permalink
fix: hide the grid-pro editor component until updated (#6820) (#6842)
Browse files Browse the repository at this point in the history
Co-authored-by: Tomi Virkki <tomivirkki@users.noreply.github.com>
Co-authored-by: Sascha Ißbrücker <sissbruecker@vaadin.com>
  • Loading branch information
3 people authored Nov 22, 2024
1 parent de91c9e commit cb206a6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,61 @@ public void customComboBox_circularReferencesInData_isEdited() {
getPanelText("prop-panel"));
}

private String LOADING_EDITOR_ATTRIBUTE = "loading-editor";

@Test
public void customComboBox_loadingEditorStateOnEdit() {
var cell = grid.getCell(0, 4);

var hasLoadingStateOnEditStart = (Boolean) executeScript(
"""
const [cell, grid, attribute] = arguments;
// Enter edit mode with double click
cell.dispatchEvent(new CustomEvent('dblclick', {composed: true, bubbles: true}));
return grid.hasAttribute(attribute);
""",
cell, grid, LOADING_EDITOR_ATTRIBUTE);
// Expect the editor to be hidden when the edit starts
Assert.assertTrue(hasLoadingStateOnEditStart);

// After the round trip to the server...
var editor = cell.$("vaadin-combo-box").first();
// The editor should be visible
Assert.assertFalse(grid.hasAttribute(LOADING_EDITOR_ATTRIBUTE));
// The editor should have focus
Assert.assertTrue("Editor should have focus",
(Boolean) executeScript(
"return arguments[0].contains(document.activeElement)",
editor));
}

@Test
public void customComboBox_loadingEditorStateClearedOnEditStop() {
var cell = grid.getCell(0, 4);
var nonCustomEditorCell = grid.getCell(0, 1);

var hasLoadingStateAttribute = (Boolean) executeScript(
"""
const [cell, nonCustomEditorCell, grid, attribute] = arguments;
// Enter edit mode with double click
cell.dispatchEvent(new CustomEvent('dblclick', {composed: true, bubbles: true}));
await new Promise(resolve => requestAnimationFrame(resolve));
// Focus another cell
nonCustomEditorCell.focus();
await new Promise(resolve => requestAnimationFrame(resolve));
return grid.hasAttribute(attribute);
""",
cell, nonCustomEditorCell, grid, LOADING_EDITOR_ATTRIBUTE);

Assert.assertFalse(hasLoadingStateAttribute);
}

@Test
public void textEditorIsUsedForTextColumn() {
assertCellEnterEditModeOnDoubleClick(0, 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,12 @@ private void setup() {
if (column.getEditorType().equals("custom")) {
column.getEditorField()
.setValue(column.getValueProvider().apply(e.getItem()));
var itemKey = getDataCommunicator().getKeyMapper()
.key(e.getItem());
UI.getCurrent().getPage().executeJs(
"window.Vaadin.Flow.gridProConnector.selectAll($0)",
column.getEditorField().getElement());
"window.Vaadin.Flow.gridProConnector.selectAll($0, $1, $2)",
column.getEditorField().getElement(), itemKey,
this.getElement());
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@ function isEditedRow(grid, rowData) {
return grid.__edited && grid.__edited.model.item.key === rowData.item.key;
}

const LOADING_EDITOR_CELL_ATTRIBUTE = 'loading-editor';

window.Vaadin.Flow.gridProConnector = {
selectAll: (editor) => {
selectAll: (editor, itemKey, grid) => {
if (editor.__itemKey !== itemKey) {
// This is an outdated call that can occur if the user starts editing a cell,
// and quickly starts editing another cell on the same column before the editor
// is unhidden for the first cell.
return;
}

grid.toggleAttribute(LOADING_EDITOR_CELL_ATTRIBUTE, false);

if (editor instanceof HTMLInputElement) {
editor.select();
} else if (editor.focusElement && editor.focusElement instanceof HTMLInputElement) {
Expand All @@ -34,11 +45,20 @@ window.Vaadin.Flow.gridProConnector = {
root.appendChild(component);
this._grid._cancelStopEdit();
component.focus();

component.__itemKey = rowData.item.key;
this._grid.toggleAttribute(LOADING_EDITOR_CELL_ATTRIBUTE, true);
};

// Not needed in case of custom editor as value is set on server-side.
// Overridden in order to avoid blinking of the cell content.
column._setEditorValue = function (editor, value) {};

const stopCellEdit = column._stopCellEdit;
column._stopCellEdit = function () {
stopCellEdit.apply(this, arguments);
this._grid.toggleAttribute(LOADING_EDITOR_CELL_ATTRIBUTE, false);
};
},

patchEditModeRenderer(column) {
Expand Down

0 comments on commit cb206a6

Please sign in to comment.