<tr><td scope="row";class=width90">{{data.value.name}}<td class="width50"><输入类型=复选框"名称=邮件"formControlName=邮件"/></td><td class="width50"><输入类型=复选框"名称=电子产品"formControlName=电子"/></td><td class="width100"><选择类=自定义选择"formControlName="deliveryMethodId";name="deliveryMethodId";tabindex=1"(change)="dropdownSelection(j)";><option value=null>选择一个</option><选项*ngFor=让代理商Type of DeliveryMethod";[值]=agencyType.id";>{{agencyType.label}}</option></选择></td><td class="width200"><ng-container *ngIf=data.value.deliveryMethodId == 178"><输入类型=文本"类=表单控制"占位符=电子邮件"姓名=收件人"formControlName=收件人"*ngIf=data.value.deliveryMethodId == 178";[ngClass]="{'is-invalid': data.get('recipients').invalid &&data.get('recipients').touched }";自动完成=关闭"><div class='invalid-feedback' *ngIf="data.get('recipients').invalid">请输入有效的电子邮件</ng-容器><ng-container *ngIf="data.value.deliveryMethodId == 179"><输入类型=文本"前缀=+1"类=表单控制"占位符=(###)### - ####";formControlName=收件人"姓名=收件人"自动完成=关闭"*ngIf=data.value.deliveryMethodId == 179";面具="(000) 000-0000"[showMaskTyped]=假";[ngClass]="{'is-invalid': data.get('recipients').invalid &&data.get('recipients').touched }";><div class='invalid-feedback'>请输入有效的传真号码
</ng-容器><ng-container *ngIf="data.value.deliveryMethodId != '178' &&data.value.deliveryMethodId !='179'><输入类型=文本"类=表单控制"占位符=收件人"姓名=收件人"[ngClass]="{'is-invalid': data.get('recipients').invalid &&data.get('recipients').touched }";formControlName=收件人"/><div class='invalid-feedback'>字段为必填项
</ng-容器></td></tr></tbody>
此处演示>
I am using Angular8 with bootstrap. I have made inputs from a loop array. If there is any validation error for email or fax number, it is throwing validation error. Then, if there is an error for the email field in the first row, if there is any error for fax in second row it shows. if in the 3rd row if email is entered incorrectly and then corrected, the first row validation error also goes off.
I want to show validation error for all rows of there is an error with respect to fax or email fields.
HTML:
<input type="text" class="form-control" placeholder="Email" name="Recepient"
formControlName="recipients" *ngIf="data.value.deliveryMethodId == 178"
(focusout)="validationErrorOnFocusOut('emailvalid',data)"
[ngClass]="{ 'is-invalid': emailsubmitted && data.controls.recipients.errors}"
pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$" autocomplete="off">
<div *ngIf="(emailsubmitted && data.controls.recipients.errors)" class="invalid-feedback">
<div *ngIf="(emailsubmitted && data.controls.recipients.errors)">
Please enter valid email</div>
</div>
<input type='text' prefix="+1 " mask=" (000) 000-0000" class="form-control"
placeholder="Recepient" name="Recepient" formControlName="recipients"
*ngIf="data.value.deliveryMethodId == 179" maxLength="18"
(focusout)="validationErrorOnFocusOut('fax',data)"
autocomplete="off"
[ngClass]="{ 'is-invalid':faxsubmitted && data.controls.recipients.errors.mask}">
<div *ngIf="faxsubmitted && data.controls.recipients.errors.mask" class="invalid-feedback">
<div *ngIf="faxsubmitted && data.controls.recipients.errors.mask">Please enter valid fax number
</div>
</div>
TS:
public validationErrorOnFocusOut(name, data) {
if (name == "emailvalid") {
if (data.controls.recipients.status === "VALID") {
this.emailsubmitted = false;
} else {
this.emailsubmitted = true;
}
if (
data.controls.recipients.value === "" ||
data.controls.recipients.value === null
) {
this.emailsubmitted = false;
}
} else if (name == "fax") {
if (data.controls.recipients.status === "VALID") {
this.faxsubmitted = false;
} else {
this.faxsubmitted = true;
}
if (
data.controls.recipients.value === "" ||
data.controls.recipients.value === null
) {
this.faxsubmitted = false;
}
}
}
DEMO
解决方案
You have set up your form correctly using the FormBuilder
. My Solution will focus on the Reactivity
of your form
Below are the steps I have taken
- Remove the binding on
[disabled]
property https://stackoverflow.com/a/58831653/13680115
Below is a warning in the console thrown if you do include [disabled]
property
It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
you. We recommend using this approach to avoid 'changed after checked' errors.
Example:
form = new FormGroup({
first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
last: new FormControl('Drew', Validators.required)
});
- Remove the
onChange
event handler. In its place we will have below in our ngOninit
function. We will watch for form valuechanges and react to this to disable the appropriate control
this.printListControl.valueChanges
.pipe(
distinctUntilChanged(),
tap((controls: any[]) => {
controls.forEach(({ mail, deliveryMethodId }, index) => {
const control = this.printListControl.at(index);
if (mail) {
control.get("deliveryMethodId").enable({ emitEvent: false });
control.get("recipients").enable({ emitEvent: false });
} else {
// I would not include below two lines for better user experience.
control
.get("deliveryMethodId")
.setValue(null, { emitEvent: false });
control.get("recipients").setValue(null, { emitEvent: false });
control.get("deliveryMethodId").disable({ emitEvent: false });
control.get("recipients").disable({ emitEvent: false });
}
// console.log(deliveryMethodId);
control
.get("recipients")
.setValidators(this.getRecipientsValidation(deliveryMethodId));
});
})
)
.subscribe();
}
getRecipientsValidation(deliveryMethodId) {
return +deliveryMethodId === 178
? [Validators.pattern(this.emailPattern), Validators.required]
: +deliveryMethodId === 179
? [
Validators.minLength(10),
(10),
Validators.required
]
: [Validators.required];
}
Now whenever the mail
value is changed the deliveryMethodId
and recipients
control are enabled or disabled
Also we update the validators based on the delivery method selected
- Remove the pattern validations from the html. We will use
Validators.pattern
We can declare the patterns
emailPattern = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
Remove the event for validationErrorOnFocusOut
from the template
Since we have removed the template validation, we can employ the use of Validator
static classes
let printList = this.printListArray.map(x => {
const { deliveryMethodId } = x;
return this.fb.group({
id: x.id,
name: x.name,
mail: x.mail,
electronics: x.electronics,
deliveryMethodId: x.deliveryMethodId,
recipients: [
x.recipients,
{
validators:
deliveryMethodId === 178
? [Validators.pattern(this.emailPattern), Validators.required]
: deliveryMethodId === 179
? [
Validators.minLength(10),
Validators.maxLength(10),
Validators.required
]
: [Validators.required],
updateOn: "blur"
}
]
});
});
We are applying validation to each control individally to avoid their effect on other controls
- Finally our html will be something like this
<div class="custom-control custom-checkbox"
*ngFor="let data of exampleForm.get('printList').controls; let j = index" formArrayName="printList">
<div [formGroupName]="j">
<table class="table table-print table-borderless">
<tbody>
<tr>
<td scope="row" class="width90">{{data.value.name}}</td>
<td class="width50">
<input
type="checkbox"
name="mail"
formControlName="mail"
/>
</td>
<td class="width50">
<input
type="checkbox"
name="electronics"
formControlName="electronics"
/>
</td>
<td class="width100">
<select
class="custom-select"
formControlName="deliveryMethodId"
name="deliveryMethodId"
tabindex="1" (change)="dropdownSelection(j)"
>
<option value=null>Select One </option>
<option
*ngFor="let agencyType of DeliveryMethod"
[value]="agencyType.id"
>
{{agencyType.label}}</option
>
</select>
</td>
<td class="width200">
<ng-container *ngIf="data.value.deliveryMethodId == 178">
<input type="text" class="form-control" placeholder="Email" name="Recepient"
formControlName="recipients" *ngIf="data.value.deliveryMethodId == 178"
[ngClass]="{ 'is-invalid': data.get('recipients').invalid && data.get('recipients').touched }"
autocomplete="off">
<div class='invalid-feedback' *ngIf="data.get('recipients').invalid">
Please enter valid email
</div>
</ng-container>
<ng-container *ngIf="data.value.deliveryMethodId == 179">
<input type="text" prefix="+1 " class="form-control" placeholder="(###) ### - ####"
formControlName="recipients" name="recipients" autocomplete="off"
*ngIf="data.value.deliveryMethodId == 179"
mask=" (000) 000-0000" [showMaskTyped]="false"
[ngClass]="{ 'is-invalid' : data.get('recipients').invalid && data.get('recipients').touched }" >
<div class='invalid-feedback'>
Please enter valid fax number
</div>
</ng-container>
<ng-container *ngIf="data.value.deliveryMethodId != '178' && data.value.deliveryMethodId != '179'">
<input type="text" class="form-control" placeholder="Recepient" name="Recepient"
[ngClass]="{ 'is-invalid' : data.get('recipients').invalid && data.get('recipients').touched }"
formControlName="recipients"
/>
<div class='invalid-feedback'>
Field is required
</div>
</ng-container>
</td>
</tr>
</tbody>
</table>
</div>
</div>
DEMO HERE
这篇关于如何使用angular8为循环项目的电子邮件和传真的每一行显示验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文