如何使用angular8为循环项目的电子邮件和传真的每一行显示验证错误 [英] How to show validation error for each row for email and fax for loop items using angular8

查看:20
本文介绍了如何使用angular8为循环项目的电子邮件和传真的每一行显示验证错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有引导程序的 Angular8.我已经从循环数组中进行了输入.如果电子邮件或传真号码有任何验证错误,则抛出验证错误.然后,如果第一行中的电子邮件字段有错误,如果第二行中的传真有任何错误,则显示.如果在第 3 行,如果电子邮件输入不正确,然后更正,则第一行验证错误也会消失.

如果传真或电子邮件字段存在错误,我想显示所有行的验证错误.

HTML:

 <div *ngIf="(emailsubmitted && data.controls.recipients.errors)";class =无效反馈"><div *ngIf="(emailsubmitted && data.controls.recipients.errors)">请输入有效的电子邮件地址

<input type='text' prefix="+1 "面具="(000) 000-0000"类=表单控制"占位符=收件人"姓名=收件人"formControlName=收件人"*ngIf=data.value.deliveryMethodId == 179";maxLength=18"(focusout)="validationErrorOnFocusOut('fax',data)";自动完成=关闭"[ngClass]="{'is-invalid':faxsubmitted &&data.controls.recipients.errors.mask}><div *ngIf="faxsubmitted &&data.controls.recipients.errors.mask"class =无效反馈"><div *ngIf="faxsubmitted &&data.controls.recipients.errors.mask">请输入有效的传真号码

TS:

 public validationErrorOnFocusOut(name, data) {if (name == "emailvalid") {if (data.controls.recipients.status === "VALID") {this.emailsubmitted = false;} 别的 {this.emailsubmitted = true;}如果 (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;} 别的 {this.faxsubmitted = true;}如果 (data.controls.recipients.value === "";||data.controls.recipients.value === null){this.faxsubmitted = false;}}}

演示

您已使用 FormBuilder 正确设置了表单.我的解决方案将专注于表单的 Reactivity

以下是我采取的步骤

  1. 移除对 [disabled] 属性的绑定 https://stackoverflow.com/a/58831653/13680115如果您确实包含 [disabled] 属性
  2. ,则会在控制台中抛出警告

<预><代码>看起来您正在将 disabled 属性与响应式表单指令一起使用.如果您将禁用设置为 true当你在你的组件类中设置这个控件时,disabled 属性实际上会在 DOM 中设置为你.我们建议使用这种方法来避免检查后更改"错误.例子:表单 = 新表单组({第一:new FormControl({value: 'Nancy', disabled: true}, Validators.required),最后: new FormControl('Drew', Validators.required)});

  1. 删除 onChange 事件处理程序.取而代之的是我们的 ngOninit 函数.我们将观察表单值的变化并对此做出反应以禁用相应的控件

 this.printListControl.valueChanges.管道(distinctUntilChanged(),点击((控制:任何[])=> {control.forEach(({ mail, deliveryMethodId }, index) => {const control = this.printListControl.at(index);如果(邮件){control.get("deliveryMethodId").enable({emitEvent: false });control.get("recipients").enable({emitEvent: false });} 别的 {//为了更好的用户体验,我不会包括以下两行.控制.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);控制.get(收件人").setValidators(this.getRecipientsValidation(deliveryMethodId));});})).订阅();}getRecipientsValidation(deliveryMethodId) {返回 +deliveryMethodId === 178?[Validators.pattern(this.emailPattern), Validators.required]:+deliveryMethodId === 179?[Validators.minLength(10),(10),Validators.required]: [Validators.required];}

现在,每当 mail 值更改时,deliveryMethodIdrecipients 控件都会启用或禁用

我们还会根据选择的交付方式更新验证器

  1. 从 html 中删除模式验证.我们将使用 Validators.pattern

我们可以声明模式

emailPattern =/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;

  1. 从模板中移除 validationErrorOnFocusOut 的事件

  2. 由于我们移除了模板验证,我们可以使用 Validator 静态类

 let printList = this.printListArray.map(x => {const { deliveryMethodId } = x;返回 this.fb.group({id: x.id,名称:x.name,邮件:x.mail,电子:x.electronics,DeliveryMethodId: x.deliveryMethodId,收件人: [x.收件人,{验证器:DeliveryMethodId === 178?[Validators.pattern(this.emailPattern), Validators.required]: DeliveryMethodId === 179?[Validators.minLength(10),Validators.maxLength(10),Validators.required]: [Validators.required],更新:模糊"}]});});

我们对每个控件单独应用验证,以避免它们对其他控件的影响

  1. 最终我们的 html 将是这样的

<div [formGroupName]=j"><table class="table table-print table-borderless"><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

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

  1. 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

  1. 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})+$/;

  1. Remove the event for validationErrorOnFocusOut from the template

  2. 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

  1. 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屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