【问题标题】:Angular - StartDate and EndDate comparison validator not displaying error messageAngular - StartDate 和 EndDate 比较验证器不显示错误消息
【发布时间】:2023-02-03 06:54:15
【问题描述】:

在 Angular-14 项目中,我在 ngx-bootstrap 中使用 BsDatepickerModule datepicker 实现 Datepicker。我必须验证 StartDate 不应大于 EndDate,并且我不想使用 DateRange 选择器,所以我分别有 StartDate 和 EndDate。

日期比较 validator.ts:

import { AbstractControl, ValidationErrors, Validators } from '@angular/forms';

export function DateComparisonValidator(dateCompareControlName: string) {

    let thisDateControl: AbstractControl;
    let otherDateControl: AbstractControl;

    return function DateComparisonValidator(control: AbstractControl): ValidationErrors | null {
        if (!control.parent) {
            return null;
        }
        if (!thisDateControl) {
            thisDateControl = control;
            otherDateControl = control.parent.get(dateCompareControlName) as AbstractControl;
            if (!otherDateControl) {
                throw new Error('dateLessThanOrEqualsValidator(): other control is not found in parent group');
            }
            otherDateControl.valueChanges.subscribe(() => {
                thisDateControl.updateValueAndValidity();
            });
        }
        if (!otherDateControl || !otherDateControl.value) {
            return null;
        }
        const date1 = thisDateControl.value;
        const date2 = otherDateControl.value;
        if (date1 !== null && date2 !== null && date1 > date2) {
            return {
                'date_less_than_or_equal': true
            };
        }
        return null;
    };
}

然后是 component.ts:

import { DateComparisonValidator } from 'src/app/shared/validators/date-comparison-validator';


  createTransactionForm = this.fb.group({
      startDate: ['', [Validators.required, DateComparisonValidator('endDate')]],
      endDate: ['', [Validators.required]]
    });
  }

  ngOnInit(): void {
    this.createTransaction();
  }

  createValidate() {
    if (!this.createTransactionForm.valid) {
      this.createTransactionForm.markAllAsTouched();
      return;
    }
  }
  get fc() {
    return this.createTransactionForm.controls;
  };

组件.html:

<div class="row">
  <div class="col-md-6">
    <div class="form-group">
      <label for="startDate">Start Date</label>
      <div class="input-group">
        <div class="input-group-prepend">
          <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
        </div>
        <input type="text"
        placeholder="DD-MM-YYYY"
        class="form-control"
        formControlName='startDate'
        bsDatepicker
        [minDate]="minStartDate"
        [bsConfig]="{ isAnimated: true, dateInputFormat: 'DD-MM-YYYY', returnFocusToInput: true, showClearButton: true, clearPosition: 'right' }">
      </div>
      <div *ngIf="fc['startDate'].touched && fc['startDate'].invalid" class="alert alert-danger">
        <div *ngIf="fc['startDate'].errors && fc['startDate'].errors['required']">Start Date field is required!</div>
        <div *ngIf="fc['startDate'].errors && fc['startDate'].errors['DateComparisonValidator']">Start Date must be less than End Date!</div>
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <div class="form-group">
      <label for="endDate">End Date<span style="color:red;">*</span></label>
      <div class="input-group">
        <div class="input-group-prepend">
          <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
        </div>
        <input type="text"
        placeholder="DD-MM-YYYY"
        class="form-control"
        formControlName='endDate'
        bsDatepicker
        [minDate]="minEndDate"
        [bsConfig]="{ isAnimated: true, dateInputFormat: 'DD-MM-YYYY', returnFocusToInput: true, showClearButton: true, clearPosition: 'right' }">
      </div>
      <div *ngIf="fc['endDate'].touched && fc['endDate'].invalid" class="alert alert-danger">
        <div *ngIf="fc['endDate'].errors && fc['endDate'].errors['required']">End Date field is required!</div>
      </div>
    </div>
  </div>
</div>
关闭 提交

当 StartDate 大于 EndDate 时,我希望看到此消息。但是没有显示任何消息。

我该如何解决这个问题?

谢谢

【问题讨论】:

  • 请与已复制的问题分享 stackblitz!和需要输出的屏幕截图!

标签: angular ngx-bootstrap


【解决方案1】:

交叉控件验证器应该设置在表单上,​​而不是控件上。这是因为控件将更新父组,但不会更新其兄弟控件,而组将更新其所有子控件。

  createTransactionForm = this.fb.group({
      startDate: ['', [Validators.required]],
      endDate: ['', [Validators.required]]
    }, { validators: [DateComparisonValidator('endDate')] });
  }

当然,相应地更新您的验证器。

【讨论】:

  • 无需将控件名称传递给验证器工厂 DateComparisonValidator()。验证器将在控件的值更改时接收 FormGroup。
  • @EdmundsFolkmanis 这不是这里的问题,但你错了一部分:如果你不传递控件的名称,那么验证器只能用于这个特定的表单组。如果他想重新使用它,那么他将不得不复制代码。所以你同时是对也是错,这取决于他试图达到的目标!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 2019-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
相关资源
最近更新 更多