I am building a component (html, css, spec.ts, ts) in angular in which I always want endDate > startDate. I have followed this link https://material.angular.io/components/datepicker/overview in order make multiple datepickers.
Below is my HTML for startDate and endDate:
startDate:
<div class="start-date" fxFlex="50%" fxFlexOrder="1">
<mat-form-field>
<input matInput [matDatepicker]="picker1" placeholder="{{'PORTAL.STARTDATE' | translate}}" type="text" formControlName="startDate" [(ngModel)]="unavailability.startDate" [readonly]="!componentPermission.writePermission">
<mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
<mat-datepicker #picker1></mat-datepicker>
</mat-form-field>
</div>
endDate:
<div class="end-date" fxFlex="50%" fxFlexOrder="2">
<mat-form-field>
<input matInput [matDatepicker]="picker2" placeholder="{{'PORTAL.ENDDATE' | translate}}" type="text" formControlName="endDate" [(ngModel)]="unavailability.endDate" [readonly]="!componentPermission.writePermission">
<mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle>
<mat-datepicker #picker2></mat-datepicker>
</mat-form-field>
</div>
Now below is my angular code (ts) where I am calling validateForm method on the page load.
ngOnInit() {
....
this.validateForm();
}
validateForm() {
this.unavailabilityForm = this.formBuilder.group({
'startDate': ['', Validators.required],
'endDate': ['', Validators.required],
'unavailabilityReason': ['']
});
}
ProblemStatement:
Now what I need to do is - if I have selected any date in startDate (for example 23rd Nov), then in the endDate datepicker all the dates before and including 23rd Nov should be disabled so that I can only select dates after 23rd Nov only. Is this possible to do in Angular?
Can we achieve that by placing minDate and maxDate somewhere in HTML or TS ?
Binding with [min] works perfect for any date
.ts file
//today's date
todayDate:Date = new Date();
//any date
someDate: Date = new Date(anydate);
.html file
<mat-form-field>
<input matInput [matDatepicker]="picker" [min]="todayDate" placeholder="Appointment date" formControlName="appointment_date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Since you are using a reactive form, utilize the form controls. It's not recommended to have two bindings (ngModel and formControl). So drop the ngModel like I suggested in a previous question of yours: https://stackoverflow.com/a/47426879/6294072
So populate your form controls with the values of from your object unavailability.
constructor(private formBuilder: FormBuilder) {
this.unavailabilityForm = this.formBuilder.group({
startDate: [this.unavailability.startDate],
endDate: [this.unavailability.endDate]
});
}
if you are receiving the values at a later point you can use patchValues:
this.unavailabilityForm.setValue({
startDate: this.unavailability.startDate;
endDate: this.unavailability.endDate;
})
else you can set the values when you build the form.
Then the only thing you need to add to your second datepicker is [min] like the other answer mentioned. There utilize the form control value:
<input matInput
[min]="unavailabilityForm.controls.startDate.value"
formControlName="endDate" ...>
DEMO
Unless I'm missing something, you can use the [min]="" date property:
<div class="item item-2" fxFlex="50%" fxFlexOrder="2">
<mat-form-field>
<input matInput [min]="startDate" [matDatepicker]="picker2" placeholder="{{'PORTAL.ENDDATE' | translate}}" type="text" formControlName="endDate" [(ngModel)]="unavailability.endDate" [readonly]="!componentPermission.writePermission">
<mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle>
<mat-datepicker #picker2></mat-datepicker>
</mat-form-field>
</div>
Whatever startDate is will limit the Calendar dates available for endDate. If you need it set before startDate is chosen, use another variable and set it in consturctor() or ngOnInit() of your component.
See: https://material.angular.io/components/datepicker/overview#date-validation
Using the valueChanges of Angular reactive forms and Min feature here is a complete working solution with validation and reactive forms
you can also see the image that the publishedTo only accepts values greater than or equal to any values you set on the PublisedFrom
components.ts
export class AnnouncementformComponent implements OnInit {
constructor(private _formBuilder: FormBuilder){}
Announcementform: FormGroup;
minDate:Date;
this.Announcementform = this._formBuilder.group({
PublishedFrom: ['', Validators.required],
PublishedTo: ['', Validators.required],
});
this.Announcementform.valueChanges.subscribe(res=>{
this.minDate = new Date(res.PublishedFrom);
});
component.html
<mat-form-field appearance="outline">
<input matInput [matDatepicker]="PublishedFrom" placeholder="Publish FROM *"
formControlName="PublishedFrom">
<mat-label>Publish FROM *</mat-label>
<mat-datepicker-toggle matSuffix [for]="PublishedFrom"></mat-datepicker-toggle>
<mat-datepicker #PublishedFrom></mat-datepicker>
</mat-form-field>
<mat-form-field appearance="outline">
<input matInput [matDatepicker]="PublishedTo" placeholder="Publish To *"
formControlName="PublishedTo" [min]="minDate">
<mat-label>Publish TO *</mat-label>
<mat-datepicker-toggle matSuffix [for]="PublishedTo"></mat-datepicker-toggle>
<mat-datepicker #PublishedTo></mat-datepicker>
</mat-form-field>
I am also writing additional code below if someone needs to start his date from a specific date or greater or equal to current date can use simple line of code below
1- create a variable in your component class name it for example startDate
startDate:Date;
ngOnInit() {
//---This will set the datepicker to accept values from current date or above---//
//--- you can also customize the value to set any date you want----//
this.startDate= new Date();
}
then in your component.html file
<mat-form-field appearance="outline">
<input matInput [matDatepicker]="publishdate" placeholder="Publish Date *"
formControlName="publishdate" [min]="startDate">
<mat-datepicker-toggle matSuffix [for]="publishdate"></mat-datepicker-toggle>
<mat-datepicker #publishdate></mat-datepicker>
</mat-form-field>
I used [min]="startDate.value" and worked like expected (disabled endDate calendar previous dates from selected date in startDate Calendar)
Latest version accept minDate and maxDate as Properties
https://material.angular.io/components/datepicker/api
<mat-calendar [minDate]="theDateYouWant"></mat-calendar>
<mat-form-field >
<input placeholder="Enter Date" matInput
[matDatepicker]="picker1"
formControlName="voucherExpirationDate"
[min]="minDate">
<mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
<mat-datepicker #picker1></mat-datepicker>
</mat-form-field>
first date
<mat-form-field appearance="outline" class="w-100">
<mat-label>1st installment date</mat-label>
<input matInput [matDatepicker]="firstDate (focus)="firstDate.open()"
placeholder="Select 1st installment date"
formControlName="fstInstalmentDate" readonly required>
<mat-datepicker-toggle matSuffix [for]="firstDate"></mat-datepicker-toggle>
<mat-datepicker #firstDate></mat-datepicker>
</mat-form-field>
2nd date
<mat-form-field appearance="outline" class="w-100">
<mat-label>2nd installment date</mat-label>
<input matInput [matDatepicker]="secondDate" (focus)="secondDate.open()"
placeholder="Select 2nd installment date"
[min]="settingForm?.get('fstInstalmentDate')?.value"
formControlName="scndInstalmentDate" readonly required>
<mat-datepicker-toggle matSuffix [for]="secondDate"></mat-datepicker-toggle>
<mat-datepicker #secondDate></mat-datepicker>
</mat-form-field>
Here settingForm is my formgroup name, Just one line change in second date no need to write anything in .ts file
//today's date in your component.ts file declare varaible which stores present //date
presentDate:Date = new Date();
//and in component.html write [min]= "presentDate" in input of type date
<input matInput [matDatepicker]="picker" [min]="presentDate" placeholder="Appointment date" formControlName="appointment_date">
<mat-datepicker-toggle matSuffix [for]="picker">
<mat-datepicker #picker>
Related
I'm trying to use the Datepicker feature of Angular Material and got this error inside the "div" I created. "Error: A MatDatepicker can only be associated with a single input." After getting this error, I saw that when I select the dates, I cannot affect the following. I was only able to change the date area above.
You can see the feature I'm trying to use here:
calendar
Here is my HTML code:
<div class="col-2">
<mat-form-field appearance="outline" class="margin-0">
<mat-label>{{ "PROD_REPORT.FROM" | translate }}</mat-label>
<input matInput [matDatepicker]="picker" [(ngModel)]="start_time" />
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<mat-form-field appearance="outline" class="margin-0">
<mat-label>{{ "PROD_REPORT.TO" | translate }}</mat-label>
<input matInput [matDatepicker]="picker" [(ngModel)]="end_time" />
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</div>
I am facing the same issue, Actually when you use Angular material date picker multiple fields in the same form, then you should use #picker name should be different.
<div class="col-2">
<mat-form-field appearance="outline" class="margin-0">
<mat-label>{{ "PROD_REPORT.FROM" | translate }}</mat-label>
<input matInput [matDatepicker]="picker" [(ngModel)]="start_time" />
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<mat-form-field appearance="outline" class="margin-0">
<mat-label>{{ "PROD_REPORT.TO" | translate }}</mat-label>
<input matInput [matDatepicker]="picker_another" [(ngModel)]="end_time" />
<mat-datepicker-toggle matSuffix [for]="picker_another"></mat-datepicker-toggle>
<mat-datepicker #picker_another></mat-datepicker>
</mat-form-field>
</div>
I have two datepickers picker1 and picker2. What I am trying to to is that when I select a date in picker1 the picker2 should automatically get selected and the date in the picker2 should be 60 days from date in picker1
For example if its march 1 2021 in picker1 It should be april 29 2021 in picker2
I have searched for various solutions in stackoverflow but couldn't get the exact solution.
Pleease help if u guys know
Datepicker1:
<td>
<mat-form-field >
<input matInput readonly [matDatepicker]="picker1" formControlName="startdate"
(dateChange)="setDate($event.value)"placeholder="Start Date">
<mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
<mat-datepicker #picker1></mat-datepicker>
</mat-form-field>
</td>
Datepicker2
<td>
<mat-form-field>
<input matInput readonly [matDatepicker]="picker2" formControlName="enddate"
placeholder="End Date">
<mat-datepicker-toggle matSuffix [for]="picker2"></mat-datepicker-toggle>
<mat-datepicker #picker2></mat-datepicker>
</mat-form-field>
</td>
My ts
setDate(a) {
this.datecheck = this.eventaddform.value.startdate+60
this.eventaddform.patchValue({
expirydate: this.datecheck
})
}
I have created a sample stackblitz justincase if u guys need something to work with
Stackblitz: https://stackblitz.com/edit/angular-date-picker-sample-fr-h19bes?file=app%2Fapp.component.html
Use dateChange event from picker1 to set picker2 by binding value
I've created a basic stackblitz example removing Forms
DEMO
PS: adding 60 to March 01 2021 gave me April 30 2021. So you can try adding 59
I have a question concerning angular reactive form. When I want to set default values for my form controls it does not work in the HTML.
TS:
// set form controls
this.DataService.TabArchivForm = this.fb.group({
ArchiveControl: [true],
DateChannelControl: [Date.now(), Validators.required]
});
HTML:
<div class="tab_main" [formGroup]="this.DataService.TabArchivForm">
<mat-form-field class="field_width">
<mat-label class="Inputlabel">Date</mat-label>
<input class="Inputvalue" matInput id="date" [formControl]="this.DataService.TabArchivForm.controls.DateChannelControl" [matDatepicker]="dp3" required>
<mat-datepicker-toggle matSuffix [for]="dp3"></mat-datepicker-toggle>
<mat-datepicker #dp3 disabled="false"></mat-datepicker>
<mat-error *ngIf="this.DataService.TabArchivForm.controls.DateChannelControl.invalid">{{getErrorMessage()}}</mat-error>
</mat-form-field>
<mat-checkbox color="primary" [formControl]="this.DataService.TabArchivForm.controls.ArchivControl" id="archive">Archive</mat-checkbox>
</div>
I don't know why it does not set the default values for the HTML elements. The checkbox is unchecked and the input field from the date picker is empty as well. Am I missing something?
Thanks for answers!
I am trying bind data from a datepicker to a variable such that it can be readily used in Typescript. Any ideas on this problem would be much appreciated
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker #picker></mat-datepicker>
Select Date
MatDatePicker's contents need to be enclosed in a <mat-form-field>. See the following example from the Angular Material documentation.
<mat-form-field>
<mat-label>Choose a date</mat-label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
You can use this event dateChange or dateInput on the input tag that you can use in your ts file :
<input matInput [matDatepicker]="picker"
(dateInput)="addEvent( $event)" (dateChange)="addEvent( $event)">
I use matte DatePicker for input and output date selection. [MatDatepicker] = It works when I type "Selector". When you give someone a different name, only [matDatepicker] = "selector" works and the other gives an error. How can I fix?
<mat-form-field>
<label>Entry Date?</label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<mat-form-field>
<label>Pay Date?</label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Your question is unclear but it sounds like you are wanting to have two date pickers but are struggling since you need to provide a different name for [matDatePicker]. Your picker value needs to match your binding on the <mat-datepicker>
Example:
<mat-form-field>
<label>Entry Date?</label>
<input matInput [matDatepicker]="startDate">
<mat-datepicker-toggle matSuffix [for]="startDate"></mat-datepicker-toggle>
<mat-datepicker #startDate></mat-datepicker>
</mat-form-field>
<mat-form-field>
<label>Pay Date?</label>
<input matInput [matDatepicker]="endDate">
<mat-datepicker-toggle matSuffix [for]="endDate"></mat-datepicker-toggle>
<mat-datepicker #endDate></mat-datepicker>
</mat-form-field>
Here's a stackblitz: https://stackblitz.com/angular/lyeebaxdmyd