Skip to content

Commit

Permalink
Merge pull request #15423 from RogueTea/minDate_12_hour_format
Browse files Browse the repository at this point in the history
Stop incrementing date when decrement hour is pressed (Min Date defined, hour format set to 12)
  • Loading branch information
cetincakiroglu committed May 3, 2024
2 parents b46597e + a140db4 commit 2b3049b
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 6 deletions.
27 changes: 27 additions & 0 deletions src/app/components/calendar/calendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1941,4 +1941,31 @@ describe('Calendar', () => {
calendar.updateTime();
expect((calendar.value as Date).toISOString()).toBe(maxDateISO);
});

it('should set input element date to minDate including the set time', () => {
const minDate = new Date(2022, 0, 1, 20, 30, 0);
const date = new Date(2022, 0, 2);
calendar.minDate = minDate;
calendar.defaultDate = date;
calendar.hourFormat = '12';
jasmine.clock().mockDate(date);
fixture.detectChanges();

const inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
const focusEvent = new Event('focus');
inputEl.click();
calendar.currentHour = 11;
calendar.currentMinute = 30;
inputEl.dispatchEvent(focusEvent);
fixture.detectChanges();

const selectdateSpy = spyOn(calendar, 'selectDate').and.callThrough();
const calendarContainer = fixture.debugElement.query(By.css('.p-datepicker-calendar-container'));
const dates = calendarContainer.query(By.css('tbody')).queryAll(By.css('span:not(.p-datepicker-weeknumber):not(.p-disabled)'));
dates[0].nativeElement.click();
fixture.detectChanges();

expect(selectdateSpy).toHaveBeenCalled();
expect(calendar.value).toEqual(minDate);
});
});
59 changes: 53 additions & 6 deletions src/app/components/calendar/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,7 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {

formatDateTime(date: any) {
let formattedValue = this.keepInvalid ? date : null;
const isDateValid = this.isValidDateForTimeConstraints(date);

if (this.isValidDate(date)) {
if (this.timeOnly) {
Expand All @@ -1617,7 +1618,7 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
} else if (this.dataType === 'string') {
formattedValue = date;
}

formattedValue = isDateValid ? formattedValue : '';
return formattedValue;
}

Expand Down Expand Up @@ -2510,7 +2511,7 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
this.createMonths(this.currentMonth, this.currentYear);
}

convertTo24Hour = function (hours: number, pm: boolean) {
convertTo24Hour(hours: number, pm: boolean) {
//@ts-ignore
if (this.hourFormat == '12') {
if (hours === 12) {
Expand All @@ -2520,10 +2521,11 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
}
}
return hours;
};
}

constrainTime(hour: number, minute: number, second: number, pm: boolean) {
let returnTimeTriple: number[] = [hour, minute, second];
let minHoursExceeds12: boolean;
let value = this.value;
const convertedHour = this.convertTo24Hour(hour, pm);
const isRange = this.isRangeSelection(),
Expand All @@ -2544,9 +2546,38 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
const valueDateString = value ? value.toDateString() : null;
let isMinDate = this.minDate && valueDateString && this.minDate.toDateString() === valueDateString;
let isMaxDate = this.maxDate && valueDateString && this.maxDate.toDateString() === valueDateString;

if (isMinDate) {
minHoursExceeds12 = this.minDate.getHours() >= 12;
}

switch (
true // intentional fall through
) {
case isMinDate && minHoursExceeds12 && this.minDate.getHours() === 12 && this.minDate.getHours() > convertedHour:
returnTimeTriple[0] = 11;
case isMinDate && this.minDate.getHours() === convertedHour && this.minDate.getMinutes() > minute:
returnTimeTriple[1] = this.minDate.getMinutes();
case isMinDate && this.minDate.getHours() === convertedHour && this.minDate.getMinutes() === minute && this.minDate.getSeconds() > second:
returnTimeTriple[2] = this.minDate.getSeconds();
break;
case isMinDate && !minHoursExceeds12 && this.minDate.getHours() - 1 === convertedHour && this.minDate.getHours() > convertedHour:
returnTimeTriple[0] = 11;
this.pm = true;
case isMinDate && this.minDate.getHours() === convertedHour && this.minDate.getMinutes() > minute:
returnTimeTriple[1] = this.minDate.getMinutes();
case isMinDate && this.minDate.getHours() === convertedHour && this.minDate.getMinutes() === minute && this.minDate.getSeconds() > second:
returnTimeTriple[2] = this.minDate.getSeconds();
break;

case isMinDate && minHoursExceeds12 && this.minDate.getHours() > convertedHour && convertedHour !== 12:
this.setCurrentHourPM(this.minDate.getHours());
returnTimeTriple[0] = this.currentHour;
case isMinDate && this.minDate.getHours() === convertedHour && this.minDate.getMinutes() > minute:
returnTimeTriple[1] = this.minDate.getMinutes();
case isMinDate && this.minDate.getHours() === convertedHour && this.minDate.getMinutes() === minute && this.minDate.getSeconds() > second:
returnTimeTriple[2] = this.minDate.getSeconds();
break;
case isMinDate && this.minDate.getHours() > convertedHour:
returnTimeTriple[0] = this.minDate.getHours();
case isMinDate && this.minDate.getHours() === convertedHour && this.minDate.getMinutes() > minute:
Expand All @@ -2562,6 +2593,7 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
returnTimeTriple[2] = this.maxDate.getSeconds();
break;
}

return returnTimeTriple;
}

Expand All @@ -2577,11 +2609,22 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
}
newHour = newHour >= 13 ? newHour - 12 : newHour;
}
this.toggleAMPMIfNotMinDate(newPM);
[this.currentHour, this.currentMinute, this.currentSecond] = this.constrainTime(newHour, this.currentMinute!, this.currentSecond!, newPM!);
this.pm = newPM;
event.preventDefault();
}

