Skip to content

Commit 203d775

Browse files
committed
fix(time-picker): different styling for item outside the min/max values #3978
1 parent e9abe7a commit 203d775

File tree

5 files changed

+146
-15
lines changed

5 files changed

+146
-15
lines changed

projects/igniteui-angular/src/lib/time-picker/time-picker.component.html

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<igx-prefix (click)="openDialog(group.element.nativeElement)">
55
<igx-icon>access_time</igx-icon>
66
</igx-prefix>
7-
<input
7+
<input
88
type="text"
99
[igxMask]="mask"
1010
igxInput
@@ -61,16 +61,37 @@ <h2 class="igx-time-picker__header-hour">
6161
<div class="igx-time-picker__main">
6262
<div class="igx-time-picker__body">
6363
<div *ngIf="showHoursList" #hourList [igxItemList]="'hourList'">
64-
<span [igxHourItem]="hour" *ngFor="let hour of hourView">{{ hour }}</span>
64+
<span [igxHourItem]="hour"
65+
[minValueDate]="convertMinMaxValue(minValue)"
66+
[maxValueDate]="convertMinMaxValue(maxValue)"
67+
[selectedAmPm]="selectedAmPm"
68+
*ngFor="let hour of hourView">{{ hour }}</span>
6569
</div>
6670
<div *ngIf="showMinutesList" #minuteList [igxItemList]="'minuteList'">
67-
<span [igxMinuteItem]="minute" *ngFor="let minute of minuteView">{{ minute }}</span>
71+
<span [igxMinuteItem]="minute"
72+
[minValueDate]="convertMinMaxValue(minValue)"
73+
[maxValueDate]="convertMinMaxValue(maxValue)"
74+
[selectedHour]="selectedHour"
75+
[selectedAmPm]="selectedAmPm"
76+
*ngFor="let minute of minuteView" >{{ minute }}</span>
6877
</div>
6978
<div *ngIf="showSecondsList" #secondsList [igxItemList]="'secondsList'">
70-
<span [igxSecondsItem]="seconds" *ngFor="let seconds of secondsView">{{ seconds }}</span>
79+
<span [igxSecondsItem]="seconds"
80+
[minValueDate]="convertMinMaxValue(minValue)"
81+
[maxValueDate]="convertMinMaxValue(maxValue)"
82+
[selectedHour]="selectedHour"
83+
[selectedMinute]="selectedMinute"
84+
[selectedAmPm]="selectedAmPm"
85+
*ngFor="let seconds of secondsView">{{ seconds }}</span>
7186
</div>
7287
<div *ngIf="showAmPmList" #ampmList [igxItemList]="'ampmList'">
73-
<span [igxAmPmItem]="ampm" *ngFor="let ampm of ampmView">{{ ampm }}</span>
88+
<span [igxAmPmItem]="ampm"
89+
[minValueDate]="convertMinMaxValue(minValue)"
90+
[maxValueDate]="convertMinMaxValue(maxValue)"
91+
[selectedHour]="selectedHour"
92+
[selectedMinute]="selectedMinute"
93+
[selectedSecond]="selectedSeconds"
94+
*ngFor="let ampm of ampmView">{{ ampm }}</span>
7495
</div>
7596
</div>
7697
<ng-container

projects/igniteui-angular/src/lib/time-picker/time-picker.component.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ export class IgxTimePickerComponent implements
579579
*/
580580
public selectedAmPm: string;
581581

582+
public minValueConverted: Date;
583+
584+
public maxValueConverted: Date;
585+
582586
/** @hidden @internal */
583587
private _value: Date;
584588
private _resourceStrings = CurrentResourceStrings.TimePickerResStrings;
@@ -1268,7 +1272,7 @@ export class IgxTimePickerComponent implements
12681272
return date;
12691273
}
12701274

