代码之家  ›  专栏  ›  技术社区  ›  firasKoubaa

角度6反应形式:Hoo将焦点设置在第一个无效输入上

  •  2
  • firasKoubaa  · 技术社区  · 7 年前

    在我的 角度6 应用程序,我正在使用 反应形式 .

    我的表单如下所示:

    <form [formGroup]="addItemfForm " (ngSubmit)="onSubmitForm()">
    
      <div class="form-inline form-group">
        <label class="col-md-2 justify-content-start">
            Libellé du pef
            <span class="startRequired mr-1"> *</span>
        </label>
        <input type="text" maxlength="100" formControlName="libellePef" class="col-md-6 form-control" placeholder="saisie obligatoire" [ngClass]="{ 'is-invalid': submitted && formFiels.libellePef.errors }" />
        <div *ngIf="submitted && formFiels.libellePef.errors" class="col invalid-feedback">
          <div class="col text-left" *ngIf="formFiels.libellePef.errors.required">Libellé du pef est requis.</div>
        </div>
      </div>
    
      <div class="form-inline form-group">
        <label class="col-md-2 justify-content-start">
           Code Basicat
           <span class="startRequired mr-1"> *</span>
        </label>
        <input type="text" maxlength="100" formControlName="codeBasicat" class="col-md-3 form-control" placeholder="saisie obligatoire" [ngClass]="{ 'is-invalid': submitted && formFiels.codeBasicat.errors }" />
        <div *ngIf="submitted && formFiels.codeBasicat.errors" class="col invalid-feedback">
          <div class="text-left" *ngIf="formFiels.codeBasicat.errors.required">Code Basicat est requis.</div>
        </div>
      </div>
    
      <div class="form-inline form-group">
        <label class="col-md-2 justify-content-start">
            Nom de l'application
            <span class="startRequired mr-1"> *</span>
        </label>
        <input type="text" maxlength="100" formControlName="nomApplication" class="col-md-6 form-control" placeholder="saisie obligatoire" [ngClass]="{ 'is-invalid': submitted && formFiels.nomApplication.errors }" />
        <div *ngIf="submitted && formFiels.nomApplication.errors" class="col invalid-feedback">
          <div class="text-left" *ngIf="formFiels.nomApplication.errors.required">Nom de l'application est requis.
          </div>
        </div>
      </div>
    </form>
    

    在我的TS文件下,我的表单配置如下所示:

    this.addItemfForm = this.formBuilder.group({
      libellePef: ['', Validators.required],
      codeBasicat: ['', Validators.required ],
      nomApplication: ['', Validators.required ],
      urlCible: [''],
      modeTransfert: [''],
    });
    

    自动对焦 但那不起作用

    建议?

    2 回复  |  直到 6 年前
        1
  •  21
  •   Avinash Manohar    6 年前

    在提交时使用以下代码。

    for (const key of Object.keys(this.addressForm.controls)) {
          if (this.addressForm.controls[key].invalid) {
            const invalidControl = this.el.nativeElement.querySelector('[formcontrolname="' + key + '"]');
            invalidControl.focus();
            break;
         }
    }
    

    此.addressForm将成为您的FormGroup。

        2
  •  7
  •   SiddAjmera    7 年前

    我的回答是从 yurzui 的 answer 在这里我用他回答的逻辑来得到答案 nativeElement 特定的 FormControl 通过使用它的 窗体控件 .

    const originFormControlNameNgOnChanges = FormControlName.prototype.ngOnChanges;
    FormControlName.prototype.ngOnChanges = function () {
      const result = originFormControlNameNgOnChanges.apply(this, arguments);
      this.control.nativeElement = this.valueAccessor._elementRef.nativeElement;
      return result;
    };
    

    现在,表单的errors字段将为null,即使它的字段无效。因此,为了得到第一个无效的字段,我们必须遍历所有字段并检查每个字段的有效性。我可以把这个逻辑写在 onSubmitForm() 方法大概是这样的:

    onSubmitForm() {
      const fieldsToCheck = [
        'codeBasicat',
        'libellePef',
        'nomApplication'
      ];
      for (let i = 0; i < fieldsToCheck.length; i++) {
        const fieldName = fieldsToCheck[i];
        if (this.addItemfForm.get(fieldName).invalid) {
          ( < any > this.addItemfForm.get(fieldName)).nativeElement.focus();
          break;
        }
      }
    }
    

    我故意用 for 而不是 Array.forEach 因为我想打破这个循环。

    希望这能帮到你。

    Working Sample StackBlitz

        3
  •  3
  •   piotr szybicki    7 年前

    我是用指令做的。因此,我的表单如下所示:

    <form [formGroup]="userForm" (submit)="saveData()" appFocus >
    ...
    </form>
    

    import { Directive, HostListener, Input, ElementRef } from '@angular/core';
    import { NgForm } from '@angular/forms';
    
    @Directive({
      selector: '[appFocus]'
    })
    export class FocusDirective {
    
      constructor(private el: ElementRef) { }
    
      @Input() formGroup: NgForm;
    
      @HostListener('submit', ['$event'])
      public onSubmit(event): void {
        if ('INVALID' === this.formGroup.status) {
          event.preventDefault();
    
          const formGroupInvalid = this.el.nativeElement.querySelectorAll('.ng-invalid');
          (<HTMLInputElement>formGroupInvalid[0]).focus();
        }
      }
    }
    

        4
  •  3
  •   Aswathy    6 年前

    我们只需在表单的submit()中编写此代码,就可以将焦点设置在第一个无效输入上。

       if(this.form.invalid)
        {  
          // Got focus to the error field
        let invalidFields = [].slice.call(document.getElementsByClassName('ng-invalid'));
        invalidFields[1].focus();  
    
        }
    
        5
  •  1
  •   Mateus Gonçalves    7 年前

    import { Directive, HostListener, ElementRef} from '@angular/core';
    
    @Directive({
      selector: '[focusFirstInvalidField]'
    })
    export class FocusFirstInvalidFieldDirective {
    
      constructor(private el: ElementRef) { }
    
      @HostListener('submit')
      onFormSubmit() {
        const invalidElements = this.el.nativeElement.querySelectorAll('.ng-invalid');
        if (invalidElements.length > 0) {
          console.log(invalidElements[0]); 
    
          invalidElements[0].focus();
        }
      }
    }
    

    请记住调试,看看元素0是否不是我遇到的您自己的表单,所以请正确查看它作为第一个字段报告的字段,并正确放置位置。

        6
  •  0
  •   JLazar0    7 年前

    @Directive({
      selector: '[appErrorFocusin]'
    })
    export class ErrorFocusinDirective {
    
      selectorToFocus : String = 'textArea,mat-select,select,input,button';
    
      constructor(private el: ElementRef,
        @Inject(DOCUMENT) private document: Document) { }
    
      @Input() formGroup: NgForm;
    
      @HostListener('submit', ['$event'])
      public onSubmit(event): void {
        if ('INVALID' === this.formGroup.status) {
          event.preventDefault();
    
          const formGroupInvalid = this.el.nativeElement.querySelectorAll('.ng-    invalid,:not(.mat-badge-hidden).mat-badge');
          let elementToOffset = this.getElementToOffset(formGroupInvalid[0]);
          this.document.documentElement.scrollTop = elementToOffset.offsetTop;
          this.setFocusOnError(elementToOffset);
        }
      }
    
    
      getElementToOffset(element : any){
        let defaultElement = element;
        while (!(element.parentElement instanceof HTMLFormElement)){
          if (element.parentElement){
            element = element.parentElement;
          }else{
            return defaultElement;
          }
        }
        return element;
      }
    
      setFocusOnError(elementToOffset : any){
        let listaElementos =     elementToOffset.querySelectorAll(this.selectorToFocus);
        if (listaElementos.length>0){
          listaElementos[0].focus();
        }
      }
    
    }
    
    推荐文章