首页 文章

达到maxLength时将输入焦点移动到下一个输入 - Angular 4 / Typescript

提问于
浏览
0

当用户在第一个输入字段中输入maxLength字符数时,我想将焦点从输入字段移动到另一个字段 . 因此,在下面的示例中,当用户在日输入中输入2个字符时,焦点将移至月份输入 .

到目前为止这是我的代码:

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

在我的TS文件中:

keytab(event){
    let nextInput = event.srcElement.nextElementSibling; // get the sibling element

    var target = event.target || event.srcElement;
    var id = target.id
    console.log(id.maxlength); // prints undefined

    if(nextInput == null)  // check the maxLength from here
        return;
    else
        nextInput.focus();   // focus if not null
}

我知道我的TS文件中的代码是错误的,但我试图找到一种获取maxLength属性然后转移焦点的方法 . 现在,只要输入字段中有一个键盘,焦点就会移动 .

谁能告诉我如何从keytab函数访问输入maxLength属性?谢谢 .

我正在使用 Angular 4 .

编辑 - 我正在尝试获取maxLength值,然后与输入值长度进行比较 . 如果输入值更大,则将焦点移至输入字段 .

4 回答

  • 1

    只是一个想法,但如果你使用反应形式,你可以做这样的事情:

    import { FormGroup, FormBuilder, Validators } from "@angular/forms";
    import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
    import "rxjs/add/operator/filter";
    
    @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
          .filter((value: string) => value.length === dayMaxLength)
          .subscribe(() => this.monthElement.nativeElement.focus());
    
        this.form.get("month").valueChanges
          .filter((value: string) => value.length === monthMaxLength)
          .subscribe(() => this.yearElement.nativeElement.focus());
    }
    

    基本上订阅日期和月份表单控件的值更改,过滤每个流,使其仅在值等于最大长度时继续,然后将焦点设置为下一个元素 . 可能值得注意的是,这些也需要取消订阅 .

  • 1

    这是一个通用(指令)解决方案,当达到最大长度时移动到下一个类似的控制类型

    1-创建指令

    import { Directive, ElementRef, HostListener, Input } from '@angular/core';
    
    @Directive({
    selector: '[moveNextByMaxLength]'
    })
    export class MoveNextByMaxLengthDirective {
    
    constructor(private _el: ElementRef) { }
    
    @HostListener('keyup', ['$event']) onKeyDown(e: any) {
        if (e.srcElement.maxLength === e.srcElement.value.length) {
    
            e.preventDefault();
    
            let nextControl: any = e.srcElement.nextElementSibling;
           // Searching for next similar control to set it focus
            while (true)
            {
                if (nextControl)
                {
                    if (nextControl.type === e.srcElement.type)
                    {
                        nextControl.focus();
                        return;
                    }
                    else
                    {
                        nextControl = nextControl.nextElementSibling;
                    }
                }
                else
                {
                    return;
                }
            }
        }
    }
    
    }
    

    2-在模块中声明指令

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

    3-在组件中使用指令

    <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" />
    
  • 1

    使用不同的方法 . Angular不像jQuery那样从现有DOM中选择元素和读取属性,因为Angular从数据生成DOM . 所以's difficult, if possible at all, to read the input' s maxlength 属性,无论如何它将是笨拙的"non-Angulary" .

    相反,使用不同的方法并在 keyup 函数中传递maxLength:

    <input type="text" (keyup)="keytab($event, 2)" />
    <input type="text" (keyup)="keytab($event, 4)" />
    
    
    keytab(event, maxLength){
       console.log(maxlength); // 2 or 4
       // .......
    }
    
  • 1

    纯粹的js方法

    let allInputs = document.getElementsByTagName('input');
    let index = 0;
    for(i=0;i<allInputs.length;i++) {
    allInputs[i].onkeydown =trackInputandChangeFocus;
    }
    
    function trackInputandChangeFocus() {
    let allInputsArr = Array.from(allInputs); 
    let presentInput = allInputsArr.indexOf(this)
    if(this.value.length == parseInt(this.getAttribute('maxlength'))) {
          let next;
          if(presentInput != 2) next = allInputsArr[presentInput+1]
          else next = allInputsArr[0]
          next.focus();
        }
    }
    
    <input formControlName="day" maxlength="2" placeholder="DD" type="text" (keyup)="keytab($event)" />
    <input formControlName="month" maxlength="2" placeholder="MM" type="text" (keyup)="keytab($event)" />
    <input formControlName="year" maxlength="4" placeholder="YYYY" type="text" />
    

相关问题