2016-12-15 15 views
6

Mam dziwne wymaganie i miałem nadzieję na jakąś pomoc.Angular 2 Skupienie na pierwszym nieprawidłowym wejściu po kliknięciu/zdarzeniu

Muszę skupić się na pierwszym znalezionym nieprawidłowym wprowadzeniu formularza po kliknięciu przycisku (nie przesyłaj). Formularz jest dość duży, więc ekran musi przejść do pierwszego nieprawidłowego wejścia.

Ten angularjs odpowiedź byłaby czego mi potrzeba, ale nie wiem, czy dyrektywa jak byłoby to do zrobienia w Kątowymi 2:

Set focus on first invalid input in AngularJs form

Jaki byłby kątowej 2 sposób to zrobić? Dzięki za pomoc!

Odpowiedz

5

Niestety nie mogę tego przetestować w tej chwili, więc może być kilka błędów, ale powinno być w większości. Po prostu dodaj go do swojego formularza.

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

Przepraszam za spóźnioną odpowiedź, otrzymam test z tego! Dziękuję za pomoc! –

+0

Jak możemy to zrobić bez jquery? –

+0

Cóż, możesz przejść do elementu bez animacji, lub możesz napisać własną funkcję animacji (lub użyć kogoś innego). Coś podobnego do tego (http://stackoverflow.com/questions/8917921/cross-browser-javascript-not-jquery-scroll-to-topanimation) – Baconbeastnz

2

Jeśli używasz AngularMaterial The MdInputDirective ma metodę ostrości(), która pozwoli Ci skupić się bezpośrednio na polu wprowadzania.

W komponentu, po prostu odniesienie do wszystkich wejść z @ViewChildren adnotacji, tak:

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

Następnie, ustawienie ostrości na pierwszym nieprawidłowym wejście jest tak proste, jak to:

this.inputs.find(input => !input._ngControl.valid).focus()

1

Polecam umieszczenie tego w służbie, dla mnie to działa tak:

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(); 
    }); 
    } 
} 
1

Nie wiem, czy to jest prawidłowe podejście, czy nie, ale to działa dobrze dla mnie.

import { Directive, Input, HostListener, ElementRef } from '@angular/core'; 
import { NgForm } from '@angular/forms'; 
import * as $ from 'jquery'; 

@Directive({ selector: '[accessible-form]' }) 
export class AccessibleForm { 

    @Input('form') form: NgForm; 

    constructor(private el: ElementRef) { 

    } 

    @HostListener('submit', ['$event']) 
    onSubmit(event) { 
     event.preventDefault(); 

     if (!this.form.valid) { 
      let target; 

      target = this.el.nativeElement.querySelector('.ng-invalid') 

      if (target) { 
       $('html,body').animate({ scrollTop: $(target).offset().top }, 'slow'); 
       target.focus(); 
      } 
     } 
    } 

} 

W HTML

<form [formGroup]="addUserForm" class="form mt-30" (ngSubmit)="updateUser(addUserForm)" accessible-form [form]="addUserForm"></form> 

Mam mieszane podejście angularjs dostępnym dyrektywy w tej formie. Ulepszenia są mile widziane !!!