簡體   English   中英

如何顯示 email 的每一行的驗證錯誤和使用 angular8 的循環項目的傳真

[英]How to show validation error for each row for email and fax for loop items using angular8

我正在使用帶有引導程序的 Angular8。 我已經從循環數組中輸入了。 如果 email 或傳真號碼有任何驗證錯誤,則拋出驗證錯誤。 然后,如果第一行的 email 字段有錯誤,如果第二行的傳真有任何錯誤,則會顯示。 如果在第 3 行中,如果 email 輸入錯誤然后更正,則第一行驗證錯誤也會消失。

我想顯示關於傳真或 email 字段的錯誤的所有行的驗證錯誤。

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;
      }
    }
  }

演示

您已經使用FormBuilder正確設置了表單。 我的解決方案將專注於表單的Reactivity

以下是我采取的步驟

  1. 刪除[disabled]屬性https://stackoverflow.com/a/58831653/13680115上的綁定如果您包含[disabled]屬性,以下是控制台中的警告

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. 刪除onChange事件處理程序。 取而代之的是我們的ngOninit function。 我們將觀察表單值的變化並對此做出反應以禁用適當的控件
      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];
  }

現在,無論何時更改mail值,都會啟用或禁用deliveryMethodIdrecipients控件

我們還根據選擇的交付方式更新驗證器

  1. 從 html 中刪除模式驗證。 我們將使用Validators.pattern

我們可以聲明模式

emailPattern = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
  1. 從模板中移除validationErrorOnFocusOut的事件

  2. 由於我們刪除了模板驗證,我們可以使用Validator static 類

    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"
          }
        ]
      });
    });

我們分別對每個控件應用驗證,以避免它們對其他控件的影響

  1. 最后我們的 html 將是這樣的
<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>

在這里演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM