Угловые 5 имитируют нажатия клавиш управления входом

Я пытаюсь имитировать нажатие клавиши табуляции, когда вводится нажатие на элементе управления ввода. Для этого я использую директиву:

 private el: ElementRef;
    @Input() onEnter: string;
    constructor(private _el: ElementRef, public renderer: Renderer) {
        this.el = this._el;
    }
    @HostListener('keydown', ['$event']) onKeyDown(e: any) {
        if ((e.which === 13 || e.keyCode === 13)) {
            e.preventDefault();


    const event = new KeyboardEvent("keypress", {
            "key": "Tab"
          });
          this.el.nativeElement.dispatchEvent(event);
............

код для ввода ключевых огней, но ни одна вкладка не отправляется

angular,typescript,angular-directive,

0

Ответов: 2


1

Если вы хотите использовать ENTER для фокусировки элемента, вы можете использовать директиву

@Directive({
  selector: '[next-tab]',
})
export class NextTabDirective {


  @Input('next-tab') nextControl: any;

  @HostListener("keydown.enter", ["$event"])
  onEnter(event: KeyboardEvent) {
    if (this.nextControl) {
      if (this.nextControl.focus) {
        this.nextControl.focus();
        this.nextControl.select();
        event.preventDefault();
        return false;
      }
    }
  }

  constructor(private control: NgControl) {
  }
}

Вы можете использовать в форме, подобной

  <form (submit)="Submit()">
      <input #input0 [next-tab]="input1"  />
      <input #input1 [next-tab]="input2"  />
      <!--the last not have [next-tab]-->
      <!-an ENTER make a submit -->
      <input #input2   />
       <button type="button" (click)="cancel()">Cancel</button>
       <button type="submit">OK</button>
   </form>

Я бы не хотел использовать эту уродливую работу, но мы можем улучшить отправку директивы в качестве следующей вкладки в виде массива элементов управления

@Directive({
  selector: '[next-tab]',
})
export class NextTabDirective {

  @Input('next-tab') nextControl: any[]; //<--an array of controls

  @HostListener("keydown.enter", ["$event"])
  onEnter(event: KeyboardEvent) {

    //find the nextControl not disabled. We check if c is defined
    //This allow us to use *ngIf and not put the control
    let nextControl=this.nextControl.find(c=>c && !c.disabled);
    if (nextControl) {
      if (nextControl.focus) {
        nextControl.focus();
        nextControl.select();
        event.preventDefault();
        return false;
      }
    }
  }

  constructor(private control: NgControl) {
  }
}

Форма выглядит

   <form (submit)="Submit()">
      <!--see that we create an array-->
      <input #input0 [next-tab]="[input1,input2,input3]"  />
      <input #input1 [next-tab]="[input2,input3]"  />
      <!--if only one element, we make an array of one element-->
      <input #input2 [style.display]="existInput2?'inherit':'none'" [next-tab]="[input3]"   />
      <!--if we want make invisible control NOT use *nfIf, therefore, we must hidden and disabled too -->

      <input #input3 />
       <button type="button" (click)="cancel()">Cancel</button>
       <button type="submit">OK</button>
   </form>

Наконец, я поместил stackblitz в https://stackblitz.com/edit/angular-v8fkkf


1

Существует более «удобный способ сделать« следующую вкладку »: идея состоит в том, что директива next-tab имеет две переменные:« self »и« next-control ». Мы не используем @Input, директива подобна

@Directive({
  selector: '[next-tab]',
})
export class NextTabDirective {

  self:any;     
  nextControl:any;  //See that is not a @Input

  @HostListener("keydown.enter", ["$event"])
  onEnter(event: KeyboardEvent) {
    if (this.nextControl) {
      if (this.nextControl.focus) {
        this.nextControl.focus();
        this.nextControl.select();
        event.preventDefault();
        return false;
      }
    }
  }

  constructor(private control: ElementRef) {
    //we store in "self" the native element. This make us easy refered to 
    //html properties of control
    this.self=control.nativeElement;
  }
}

В .html см., Что директива - это просто следующая вкладка, а не [следующая вкладка], а не [next-tab] = "". Учтите, что input4 слишком «украшен» директивой и что все входные данные имеют свойство «name» html

<form [formGroup]="myForm" (submit)="submit(myForm)">
  <p>
    <input type="checkbox" formControlName="ckDisabled"/>Disabled input 2
  </p>
  <p>
    <input type="checkbox" formControlName="ckInvisible"/>Invisible input 3
  </p>
  <p>
    Input 1: <input name="input1" formControlName="input1"
              next-tab/>
  </p>
  <p>
    Input 2: <input name="input2" formControlName="input2" tabindex=""
              [enableControl]="!myForm.controls['ckDisabled'].value" 
              next-tab/>
  </p>
  <p [style.display]="myForm.controls['ckInvisible'].value?'none':'inherit'">
    Input 3: <input name="input3" formControlName="input3"
              [enableControl]="!myForm.controls['ckInvisible'].value"
              next-tab
/>
  </p>
  <p>
    Input 4: <input name="input4"  next-tab formControlName="input4"/>
  </p>
  <p>
  <button>OK</button>
</p>
  </form>

И теперь .ts. Мы используем ViewChildren для получения всего элемента с директивой next-tab.

export class AppComponent implements OnInit,AfterViewInit  {
  //We use a ViewChildren to get all the controls width NextTabDirective
  //We use QueryList<NextTabDirective>. So the elements of "inputs"
  //will have the properties: self and nextControl

  @ViewChildren(NextTabDirective) inputs: QueryList<NextTabDirective>;

  myForm:FormGroup;

  constructor(private fb:FormBuilder){}
  //in ngAfterViewInit we asing to nextControl, the self of the next control
  ngAfterViewInit() {
      const controls=this.inputs.toArray();
      //controls will be [input1,input2,input3,input4]
      for (let i=0;i<controls.length-1;i++)
          controls[i].nextControl=controls[i+1].self;        }
}


  ngOnInit()
  {
   this.myForm=this.fb.group({
    ckDisabled:false,
    ckInvisible:false,
    input1:'',
    input2:'',
    input3:'',
    input4:''

  });
  this.onChanges();
  }
  onChanges()
  {
    this.myForm.valueChanges.subscribe((value)=>{
         if (this.inputs)
         {
           //see how we get the control using self.name
           const input1=this.inputs.find(c=>c.self.name=="input1");
           const input2=this.inputs.find(c=>c.self.name=="input2");
           const input3=this.inputs.find(c=>c.self.name=="input3");
           const input4=this.inputs.find(c=>c.self.name=="input4");

           input1.nextControl=(value.ckDisabled && value.ckInvisible)?input4.self:
                            (value.ckDisabled)?input3.self:input2.self;
           input2.nextControl=(value.ckInvisible)?input4.self:input3.self;
         }

    })

  }
  submit(form:any)
  {
    if (form.valid)
      alert("Fom submitted!!")
  }
}

есть stackBlitz в https://stackblitz.com/edit/angular-dzdxmh

угловая, машинопись, угловая директивы,
Похожие вопросы