Hey everybody,
I have in my form a starting date and a ending date. I set the starting date as the minDate of the ending date field and the ending date as the maxDate of the starting date.
But the binding doesn't work well : for the ending date I could select a date before the starting date and for the starting date I could select a date that is after the ending date.
It seems that both minDate and maxDate are not updated if and only if I changed the month and come back to actual month.
I built a custom calendar component that includes all primeng calendar options.
my-calendar.component.html:
<div [formGroup]="calendarForm">
<p-calendar #pcalendar
[(ngModel)]="date"
formControlName="calendar"
[minDate]="minDate"
[maxDate]="maxDate"
[locale]="fr"
dateFormat="dd/mm/yy"
[monthNavigator]="true" [yearNavigator]="true"
yearRange="2000:2030"
inputStyleClass="form-control input-sm"
(onBlur)="onBlur($event)"
(onSelect)="onSelect($event)">
</p-calendar>
</div>
my-calendar.component:
`import { Component, Input, Output, EventEmitter, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { Calendar } from 'primeng/primeng';
import * as moment from 'moment';
@Component({
selector: 'sig-calendar',
templateUrl: './my-calendar.component.html'
})
export class MyCalendarComponent implements OnInit {
@ViewChild('pcalendar') pcalendar: Calendar;
private fr: any;
@Output() minDateChange: EventEmitter<Date> = new EventEmitter<Date>();
@Output() maxDateChange: EventEmitter<Date> = new EventEmitter<Date>();
@Output() dateChange: EventEmitter<Date> = new EventEmitter<Date>();
@Input() date: Date = null;
@Input() minDate: Date = null;
@Input() maxDate: Date = null;
@Input() controlChange: EventEmitter<FormControl> = new EventEmitter<FormControl>();
@Input() control: FormControl = null;
calendarForm: FormGroup;
constructor() { }
ngOnInit() {
this.fr = {
firstDay: 1,
monthNames: [
'janvier', 'février', 'mars',
'avril', 'mai', 'juin',
'juillet', 'août', 'septembre',
'octobre', 'novembre', 'décembre'
],
monthNamesShort: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin',
'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
dayNames: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
dayNamesShort: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
dayNamesMin: ['D', 'L', 'M', 'M', 'J', 'V', 'S']
};
this.calendarForm = new FormGroup({});
if (this.control) {
this.calendarForm.addControl('calendar', this.control);
}
}
emitChanges() {
if (this.minDate) {
this.minDateChange.emit(this.minDate);
}
if (this.maxDate) {
this.maxDateChange.emit(this.maxDate);
}
this.dateChange.emit(this.date);
this.emitControlChanges();
}
emitControlChanges() {
if (this.control) {
this.control.setValue(this.date);
this.control.markAsDirty();
this.control.markAsTouched();
if (this.date === null) {
this.control.setErrors({key: 'required'}, {emitEvent: true});
}
this.control.updateValueAndValidity();
this.controlChange.emit(this.control);
}
}
onBlur(event) {
let newDate: Date = this.strToDate(event.target.value);
this.date = newDate;
let newValue: string = this.dateToStr(newDate);
event.target.value = newValue;
this.emitChanges();
}
onSelect(event) {
let newDate = this.strToDate(event);
this.date = newDate;
this.emitChanges();
}
strToDate(newDateString: string): Date {
if (newDateString) {
let mom: moment.Moment = moment(newDateString, 'DD/MM/YYYY');
if (mom.isValid()) {
return mom.toDate();
}
}
return null;
}
dateToStr(newDate: Date, format?: string): string {
if (newDate && moment(newDate).isValid()) {
if (format) {
return moment(newDate).format(format);
}
return moment(newDate).format('DD/MM/YYYY');
}
// date vide ou incorrecte
return '';
}
}`
My form :
<form class="form-group">
<label class="col-sm-2 control-label"> Starting date </label>
<div class="col-sm-2">
<sig-calendar #calendarStart
[(date)]="filter.startDate"
[(control)]="startDateControl"
[(maxDate)]="filter.endDate"></sig-calendar>
</div>
<label class="col-sm-1 control-label"> Ending date </label>
<div class="col-sm-2">
<sig-calendar #calendarEnd
[(date)]="filter.endDate"
[(control)]="endDateControl"
[(minDate)]="filter.startDate"></sig-calendar>
</div>
</form>
I am looking forward for suggestions about this issue.
Thanks in advance,
I have the same issue. I have a form that has a start date and end date. I am trying to use minDate and maxDate to make sure start date can't be chosen before end date, and vice versa.
But when I set the date in the start date field, and then open the calendar for the end date field, all the values for the current month are still available. If I page back to the previous month the dates are disabled as expected, and paging back to the current month will now show dates disabled properly.
I have the same issue #1114
I fixed it with layout refresh, like: export class MyCalendarComponent implements OnInit { onSelect(event) {
active = true;
...
...
this.active = false;
setTimeout(() => this.active = true, 0);
}
Thanks @sashabolcina — I'm using that workaround for now too. Hope this gets fixed soon, because the layout refresh causes a blink!
I have this same issue. Odd that there's no acknowledgement from the devs about this. Still see this in RC 7
I just started using primeng yesterday (actually only for the calendar!) and I'm finding this issue - minDate bindings aren't working and I'm not invested enough to play around with OnInit hacks to get it working...
It's been a month and they've still not fixed this.. Really.
@chrillewoodz submit a PR...?
Is it fixed
For me in 5.0.2 is still reproduced.
Reproduce - https://drive.google.com/file/d/1PoWogpz_u2v6NYeGKkisqTIO4Rfr9FCS/view
How to fix:
<p-calendar #fromCalendar
<!--...-->
(onFocus)="updateCalendarUI(fromCalendar)">
</p-calendar>
import { Calendar } from 'primeng/primeng';
//...
updateCalendarUI(calendar: Calendar) {
calendar.updateUI();
}
It's pity because it's not described in official docs =(
@qetr1ck-op
When trying
import { Calendar } from 'primeng/primeng';
//...component stuff
updateCalendar(calendar: Calendar){
calendar.updateUI();
}
I get the following
TypeError: calendar.updateUI is not a function
at
It kinda seems like the Calendar interface and what's actually rendered are different.
@jbreitenbach Hmm.
What is then the type of yours calendar parameter in method?
Did you declare a template variable on <p-calendar #myCalendar ... ?
Did you pass it into onFocus handler?
@qetr1ck-op Thank you for your reply.
Yes,
The param is typed as :Calendar, there is a template variable and the handler call is being made correctly.
Your example was followed exactly as described (although with a few more calendar properties), However, that's not going to change the overall api of the component and/or the methods able to be called.
I've even tried grabbing the p-calendar as a ViewChild() with no luck calling the .updateUI() method along with a few other methods declared within the Calendar interface.
I'm not sure if your using a different version of primeng than I or if there is some other issue.
It just seems that what the typing for :Calendar is describing isn't actually what is being rendered.
@jbreitenbach
Right. Could you show the result console.log of the #templateVar?
Public method which you're interested - https://github.com/primefaces/primeng/blob/master/src/app/components/calendar/calendar.ts#L1236
Most helpful comment
For me in
5.0.2is still reproduced.Reproduce - https://drive.google.com/file/d/1PoWogpz_u2v6NYeGKkisqTIO4Rfr9FCS/view
How to fix:
It's pity because it's not described in official docs =(