Dynamic tables: focus to first input when adding a row.

This commit is contained in:
John Livingston 2024-06-12 15:43:09 +02:00
parent 72c4b0804d
commit a4a9f85956
No known key found for this signature in database
GPG Key ID: B17B5640CE66CDBC
2 changed files with 31 additions and 1 deletions

View File

@ -140,7 +140,7 @@ export class DynamicTableFormElement extends LivechatElement {
return Object.fromEntries([...Object.entries(this.schema).map((entry) => [entry[0], entry[1].default ?? ''])])
}
private readonly _addRow = (): void => {
private async _addRow (): Promise<void> {
const newRow = this._getDefaultRow()
// Create row and assign id and original index
this._rowsById.push({ _id: this._lastRowId++, _originalIndex: this.rows.length, row: newRow })
@ -148,6 +148,17 @@ export class DynamicTableFormElement extends LivechatElement {
this.requestUpdate('rows')
this.requestUpdate('_rowsById')
this.dispatchEvent(new CustomEvent('update', { detail: this.rows }))
// Once the update is completed, we give focus to the first input field of the new row.
await this.updateComplete
// Note: we make multiple querySelector, to be sure to not get a nested table.
// We want the top level table associated tr.
const input = this.querySelector('table')?.querySelector(
'&>tbody>tr:last-child>td input:not([type=hidden]),&>tbody>tr:last-child>td livechat-tags-input'
)
if (input) {
(input as HTMLElement).focus()
}
}
private async _removeRow (rowId: number): Promise<void> {

View File

@ -54,6 +54,25 @@ export class TagsInputElement extends LivechatElement {
@property({ attribute: false })
public animDuration: number = 200
/**
* Overloading the standard focus method.
*/
public override focus (): void {
const input = this.querySelector('input[type=text]')
if (input) {
(input as HTMLInputElement).focus()
return
}
// Never rendered, we will wait for the update to be complete, and then render.
// This is not fully compliant, as it is not synchrone... But needed (see dynamic-table addRow)
this.updateComplete.then(() => {
const input = this.querySelector('input[type=text]')
if (input) {
(input as HTMLInputElement).focus()
}
}, () => {})
}
protected override render = (): unknown => {
return html`<ul
id="tags"