Saltar al contenido

Mover el foco de entrada a la siguiente entrada cuando se alcanza maxLength – Angular 4 / Typecript

Solución:

aquí hay una solución genérica (directiva) para pasar al siguiente tipo de control similar cuando alcanza la longitud máxima

1- Crea la Directiva

import { Directive, HostListener } from '@angular/core';

@Directive({
  selector: 'input[moveNextByMaxLength], textarea[moveNextByMaxLength]',
})
export class MoveNextByMaxLengthDirective {
  @HostListener('keyup', ['$event']) onKeyDown(keyboardEvent: KeyboardEvent) {
    const target = keyboardEvent.target as
      | HTMLInputElement
      | HTMLTextAreaElement
      | null;

    if (!target || target.maxLength !== target.value.length) return;

    keyboardEvent.preventDefault();

    const { type } = target;
    let { nextElementSibling } = target;

    while (nextElementSibling) {
      if (
        (nextElementSibling as HTMLInputElement | HTMLTextAreaElement).type ===
        type
      ) {
        (nextElementSibling as HTMLInputElement | HTMLTextAreaElement).focus();
        return;
      }

      nextElementSibling = nextElementSibling.nextElementSibling;
    }
  }
}

2- Declarar la Directiva en el módulo

@NgModule({
  imports: [ BrowserModule ],
  declarations: [
    AppComponent,
    MoveNextByMaxLengthDirective 
  ],
  bootstrap: [ AppComponent ]
})

3- Utilice la directiva en el componente

<input formControlName="day" maxlength="2" moveNextByMaxLength placeholder="DD" type="text" (keyup)="keytab($event)" />
<input formControlName="month" maxlength="2" moveNextByMaxLength placeholder="MM" type="text" (keyup)="keytab($event)" />
<input formControlName="year" maxlength="4" placeholder="YYYY" type="text" />

Utilice un enfoque diferente. Angular no selecciona elementos ni lee atributos del DOM existente, como lo hace jQuery, porque Angular genera el DOM a partir de datos. Por lo que es difícil, si es posible, leer la entrada maxlength atributo, y de todos modos sería torpe un “no Angular”.

En su lugar, utilice un enfoque diferente y pase maxLength en el keyup función:

<input type="text" (keyup)="keytab($event, 2)" />
<input type="text" (keyup)="keytab($event, 4)" />


keytab(event, maxLength){
   console.log(maxlength); // 2 or 4
   // .......
}

Solo una idea, pero si está utilizando formas reactivas, podría hacer algo como esto:

import { FormGroup, FormBuilder, Validators } from "@angular/forms";
import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
import { filter } "rxjs/operators";

@Component({
  selector: "app-form",
  template: `
    <form [formGroup]="form">
        <input formControlName="day" placeholder="DD" type="text" #day />
        <input formControlName="month" placeholder="MM" type="text" #month />
        <input formControlName="year" placeholder="YYYY" type="text" #year />
    </form>
`
})
export class FormComponent implements OnInit {
  form: FormGroup;

  @ViewChild("day") dayElement: ElementRef;

  @ViewChild("month") monthElement: ElementRef;

  @ViewChild("year") yearElement: ElementRef;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    const dayMaxLength = 2;
    const monthMaxLength = 2;
    const yearMaxLength = 4;

    this.form = this.fb.group({
      day: ["", [Validators.required, Validators.maxLength(dayMaxLength)]],
      month: ["", [Validators.required, Validators.maxLength(monthMaxLength)]],
      year: ["", [Validators.required, Validators.maxLength(yearMaxLength)]]
    });

    this.form.get("day").valueChanges
      .pipe(filter((value: string) => value.length === dayMaxLength))
      .subscribe(() => this.monthElement.nativeElement.focus());

    this.form.get("month").valueChanges
      .pipe(filter((value: string) => value.length === monthMaxLength))
      .subscribe(() => this.yearElement.nativeElement.focus());
}

Básicamente, suscríbase a los cambios de valor de los controles de formulario de día y mes, filtre cada flujo para que solo continúe cuando el valor sea igual a la longitud máxima, luego establezca el foco en el siguiente elemento. Probablemente valga la pena señalar que también será necesario cancelar la suscripción a estos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *