diff --git a/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.d.ts b/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.d.ts index 2fdd55a493..c4e3df9974 100644 --- a/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.d.ts +++ b/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.d.ts @@ -39,4 +39,14 @@ export declare class InlineEditingMixinClass { protected _stopEdit(shouldCancel?: boolean, shouldRestoreFocus?: boolean): void; protected _switchEditCell(e: KeyboardEvent): void; + + /** + * Triggers the editor for a given (row,col) + * row should be a number (element index) + * column can be either a number (element index) or a string (columnId) + * @param {number} row + * @param {number | string} col + * @public + */ + editCell(row: number, col: number | string): void; } diff --git a/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js b/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js index 4c176ebe0f..3285e11853 100644 --- a/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js +++ b/packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js @@ -455,6 +455,58 @@ export const InlineEditingMixin = (superClass) => super._updateItem(row, item); } + /** + * Triggers the editor for a given (row, col) + * row should be a number (element index) + * column can be either a number (element index) or a string (columnId) + * @param {number | string} row + * @param {number | string} col + * @public + */ + editCell(row, col) { + const columns = this._getColumns().filter((col) => !col.hidden); + + let colIdx = -1; + // If col is not a number, maybe it's because the id was passed instead + if (isNaN(col)) { + const matchingColumn = columns.filter((c) => c.id == col); + if (!matchingColumn || matchingColumn.length == 0) { + throw new Error(`col with id ${col} was not found`); + } + colIdx = columns.indexOf(matchingColumn[0]); + } else { + colIdx = col; + } + + let rowIdx = -1; + // If row is not a number, maybe it's because the item was passed instead + if (isNaN(row)) { + throw new Error('Invalid argument type passed as row index.'); + } else { + rowIdx = row; + } + + // Make sure col[colIdx] exists and is editable: + if (colIdx > columns.length || colIdx < 0) { + throw new Error('Invalid colIdx (out of bounds)'); + } + + const column = columns[colIdx]; + if (!this._isEditColumn(column)) { + throw new Error('Column is not editable'); + } + + // Get rows (excluding header) + const tRows = this._getVisibleRows(); + + // Make sure row[rowIdx] exists + if (rowIdx > tRows.length || rowIdx < 0) { + throw new Error('Invalid rowIdx (out of bounds)'); + } + + this._startEdit(tRows[rowIdx].cells[colIdx], column); + } + /** * Fired before exiting the cell edit mode, if the value has been changed. * If the default is prevented, value change would not be applied. diff --git a/packages/grid-pro/test/edit-column-renderer.test.js b/packages/grid-pro/test/edit-column-renderer.test.js index 5e9725d051..8d8dd645e4 100644 --- a/packages/grid-pro/test/edit-column-renderer.test.js +++ b/packages/grid-pro/test/edit-column-renderer.test.js @@ -289,4 +289,76 @@ describe('edit column renderer', () => { expect(grid.items[0].name).to.equal('New'); }); }); + + describe('programatically enter edit mode', () => { + let grid; + + beforeEach(() => { + grid = fixtureSync(` + + + + + + + + `); + const column = grid.firstElementChild; + grid.items = createItems(); + + column.renderer = function (root, owner, model) { + root.innerHTML = ''; + const wrapper = document.createElement('div'); + const text = document.createTextNode(model.index + ' ' + model.item.name); + wrapper.appendChild(text); + root.appendChild(wrapper); + }; + + flushGrid(grid); + }); + + it('enter edit mode programatically should fail for non-existing indexes', () => { + expect(() => { + grid.editCell(0, 10, false); + }).to.throw(Error, /out of bounds/); + + expect(() => { + grid.editCell(10, 0, false); + }).to.throw(Error, /out of bounds/); + }); + + it('enter edit mode programatically should fail for non-existing column (by id)', () => { + expect(() => { + grid.editCell(0, 'name', false); + }).to.not.throw(Error, 'col with id name was not found'); + + expect(() => { + grid.editCell(10, 'invalid', false); + }).to.throw(Error, 'col with id invalid was not found'); + }); + + it('enter edit mode programatically should fail for non-editable columns', () => { + expect(() => { + grid.editCell(0, 0, false); + }).to.not.throw(Error, 'Column is not editable'); + + expect(() => { + grid.editCell(0, 1, false); + }).to.throw(Error, 'Column is not editable'); + }); + + it('enter edit mode programatically (x,y) should show the editor', () => { + const cell = getContainerCell(grid.$.items, 0, 0); + grid.editCell(0, 0, false); + const editor = getCellEditor(cell); + expect(editor).to.be.ok; + }); + + it('enter edit mode programatically (x,colId) should show the editor', () => { + const cell = getContainerCell(grid.$.items, 0, 0); + grid.editCell(0, 'name', false); + const editor = getCellEditor(cell); + expect(editor).to.be.ok; + }); + }); });