toggleAMPMIfNotMinDate(newPM: boolean) {
let value = this.value;
const valueDateString = value ? value.toDateString() : null;
let isMinDate = this.minDate && valueDateString && this.minDate.toDateString() === valueDateString;
if (isMinDate && this.minDate.getHours() >= 12) {
this.pm = true;
} else {
this.pm = newPM;
}
}

onTimePickerElementMouseDown(event: Event, type: number, direction: number) {
if (!this.disabled) {
this.repeat(event, null, type, direction);
Expand Down Expand Up @@ -2650,8 +2693,8 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
}
newHour = newHour <= 0 ? 12 + newHour : newHour;
}
this.toggleAMPMIfNotMinDate(newPM);
[this.currentHour, this.currentMinute, this.currentSecond] = this.constrainTime(newHour, this.currentMinute!, this.currentSecond!, newPM!);
this.pm = newPM;
event.preventDefault();
}

Expand Down Expand Up @@ -2718,8 +2761,8 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {

toggleAMPM(event: any) {
const newPM = !this.pm;
[this.currentHour, this.currentMinute, this.currentSecond] = this.constrainTime(this.currentHour, this.currentMinute, this.currentSecond, newPM);
this.pm = newPM;
[this.currentHour, this.currentMinute, this.currentSecond] = this.constrainTime(this.currentHour, this.currentMinute, this.currentSecond, newPM);
this.updateTime();
event.preventDefault();
}
Expand Down Expand Up @@ -3383,6 +3426,10 @@ export class Calendar implements OnInit, OnDestroy, ControlValueAccessor {
this.filled = (this.inputFieldValue && this.inputFieldValue != '') as boolean;
}

isValidDateForTimeConstraints(selectedDate: Date) {
return (!this.minDate || selectedDate >= this.minDate) && (!this.maxDate || selectedDate <= this.maxDate);
}

onTodayButtonClick(event: any) {
const date: Date = new Date();
const dateMeta = { day: date.getDate(), month: date.getMonth(), year: date.getFullYear(), otherMonth: date.getMonth() !== this.currentMonth || date.getFullYear() !== this.currentYear, today: true, selectable: true };
Expand Down

0 comments on commit 2b3049b

Please sign in to comment.