![](/img/trans.png)
[英]Angular 6 Reactive Forms : How to set focus on first invalid input
[英]Angular 2 Focus on first invalid input after Click/Event
我有一個奇怪的要求,並希望得到一些幫助。
單擊按鈕(不提交)后,我需要關注表單的第一個找到的無效輸入。 表單相當大,因此屏幕需要滾動到第一個無效輸入。
這個AngularJS答案將是我需要的,但不知道這樣的指令是否是Angular 2的方法:
Angular 2的方法是什么? 感謝您的幫助!
這適合我。 不是最優雅的解決方案,但考慮到Angular中的約束,我們都在為這個特定的任務經歷,它完成了這項工作。
scrollTo(el: Element): void {
if(el) {
el.scrollIntoView({ behavior: 'smooth' });
}
}
scrollToError(): void {
const firstElementWithError = document.querySelector('.ng-invalid');
this.scrollTo(firstElementWithError);
}
async scrollIfFormHasErrors(form: FormGroup): Promise <any> {
await form.invalid;
this.scrollToError();
}
這有效,允許您逃避操縱DOM。 它只是通過document.querySelector()
返回頁面上第一個帶有.ng-invalid
的元素,它返回返回列表中的第一個元素。
要使用它 :
this.scrollIfFormHasErrors(this.form).then(() => {
// Run any additional functionality if you need to.
});
我也在Angular的Github頁面上發布了這個: https : //github.com/angular/angular/issues/13158#issuecomment-432275834
不幸的是我現在無法測試這個,所以可能是一些錯誤,但應該主要在那里。 只需將其添加到您的表單即可。
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');
}
}
}
}
我不知道這是否有效,但這對我來說非常有用。
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();
}
}
}
}
在HTML中
<form [formGroup]="addUserForm" class="form mt-30" (ngSubmit)="updateUser(addUserForm)" accessible-form [form]="addUserForm"></form>
我在這里混合了angularjs可訪問表單指令的方法。 歡迎改進!!!
如果您使用的是AngularMaterial ,則MdInputDirective具有focus()方法,該方法允許您直接關注輸入字段。
在您的組件中,只需使用@ViewChildren注釋獲取對所有輸入的引用 ,如下所示:
@ViewChildren(MdInputDirective) inputs: QueryList<MdInputDirective>;
然后,將焦點設置在第一個無效輸入上就像這樣簡單:
this.inputs.find(input => !input._ngControl.valid).focus()
@HostListener('submit', ['$event'])
onSubmit(event) {
event.preventDefault();
if (!this.checkoutForm.valid) {
let target;
target = $('input[type=text].ng-invalid').first();
if (target) {
$('html,body').animate({ scrollTop: $(target).offset().top }, 'slow', ()=> {
target.focus();
});
}
}
}
我已經創建了一個Angular指令來解決這個問題。 你可以在這里檢查ngx-scroll-to-first-invalid 。
腳步:
1.安裝模塊:
npm i @ismaestro/ngx-scroll-to-first-invalid --save
2. 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.在表單中使用指令:
<form [formGroup]="testForm" ngxScrollToFirstInvalid>
<input id="test-input1" type="text" formControlName="someText1">
<button (click)="saveForm()"></button>
</form>
希望能幫助到你! :)
純HTML解決方案。 如果您不需要滾動,只需關注第一個有效輸入,我使用:
public submitForm() {
if(this.form.valid){
// submit form
} else {
let invalidFields = [].slice.call(document.getElementsByClassName('ng-invalid'));
invalidFields[1].focus();
}
}
這是針對模板驅動的表單。 我們關注的是invalidFields的第二個元素,首先是整個形式也是無效的。
我建議把它放在一個服務中,對我來說它的工作原理如下:
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();
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.