简体   繁体   中英

Angular change focus on enter in reactive forms

I have created a table and a button which creates dynamic rows inside the table with inputs. When i press enter in the first input i want to create new row (which i have done) but not able to focus in the new input. Here is what I've tried

<input type="text" class="form-control" placeholder="Product Code" formControlName="product_code" tabindex="{{i+1}}" (keyup.enter)="autoProduct($event)">

.ts code:

autoProduct(event) {
    this.addProduct();
    if (event.keyCode === 13) {
      event.preventDefault();
      const inputs =
        Array.prototype.slice.call(document.querySelectorAll('input'));
      console.log(inputs);
      const index =
        (inputs.indexOf(document.activeElement) + 1) % inputs.length;
      console.log(index);
      const input = inputs[index];
      console.log(input);
      input.focus();
      input.select();
    }
  }

I've tried this and also this but not able to make it work. Please help.

You can use ViewChildren .

private inputToFocus: any;
@ViewChildren('inputToFocus') set inputF(inputF: any) {
  this.inputToFocus = inputF
  this.inputToFocus.first.nativeElement.focus();
}

Add #inputToFocus in your input tag. <input ... #inputToFocus>

Edit

I don't know how you're adding a new input, but you can use the following code.

.ts:

import { Component, ViewChildren } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 6';
  counts = [1];
  private inputToFocus: any;
  @ViewChildren('inputToFocus') set inputF(inputF: any) {
    this.inputToFocus = inputF
    this.inputToFocus.last.nativeElement.focus();
  }

  autoProduct(event) {
    if (event.keyCode === 13) {
      event.preventDefault();
      const inputs =
        Array.prototype.slice.call(document.querySelectorAll('input'));
      const index =
        (inputs.indexOf(document.activeElement) + 1) % inputs.length;
      this.addProduct(index);
      const input = inputs[index];
      input.focus();
      input.select();
    }
  }
  addProduct(i) {
     this.counts.push(i)
  }
}

.html:

<div *ngFor="let count of counts; let i=index">
  <input type="text" class="form-control" placeholder="Product Code" tabindex="{{i+1}}" (keyup.enter)="autoProduct($event)" #inputToFocus>
</div>

Note that I'm using .last now.

I am providing this sample code , that will permit you to take control over focus in a form.This sample code will focus next field each time you press enter or arrow Down key. It is up to you to customise it to your needs. This sample code shows it works with bootstrap too .

basically,any input fields are recorded in a table. Then, it is up to you to enable focus on which one you want. if you dynamically add an input field, the table will be updated.

I have not found better way with angular.

editor.component.html

 <div > <form> <!-- container-fluid prend toute la largeur de la vue --> <div class="container-fluid" *ngFor="let item of data; let i = index" > <div class="form-group"> <div class="row"> <div class="col-md-3">{{item.designation}}</div> <div class="col-md-2">{{item.type}} </div> <div *ngIf="item.type == 'float'"class="col-md-2">{{item.value | number : '1.1-3'}} </div> <div *ngIf="item.type == 'int'"class="col-md-2">{{item.value | number }} </div> <div class="col-md-2"> <input #input type="number" class="form-control" (keydown)="onKeydown($event,i)"> </div> <div class="col-md-3">{{item.commentaire}} </div> </div> <!-- row --> </div> <!-- form group --> </div> <!--container-fluid--> </form> </div> <!--form-->

editor.component.ts :

 import { Component, OnInit } from '@angular/core'; import { ViewChildren, QueryList } from '@angular/core'; @Component({ selector: 'app-editor', templateUrl: './editor.component.html', styleUrls: ['./editor.component.css'] }) export class EditorComponent implements AfterViewInit { // Viewchildren // https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e @ViewChildren("input") inputs: QueryList<any> constructor() { } private onKeydown(event,val) { console.log(event.key); if ((event.key == "Enter") || (event.key == "ArrowDown")) { // focus next input field if (val +1 < this.inputs.toArray().length) this.inputs.toArray()[val+1].nativeElement.focus(); else this.inputs.toArray()[0].nativeElement.focus(); } } private processChildren(): void { console.log('Processing children. Their count:', this.inputs.toArray().length) } ngAfterViewInit() { console.log("AfterViewInit"); console.log(this.inputs); this.inputs.forEach(input => console.log(input)); // susbcribe to inputs changes, each time an element is added (very optional feature ...) this.inputs.changes.subscribe(_ => this.processChildren() // subsequent calls to processChildren ); } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM