Установить фокус p-таблицы на следующий ввод при вставке значения

#angular #typescript

#angular #typescript

Вопрос:

Я получил p-таблицу с полем ввода в компоненте. После заполнения входных данных и отправки данных с помощью rest в базу данных я хочу установить фокус с входных данных, нажав «tab» на следующий фокусируемый ввод, как в Excel.

Нужно ли мне делать это с помощью директив?

 <ng-template pTemplate="body" class="tableBody" let-rowData let-x="rowIndex" let-columns="columns">
   <tr [pSelectableRow]="rowData" [ngClass]="rowData.editable != 'true' ? 'cell-color-gray2' : null" [hidden]="!showSubTotal(rowData)">
      <td *ngFor="let col of columns; let i = index" class="ui-resizable-column" [pEditableColumn]="rowData[col.field]" [pEditableColumnField]="rowData[col.field]">
         <p-cellEditor>
            <ng-template pTemplate="input">
               <div *ngIf="menuLabels.state=='editable' amp;amp; rowData.editable=='true'">
                  <div *ngIf="col.field=='customEffort'" class="tableColumnRight">
                     <input #inputs type="text" ngDefaultControl [(ngModel)]="this.rowData.effort" autoResize="autoResize"
                            (focusout)="workaroundUpdateDataEffort({ data: rowData, costCenterNr: col.header.split(' ')[0], columns: columns }, x, i)"
                            (keydown.tab)="workaroundUpdateDataEffort({ data: rowData, costCenterNr: col.header.split(' ')[0], columns: columns }, x, i)"
                            (keydown.enter)="workaroundUpdateDataEffort({ data: rowData, costCenterNr: col.header.split(' ')[0] })"
                            (keydown.esc)="workaroundCatchEsc({ data: rowData })">
                  </div>
  

Комментарии:

1. Я думаю, вы хотите, чтобы табуляция фокусировалась на элементе

Ответ №1:

Вы можете использовать директиву, но это необязательно, вы также можете запустить это с помощью события. Что вам нужно, так это ссылка на HTML-элемент, на котором вы хотите сфокусироваться. Вы делаете это с помощью ViewChild:

 @ViewChild('tab') inputEl:ElementRef;
  

Чтобы это сработало, вы должны установить ref-id в вашем html:

 <tr #tab> <!-- element that holds the loop -->
  

Теперь, где-нибудь в вашем коде, где вы вызываете службу REST:

 onYourEvent(index) {
  restService.sendData().subscribe((res) => {
    // do something with the received data
    // then set the focus to the next element:
    const inputs = this.inputEl.nativeElement.querySelectorAll('input');
    if (inputs.length > index   1) {
      inputs[index   1].focus();
    }
  });
}
  

Вот демонстрация на stackblitz

Комментарии:

1. Я пытаюсь сфокусировать элемент, но он все еще не работает. На всякий случай я неправильно описал свою проблему. Я получил поле ввода в p-таблице и, например, после нажатия клавиши TAB интерфейс отправляет через REST данные, а затем следующее поле ввода справа должно быть сфокусировано, поэтому я могу гарантировать принятие пользователем.

2. ОК. Вы попадаете в restDoneEventHandler? Вы можете проверить, например, путем печати на консоли, просто для тестирования. Затем, я полагаю, вы устанавливаете загруженные данные на вход и после этого хотите сфокусировать следующий элемент. Поэтому убедитесь, что restDoneEventHandler выполняется после того, как вы задали данные. В противном случае возможно, что первый ввод вернет фокус, потому что данные изменились.

3. Сначала спасибо за вашу помощь до сих пор. Я могу получить доступ к обработчику, но, к сожалению, он не будет фокусировать следующий ввод. Я только что проверил DOM-дерево входных данных. Мое DOM-дерево выглядит примерно так: TD -> CELLEDIT -> DIV -> DIV -> ВВОД. Таким образом, цикл повторяется с celledit, а не с input . Возможно ли решить мою проблему путем ручной навигации по элементам?

4. да, просто убедитесь, что дочерний элемент view находится вне цикла, а затем вы можете использовать queryselector для поиска входных данных. Смотрите редактирование.

5. Итак, единственное, чего я могу достичь прямо сейчас, это отобразить массив <tr> с их <td> в нем. Но я все еще не могу получить к нему доступ с помощью .focus()… Вам нужна дополнительная информация?