Skip to content

Commit

Permalink
fix: wait for editor focusout on Tab to get updated value (#7822)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed Sep 24, 2024
1 parent 027c42d commit b0673cc
Show file tree
Hide file tree
Showing 6 changed files with 334 additions and 159 deletions.
137 changes: 137 additions & 0 deletions integration/tests/grid-pro-custom-editor.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { expect } from '@esm-bundle/chai';
import { fixtureSync, nextRender } from '@vaadin/testing-helpers';
import { sendKeys } from '@web/test-runner-commands';
import '@vaadin/combo-box';
import '@vaadin/date-picker';
import '@vaadin/grid-pro';
import '@vaadin/grid-pro/vaadin-grid-pro-edit-column.js';
import '@vaadin/time-picker';
import { flushGrid, getContainerCell } from '@vaadin/grid-pro/test/helpers.js';

describe('grid-pro custom editor', () => {
let grid;

beforeEach(async () => {
grid = fixtureSync(`
<vaadin-grid-pro>
<vaadin-grid-pro-edit-column path="firstName"></vaadin-grid-pro-edit-column>
<vaadin-grid-pro-edit-column path="lastName"></vaadin-grid-pro-edit-column>
<vaadin-grid-pro-edit-column path="birthday" editor-type="custom"></vaadin-grid-pro-edit-column>
<vaadin-grid-pro-edit-column path="status" editor-type="custom"></vaadin-grid-pro-edit-column>
<vaadin-grid-pro-edit-column path="time" editor-type="custom"></vaadin-grid-pro-edit-column>
</vaadin-gri-pro>
`);

grid.items = [
{ firstName: 'Aria', lastName: 'Bailey', birthday: '1984-01-13', status: 'suspended', time: '09:00' },
{ firstName: 'Aaliyah', lastName: 'Butler', birthday: '1977-07-12', status: 'active', time: '09:30' },
{ firstName: 'Eleanor', lastName: 'Price', birthday: '1976-12-14', status: 'suspended', time: '10:00' },
{ firstName: 'Allison', lastName: 'Torres', birthday: '1972-12-04', status: 'active', time: '10:00' },
{ firstName: 'Madeline', lastName: 'Lewis', birthday: '1978-02-03', status: 'active', time: '10:00' },
];

grid.querySelector('[path="birthday"]').editModeRenderer = (root, _, model) => {
root.innerHTML = `
<vaadin-date-picker value="${model.item.birthday}" auto-open-disabled>
</vaadin-date-picker>
`;
};

grid.querySelector('[path="status"]').editModeRenderer = (root, _, model) => {
if (!root.firstChild) {
const comboBox = document.createElement('vaadin-combo-box');
comboBox.autoOpenDisabled = true;
comboBox.items = ['active', 'suspended'];
root.appendChild(comboBox);
}
root.firstChild.value = model.item.status;
};

grid.querySelector('[path="time"]').editModeRenderer = (root, _, model) => {
root.innerHTML = `
<vaadin-time-picker value="${model.item.time}" auto-open-disabled></vaadin-time-picker>
`;
};

flushGrid(grid);
await nextRender();
});

describe('date-picker', () => {
it('should apply the updated date to the cell when exiting on Tab', async () => {
const cell = getContainerCell(grid.$.items, 0, 2);
cell.focus();

await sendKeys({ press: 'Enter' });

await sendKeys({ type: '1/12/1984' });
await sendKeys({ press: 'Tab' });

expect(cell._content.textContent).to.equal('1984-01-12');
});

it('should apply the updated date to the cell when exiting on Enter', async () => {
const cell = getContainerCell(grid.$.items, 0, 2);
cell.focus();

await sendKeys({ press: 'Enter' });

await sendKeys({ type: '1/12/1984' });
await sendKeys({ press: 'Enter' });

expect(cell._content.textContent).to.equal('1984-01-12');
});
});

describe('combo-box', () => {
it('should apply the updated value to the cell when exiting on Tab', async () => {
const cell = getContainerCell(grid.$.items, 0, 3);
cell.focus();

await sendKeys({ press: 'Enter' });

await sendKeys({ type: 'active' });
await sendKeys({ press: 'Tab' });

expect(cell._content.textContent).to.equal('active');
});

it('should apply the updated value to the cell when exiting on Enter', async () => {
const cell = getContainerCell(grid.$.items, 0, 3);
cell.focus();

await sendKeys({ press: 'Enter' });

await sendKeys({ type: 'active' });
await sendKeys({ press: 'Enter' });

expect(cell._content.textContent).to.equal('active');
});
});

describe('time-picker', () => {
it('should apply the updated time to the cell when exiting on Tab', async () => {
const cell = getContainerCell(grid.$.items, 0, 4);
cell.focus();

await sendKeys({ press: 'Enter' });

await sendKeys({ type: '10:00' });
await sendKeys({ press: 'Tab' });

expect(cell._content.textContent).to.equal('10:00');
});

it('should apply the updated value to the cell when exiting on Enter', async () => {
const cell = getContainerCell(grid.$.items, 0, 4);
cell.focus();

await sendKeys({ press: 'Enter' });

await sendKeys({ type: '10:00' });
await sendKeys({ press: 'Enter' });

expect(cell._content.textContent).to.equal('10:00');
});
});
});
22 changes: 19 additions & 3 deletions packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ export const InlineEditingMixin = (superClass) =>

/** @private */
_onEditorFocusOut() {
// Ignore focusout from internal tab event
if (this.__cancelCellSwitch) {
return;
}
// Schedule stop on editor component focusout
this._debouncerStopEdit = Debouncer.debounce(this._debouncerStopEdit, animationFrame, this._stopEdit.bind(this));
}
Expand Down Expand Up @@ -426,7 +430,7 @@ export const InlineEditingMixin = (superClass) =>
* @param {!KeyboardEvent} e
* @protected
*/
_switchEditCell(e) {
async _switchEditCell(e) {
if (this.__cancelCellSwitch || (e.defaultPrevented && e.keyCode === 9)) {
return;
}
Expand All @@ -436,11 +440,23 @@ export const InlineEditingMixin = (superClass) =>
const editableColumns = this._getEditColumns();
const { cell, column, model } = this.__edited;

this._stopEdit();
e.preventDefault();
// Prevent vaadin-grid handler from being called
e.stopImmediatePropagation();

const editor = column._getEditorComponent(cell);

// Do not prevent Tab to allow native input blur and wait for it,
// unless the keydown event is from the edit cell select overlay.
if (e.key === 'Tab' && editor && editor.contains(e.target)) {
await new Promise((resolve) => {
editor.addEventListener('focusout', () => resolve(), { once: true });
});
} else {
e.preventDefault();
}

this._stopEdit();

// Try to find the next editable cell
let nextIndex = model.index;
let nextColumn = column;
Expand Down
1 change: 1 addition & 0 deletions packages/grid-pro/test/edit-column-lit.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './not-animated-styles.js';
import '../theme/lumo/vaadin-lit-grid-pro.js';
import '../theme/lumo/vaadin-lit-grid-pro-edit-column.js';
import './edit-column.common.js';
1 change: 1 addition & 0 deletions packages/grid-pro/test/edit-column-polymer.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './not-animated-styles.js';
import '../theme/lumo/vaadin-grid-pro.js';
import '../theme/lumo/vaadin-grid-pro-edit-column.js';
import './edit-column.common.js';
Loading

0 comments on commit b0673cc

Please sign in to comment.