fir*_*baa 7 javascript html5 rxjs angular angular-reactive-forms
在Angular 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>
Run Code Online (Sandbox Code Playgroud)
在我的TS文件下,我的表单配置如下所示:
this.addItemfForm = this.formBuilder.group({
libellePef: ['', Validators.required],
codeBasicat: ['', Validators.required ],
nomApplication: ['', Validators.required ],
urlCible: [''],
modeTransfert: [''],
});
Run Code Online (Sandbox Code Playgroud)
我已经尝试过自动对焦指令,但这没有用
有什么建议吗?
小智 21
在您的提交中使用以下代码。
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;
}
}
Run Code Online (Sandbox Code Playgroud)
this.addressForm 将是您的 FormGroup。
我们甚至不需要这里的指令。
我的答案的灵感来自yurzui的答案。我正在使用他的回答中的逻辑来通过使用来获取nativeElement特定FormControl内容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;
};
Run Code Online (Sandbox Code Playgroud)
现在,即使表单的错误字段无效,该字段也将为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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我故意使用for而不是Array.forEach因为我想摆脱循环。
希望这可以为您解决问题。
这是供您参考的工作样本StackBlitz。
我使用指令做到了这一点。所以我的表格看起来像这样:
<form [formGroup]="userForm" (submit)="saveData()" appFocus >
...
</form>
Run Code Online (Sandbox Code Playgroud)
以及指令本身的代码:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这个解决方案并不完整,因为必须考虑很多极端情况。例如,如果第一个元素是单选按钮组怎么办?调度焦点事件会自动标记该字段。其次,并非 Angular ads ng-invalid 的每个元素都将成为输入。