1271-
private _convertMinMaxValue(value: string): Date {
1275+
public convertMinMaxValue(value: string): Date {
12721276
const date = this.value ? new Date(this.value) : this._dateFromModel ? new Date(this._dateFromModel) : new Date();
12731277
const sections = value.split(/[\s:]+/);
12741278
let hour, minutes, seconds, amPM;
@@ -1311,9 +1315,9 @@ export class IgxTimePickerComponent implements
13111315
}
13121316

13131317
private _isValueValid(value: Date): boolean {
1314-
if (this.maxValue && value > this._convertMinMaxValue(this.maxValue)) {
1318+
if (this.maxValue && value > this.convertMinMaxValue(this.maxValue)) {
13151319
return false;
1316-
} else if (this.minValue && value < this._convertMinMaxValue(this.minValue)) {
1320+
} else if (this.minValue && value < this.convertMinMaxValue(this.minValue)) {
13171321
return false;
13181322
} else {
13191323
return true;
@@ -1485,7 +1489,7 @@ export class IgxTimePickerComponent implements
14851489

14861490
private _onDropDownClosed(): void {
14871491
const oldValue = this.value;
1488-
const newVal = this._convertMinMaxValue(this.displayValue);
1492+
const newVal = this.convertMinMaxValue(this.displayValue);
14891493

14901494
if (this.displayValue === this.parseMask(false)) {
14911495
return;
@@ -1923,7 +1927,7 @@ export class IgxTimePickerComponent implements
19231927
// timepicker own value property if it is a valid Date
19241928
if (val.indexOf(this.promptChar) === -1) {
19251929
if (this._isEntryValid(val)) {
1926-
const newVal = this._convertMinMaxValue(val);
1930+
const newVal = this.convertMinMaxValue(val);
19271931
if (oldVal.getTime() !== newVal.getTime()) {
19281932
this.value = newVal;
19291933
}
@@ -1971,7 +1975,7 @@ export class IgxTimePickerComponent implements
19711975

19721976
if (value && value !== this.parseMask()) {
19731977
if (this._isEntryValid(value)) {
1974-
const newVal = this._convertMinMaxValue(value);
1978+
const newVal = this.convertMinMaxValue(value);
19751979
if (!this.value || this.value.getTime() !== newVal.getTime()) {
19761980
this.value = newVal;
19771981
}
@@ -2008,8 +2012,8 @@ export class IgxTimePickerComponent implements
20082012
let sign: number;
20092013
let displayVal: string;
20102014
const currentVal = new Date(this.value);
2011-
const min = this.minValue ? this._convertMinMaxValue(this.minValue) : this._convertMinMaxValue('00:00');
2012-
const max = this.maxValue ? this._convertMinMaxValue(this.maxValue) : this._convertMinMaxValue('24:00');
2015+
const min = this.minValue ? this.convertMinMaxValue(this.minValue) : this.convertMinMaxValue('00:00');
2016+
const max = this.maxValue ? this.convertMinMaxValue(this.maxValue) : this.convertMinMaxValue('24:00');
20132017

20142018
const cursor = this._getCursorPosition();
20152019

projects/igniteui-angular/src/lib/time-picker/time-picker.directives.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,15 @@ export class IgxHourItemDirective {
242242
@Input('igxHourItem')
243243
public value: string;
244244

245+
@Input('minValueDate')
246+
public minValueDate: Date;
247+
248+
@Input('maxValueDate')
249+
public maxValueDate: Date;
250+
251+
@Input('selectedAmPm')
252+
public selectedAmPm: string;
253+
245254
@HostBinding('class.igx-time-picker__item')
246255
get defaultCSS(): boolean {
247256
return true;
@@ -257,6 +266,17 @@ export class IgxHourItemDirective {
257266
return this.isSelectedHour && this.itemList.isActive;
258267
}
259268

269+
@HostBinding('class.igx-time-picker__item--disabled')
270+
get applyDisabledStyleForHours(): boolean {
271+
let hour = parseInt(this.value);
272+
if (this.selectedAmPm === 'PM') {
273+
hour += 12;
274+
}
275+
const date = new Date(this.minValueDate);
276+
date.setHours(hour);
277+
return !(date <= this.maxValueDate && date >= this.minValueDate);
278+
}
279+
260280
get isSelectedHour(): boolean {
261281
return this.timePicker.selectedHour === this.value;
262282
}
@@ -284,6 +304,18 @@ export class IgxMinuteItemDirective {
284304
@Input('igxMinuteItem')
285305
public value: string;
286306

307+
@Input('selectedHour')
308+
public selectedHour: string;
309+
310+
@Input('minValueDate')
311+
public minValueDate: Date;
312+
313+
@Input('maxValueDate')
314+
public maxValueDate: Date;
315+
316+
@Input('selectedAmPm')
317+
public selectedAmPm: string;
318+
287319
@HostBinding('class.igx-time-picker__item')
288320
get defaultCSS(): boolean {
289321
return true;
@@ -299,6 +331,19 @@ export class IgxMinuteItemDirective {
299331
return this.isSelectedMinute && this.itemList.isActive;
300332
}
301333

334+
@HostBinding('class.igx-time-picker__item--disabled')
335+
get applyDisabledStyleForMinutes(): boolean {
336+
const minute = parseInt(this.value);
337+
let hour = parseInt(this.selectedHour);
338+
if (this.selectedAmPm === 'PM') {
339+
hour += 12;
340+
}
341+
const date = new Date(this.minValueDate);
342+
date.setHours(hour);
343+
date.setMinutes(minute);
344+
return !(date <= this.maxValueDate && date >= this.minValueDate);
345+
}
346+
302347
get isSelectedMinute(): boolean {
303348
return this.timePicker.selectedMinute === this.value;
304349
}
@@ -326,6 +371,21 @@ export class IgxSecondsItemDirective {
326371
@Input('igxSecondsItem')
327372
public value: string;
328373

374+
@Input('selectedHour')
375+
public selectedHour: string;
376+
377+
@Input('selectedMinute')
378+
public selectedMinute: string;
379+
380+
@Input('minValueDate')
381+
public minValueDate: Date;
382+
383+
@Input('maxValueDate')
384+
public maxValueDate: Date;
385+
386+
@Input('selectedAmPm')
387+
public selectedAmPm: string;
388+
329389
@HostBinding('class.igx-time-picker__item')
330390
get defaultCSS(): boolean {
331391
return true;
@@ -341,6 +401,21 @@ export class IgxSecondsItemDirective {
341401
return this.isSelectedSeconds && this.itemList.isActive;
342402
}
343403

404+
@HostBinding('class.igx-time-picker__item--disabled')
405+
get applyDisabledStyleForSeconds(): boolean {
406+
const minute = parseInt(this.selectedMinute);
407+
let hour = parseInt(this.selectedHour);
408+
const second = parseInt(this.value);
409+
if (this.selectedAmPm === 'PM') {
410+
hour += 12;
411+
}
412+
const date = new Date(this.minValueDate);
413+
date.setHours(hour);
414+
date.setMinutes(minute);
415+
date.setSeconds(second);
416+
return !(date <= this.maxValueDate && date >= this.minValueDate);
417+
}
418+
344419
get isSelectedSeconds(): boolean {
345420
return this.timePicker.selectedSeconds === this.value;
346421
}
@@ -368,6 +443,21 @@ export class IgxAmPmItemDirective {
368443
@Input('igxAmPmItem')
369444
public value: string;
370445

446+
@Input('selectedHour')
447+
public selectedHour: string;
448+
449+
@Input('selectedMinute')
450+
public selectedMinute: string;
451+
452+
@Input('selectedSecond')
453+
public selectedSecond: string;
454+
455+
@Input('minValueDate')
456+
public minValueDate: Date;
457+
458+
@Input('maxValueDate')
459+
public maxValueDate: Date;
460+
371461
@HostBinding('class.igx-time-picker__item')
372462
get defaultCSS(): boolean {
373463
return true;
@@ -383,6 +473,22 @@ export class IgxAmPmItemDirective {
383473
return this.isSelectedAmPm && this.itemList.isActive;
384474
}
385475

476+
@HostBinding('class.igx-time-picker__item--disabled')
477+
get applyDisabledStyleForAmPm(): boolean {
478+
const minute = parseInt(this.selectedMinute);
479+
let hour = parseInt(this.selectedHour);
480+
const second = parseInt(this.selectedSecond);
481+
const amPM = this.value;
482+
if (amPM === 'PM') {
483+
hour += 12;
484+
}
485+
const date = new Date(this.minValueDate);
486+
date.setHours(hour);
487+
date.setMinutes(minute);
488+
date.setSeconds(second);
489+
return !(date <= this.maxValueDate && date >= this.minValueDate);
490+
}
491+
386492
get isSelectedAmPm(): boolean {
387493
return this.timePicker.selectedAmPm === this.value;
388494
}

src/app/time-picker/time-picker.sample.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<h4 class="sample-title">Time Picker with Dropdown</h4>
88
<div class="sample-description">{{showDate(date)}}</div>
99
<div class="preview" style="width: 280px">
10-
<igx-time-picker #tp (onValueChanged)="valueChanged($event)" [minValue]="'9:15 AM'" [maxValue]="'9:15 PM'"
10+
<igx-time-picker #tp (onValueChanged)="valueChanged($event)" [minValue]="'9:15:20 AM'" [maxValue]="'9:15:30 PM'"
1111
(onValidationFailed)="validationFailed($event)" [mode]="mode" [isSpinLoop]="isSpinLoop"
1212
[(ngModel)]="date" [itemsDelta]="itemsDelta" [format]="format">
1313
</igx-time-picker>

src/app/time-picker/time-picker.sample.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class TimePickerSampleComponent implements AfterViewInit {
1111
min = '09:00';
1212

1313
itemsDelta = { hours: 1, minutes: 5 };
14-
format = 'hh:mm tt';
14+
format = 'hh:mm:ss tt';
1515
isSpinLoop = true;
1616
isVertical = true;
1717
mode = InteractionMode.DropDown;

0 commit comments

Comments
 (0)