简体   繁体   English

如何根据其他两个 Datepicker 字段在 Datepicker 字段上设置 Min 和 Max 值 - Angular Material

[英]How do I set Min and Max values on a Datepicker field based on two other Datepicker fields - Angular Material

I have 3 date picker fields, contractPeriodFrom, contractPeriodTo and dateOfAppointment.我有 3 个日期选择器字段,contractPeriodFrom、contractPeriodTo 和 dateOfAppointment。 The dateOfAppointment should be between the contractPeriodFrom and contractPeriodTo. dateOfAppointment 应该在contractPeriodFrom 和contractPeriodTo 之间。 I am unsure how to do this as both contractPeriod fields are form controls.我不确定如何执行此操作,因为两个 contractPeriod 字段都是表单控件。

        <div fxLayout="row">
            <mat-form-field fxFlex="50">
                <input matInput [matDatepicker]="picker2" formControlName="contractPeriodFrom" readonly>
                <mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle>
                <mat-datepicker #picker2></mat-datepicker> 
            </mat-form-field>
            <mat-form-field fxFlex="50">
                <input matInput [matDatepicker]="picker3" formControlName="contractPeriodTo" readonly>
                <mat-datepicker-toggle matSuffix [for]="picker3"></mat-datepicker-toggle>
                <mat-datepicker #picker3></mat-datepicker> 
            </mat-form-field>
        </div>
        <div fxLayout="row" class="mt-16">
            <mat-form-field fxFlex="50">
                <input matInput [matDatepicker]="picker1" formControlName="dateOfAppointment" readonly>
                <mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
                <mat-datepicker #picker1></mat-datepicker> 
            </mat-form-field>
        </div>

The form fields are part of a form group and initialized as below -表单域是表单组的一部分,初始化如下 -

    this.lieUpdateForm = this._formBuilder.group({
        dateOfAppointment: [this.selectedLIE.dateOfAppointment || ''],
        contractPeriodFrom: [this.selectedLIE.contractPeriodFrom || ''],
        contractPeriodTo: [this.selectedLIE.contractPeriodTo || ''],
    }); 

Have a look here https://material.angular.io/components/datepicker/overview#date-validation .看看这里https://material.angular.io/components/datepicker/overview#date-validation There are two solutions min/max or matDatepickerFilter .有两种解决方案min/maxmatDatepickerFilter I would suggest you to use the matDatepickerFilter one, being cleaner, more flexible and not requiring subscriptions to valueChanges .我建议您使用matDatepickerFilter之一,它更干净、更灵活,并且不需要订阅valueChanges

matDatepickerFilter

Add the [matDatepickerFilter] binding to the input:[matDatepickerFilter]绑定添加到输入:

<input matInput
       [matDatepicker]="picker1"
       formControlName="dateOfAppointment" readonly
       [matDatepickerFilter]="dateFilter"
>

Then add a validation function to your component (note that is a lambda and not a member function, read more here MatDatepickerFilter - Filter function can't access class variable ) Then add a validation function to your component (note that is a lambda and not a member function, read more here MatDatepickerFilter - Filter function can't access class variable )

public dateFilter = (d: Date): boolean => {
  const value = this.lieUpdateForm.value;
  return (d >= this.toDate(value.contractPeriodFrom)) && (d <= this.toDate(value.contractPeriodTo));
}

min/max

Add the [min] and [max] binding to the input:[min][max]绑定添加到输入:

<input matInput
       [matDatepicker]="picker1"
       formControlName="dateOfAppointment" readonly
       [min]="minDate" [max]="maxDate"
>

Then after right after assigning lieUpdateForm add:然后在分配lieUpdateForm之后添加:

this._subscription = this.lieUpdateForm
  .valueChanges.subscribe(value => {
  this.minDate = toDate(value.contractPeriodFrom);
  this.maxDate = toDate(value.contractPeriodTo);
});

Do not forget to clear _subscription onDestroy不要忘记清除_subscription onDestroy

toDate

toDate is a function that makes sure we are dealing with Date objects. toDate是一个 function 确保我们正在处理 Date 对象。 According to the documentation it should work just fine without it.根据文档,没有它它应该可以正常工作。 I added it just in case.我添加它以防万一。 This is the implementation if needed:如果需要,这是实现:

protected toDate(d: Date | string): Date {
  return (typeof d === 'string') ? new Date(d) : d;
}
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="picker" placeholder="Choose a date">

Then you can set the Value for maxDate and minDate in ts file然后您可以在 ts 文件中设置 maxDate 和 minDate 的值

this.lieUpdateForm.get("dateOfAppointment").valueChanges.subscribe(selectedValue => {
  console.log('dateOfAppointment value changed')
  console.log(selectedValue)                              //latest value of dateOfAppointment
  console.log(this.lieUpdateForm.get("dateOfAppointment").value)   //latest value of dateOfAppointment
})

The accepted answer has one flaw though, when using matDateFilter the performance is affected badly.但是,接受的答案有一个缺陷,当使用 matDateFilter 时,性能会受到严重影响。 I know the logic in filterFunction is written in such as way that it must be executed minimum times but what if first date isn't provided and user want to make year disabled when false is returned looks like it recursively check for internal dates as well which makes it to get executed lots of times我知道 filterFunction 中的逻辑是这样编写的,它必须执行最少的时间,但是如果没有提供第一个日期并且用户想要在返回 false 时禁用年份看起来像它递归地检查内部日期以及哪个让它被执行很多次

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM