Angular 2 Focus on first invalid input after Click/Event

前端 未结 9 1707
不思量自难忘°
不思量自难忘° 2021-02-04 03:46

I have an odd requirement and was hoping for some help.

I need to focus on the first found invalid input of a form after clicking a button (not submit). The form is rath

相关标签:
9条回答
  • 2021-02-04 04:45

    Unfortunately I can't test this at the moment, so might be a few bugs, but should be mostly there. Just add it to your form.

    import {Directive, Input, HostListener} from '@angular/core';
    import {NgForm} from '@angular/forms';
    
    @Directive({ selector: '[scrollToFirstInvalid]' })
    export class ScrollToFirstInvalidDirective {
      @Input('scrollToFirstInvalid') form: NgForm;
      constructor() {
      }
      @HostListener('submit', ['$event'])
      onSubmit(event) {
        if(!this.form.valid) {
          let target;
          for (var i in this.form.controls) {
            if(!this.form.controls[i].valid) {
              target = this.form.controls[i];
              break;
            }
          }
          if(target) {
            $('html,body').animate({scrollTop: $(target.nativeElement).offset().top}, 'slow');
          }
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-04 04:46

    I recommend putting this in a service, for me it worked like this:

    if (this.form.valid) {
      //submit
    } else {
      let control;
      Object.keys(this.form.controls).reverse().forEach( (field) => {
        if (this.form.get(field).invalid) {
          control = this.form.get(field);
          control.markAsDirty();
        }
      });
    
      if(control) {
        let el = $('.ng-invalid:not(form):first');
        $('html,body').animate({scrollTop: (el.offset().top - 20)}, 'slow', () => {
          el.focus();
        });
      }
    }
    
    0 讨论(0)
  • 2021-02-04 04:50

    I've created an Angular directive to solve this problem. You can check it here ngx-scroll-to-first-invalid.

    Steps:

    1.Install the module:

    npm i @ismaestro/ngx-scroll-to-first-invalid --save
    

    2.Import the NgxScrollToFirstInvalidModule:

    import {BrowserModule} from '@angular/platform-browser';
    import {NgModule} from '@angular/core';
    import {NgxScrollToFirstInvalidModule} from '@ismaestro/ngx-scroll-to-first-invalid';
    
    @NgModule({
        imports: [
            BrowserModule,
            NgxScrollToFirstInvalidModule
        ],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    3.Use the directive inside a form:

    <form [formGroup]="testForm" ngxScrollToFirstInvalid>
      <input id="test-input1" type="text" formControlName="someText1">
      <button (click)="saveForm()"></button>
    </form>
    

    Hope it helps! :)

    0 讨论(0)
提交回复
热议问题