Skip to content

Commit 6a0ef83

Browse files
refactor(date-time-editor): fix model binding #7264 (#7307)
- date-range: use callback to update model; - add separate validation for projected inputs; - use separate date-editors' values when updating date-range's value Co-authored-by: Boris <[email protected]>
1 parent e9abe7a commit 6a0ef83

File tree

10 files changed

+465
-303
lines changed

10 files changed

+465
-303
lines changed

projects/igniteui-angular/src/lib/date-picker/date-picker.utils.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -246,55 +246,53 @@ export abstract class DatePickerUtil {
246246
}
247247

248248
/**
249-
* Determines whether the provided value is less than the provided min value.
249+
* Determines whether the provided value is greater than the provided max value.
250250
* @param includeTime set to false if you want to exclude time portion of the two dates
251251
* @param includeDate set to false if you want to exclude the date portion of the two dates
252+
* @returns true if provided value is greater than provided maxValue
252253
*/
253254
public static greaterThanMaxValue(value: Date, maxValue: Date, includeTime = true, includeDate = true): boolean {
254255
if (includeTime && includeDate) {
255256
return value.getTime() > maxValue.getTime();
256257
}
257258

258-
let _value = new Date(value.getTime());
259-
let _maxValue = new Date(maxValue.getTime());
260-
if (includeDate) {
259+
const _value = new Date(value.getTime());
260+
const _maxValue = new Date(maxValue.getTime());
261+
if (!includeTime) {
261262
_value.setHours(0, 0, 0, 0);
262263
_maxValue.setHours(0, 0, 0, 0);
263-
return _value.getTime() > maxValue.getTime();
264264
}
265-
if (includeTime) {
266-
_value = new Date(0, 0, 0, _value.getHours(), _value.getMinutes(), _value.getSeconds());
267-
_maxValue = new Date(0, 0, 0, _maxValue.getHours(), _maxValue.getMinutes(), _maxValue.getSeconds());
268-
return _value.getTime() > _maxValue.getTime();
265+
if (!includeDate) {
266+
_value.setFullYear(0, 0, 0);
267+
_maxValue.setFullYear(0, 0, 0);
269268
}
270269

271-
// throw?
270+
return _value.getTime() > _maxValue.getTime();
272271
}
273272

274273
/**
275-
* Determines whether the provided value is greater than the provided min value.
274+
* Determines whether the provided value is less than the provided min value.
276275
* @param includeTime set to false if you want to exclude time portion of the two dates
277276
* @param includeDate set to false if you want to exclude the date portion of the two dates
277+
* @returns true if provided value is less than provided minValue
278278
*/
279279
public static lessThanMinValue(value: Date, minValue: Date, includeTime = true, includeDate = true): boolean {
280280
if (includeTime && includeDate) {
281281
return value.getTime() < minValue.getTime();
282282
}
283283

284-
let _value = new Date(value.getTime());
285-
let _minValue = new Date(minValue.getTime());
286-
if (includeDate) {
284+
const _value = new Date(value.getTime());
285+
const _minValue = new Date(minValue.getTime());
286+
if (!includeTime) {
287287
_value.setHours(0, 0, 0, 0);
288288
_minValue.setHours(0, 0, 0, 0);
289-
return _value.getTime() < _minValue.getTime();
290289
}
291-
if (includeTime) {
292-
_value = new Date(0, 0, 0, _value.getHours(), _value.getMinutes(), _value.getSeconds());
293-
_minValue = new Date(0, 0, 0, _minValue.getHours(), _minValue.getMinutes(), _minValue.getSeconds());
294-
return _value.getTime() > _minValue.getTime();
290+
if (!includeDate) {
291+
_value.setFullYear(0, 0, 0);
292+
_minValue.setFullYear(0, 0, 0);
295293
}
296294

297-
// throw?
295+
return _value.getTime() < _minValue.getTime();
298296
}
299297

300298
private static ensureLeadingZero(part: DatePartInfo) {
@@ -848,4 +846,3 @@ export abstract class DatePickerUtil {
848846
}
849847
}
850848

851-

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker-inputs.common.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Component, ContentChild, Pipe, PipeTransform, Output, EventEmitter, HostListener, Directive } from '@angular/core';
2+
import { formatDate } from '@angular/common';
3+
import { NgControl } from '@angular/forms';
4+
import { IgxInputDirective, IgxInputState } from '../input-group';
25
import { IgxInputGroupComponent } from '../input-group/input-group.component';
36
import { IgxInputGroupBase } from '../input-group/input-group.common';
4-
import { NgControl } from '@angular/forms';
57
import { IgxDateTimeEditorDirective } from '../directives/date-time-editor';
6-
import { formatDate } from '@angular/common';
7-
import { IgxInputDirective } from '../input-group';
88

99
/**
1010
* Represents a range between two dates.
@@ -65,13 +65,19 @@ export class IgxDateRangeInputsBaseComponent extends IgxInputGroupComponent {
6565
}
6666

6767
/** @hidden @internal */
68-
public updateInput(value: Date) {
68+
public updateInputValue(value: Date) {
6969
if (this.ngControl) {
7070
this.ngControl.control.setValue(value);
7171
} else {
7272
this.dateTimeEditor.value = value;
7373
}
7474
}
75+
76+
/** @hidden @internal */
77+
public updateInputValidity(state: IgxInputState) {
78+
this.inputDirective.valid = state;
79+
}
80+
7581
}
7682

7783
/**
@@ -100,8 +106,10 @@ export class IgxPickerToggleComponent {
100106
@Output()
101107
public clicked = new EventEmitter();
102108

103-
@HostListener('click')
104-
public onClick() {
109+
@HostListener('click', ['$event'])
110+
public onClick(event: MouseEvent) {
111+
// do not focus input on click
112+
event.stopPropagation();
105113
this.clicked.emit();
106114
}
107115
}
@@ -133,7 +141,10 @@ export class IgxPickerToggleComponent {
133141
@Component({
134142
selector: 'igx-date-range-start',
135143
templateUrl: '../input-group/input-group.component.html',
136-
providers: [{ provide: IgxInputGroupBase, useExisting: IgxDateRangeStartComponent }]
144+
providers: [
145+
{ provide: IgxInputGroupBase, useExisting: IgxDateRangeStartComponent },
146+
{ provide: IgxDateRangeInputsBaseComponent, useExisting: IgxDateRangeStartComponent }
147+
]
137148
})
138149
export class IgxDateRangeStartComponent extends IgxDateRangeInputsBaseComponent { }
139150

@@ -164,7 +175,10 @@ export class IgxDateRangeStartComponent extends IgxDateRangeInputsBaseComponent
164175
@Component({
165176
selector: 'igx-date-range-end',
166177
templateUrl: '../input-group/input-group.component.html',
167-
providers: [{ provide: IgxInputGroupBase, useExisting: IgxDateRangeEndComponent }]
178+
providers: [
179+
{ provide: IgxInputGroupBase, useExisting: IgxDateRangeEndComponent },
180+
{ provide: IgxDateRangeInputsBaseComponent, useExisting: IgxDateRangeEndComponent }
181+
]
168182
})
169183
export class IgxDateRangeEndComponent extends IgxDateRangeInputsBaseComponent { }
170184

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ describe('IgxDateRangePicker', () => {
7777
const dateRangePicker = new IgxDateRangePickerComponent(null, null, 'en', null);
7878
dateRangePicker.registerOnChange(mockNgControl.registerOnChangeCb);
7979
dateRangePicker.registerOnTouched(mockNgControl.registerOnTouchedCb);
80-
spyOn(dateRangePicker, 'handleSelection');
80+
spyOn(dateRangePicker, 'handleSelection').and.callThrough();
8181

8282
// writeValue
8383
expect(dateRangePicker.value).toBeUndefined();
@@ -92,7 +92,7 @@ describe('IgxDateRangePicker', () => {
9292
dateRangePicker.handleSelection([range.start]);
9393
expect(dateRangePicker.handleSelection).toHaveBeenCalledWith([range.start]);
9494
expect(dateRangePicker.handleSelection).toHaveBeenCalledTimes(1);
95-
expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith({ start: range.start, end: range.end });
95+
expect(mockNgControl.registerOnChangeCb).toHaveBeenCalledWith({ start: range.start, end: range.start });
9696

9797
// awaiting implementation - OnTouched callback
9898
// Docs: changes the value, turning the control dirty; or blurs the form control element, setting the control to touched.
@@ -201,14 +201,14 @@ describe('IgxDateRangePicker', () => {
201201
verifyDateRangeInSingleInput();
202202
});
203203

204-
it('should set start date on single date selection', () => {
204+
it('should set start and end dates on single date selection', () => {
205205
fixture.componentInstance.mode = InteractionMode.DropDown;
206206
fixture.detectChanges();
207207

208208
const dayRange = 0;
209209
const today = new Date();
210210
startDate = new Date(today.getFullYear(), today.getMonth(), 10, 0, 0, 0);
211-
endDate = null;
211+
endDate = startDate;
212212
selectDateRangeFromCalendar(startDate.getDate(), dayRange);
213213
verifyDateRangeInSingleInput();
214214
});
@@ -506,13 +506,13 @@ describe('IgxDateRangePicker', () => {
506506
verifyDateRange();
507507
});
508508

509-
it('should apply selection to start date when single date is selected', () => {
509+
it('should apply selection to start and end dates when single date is selected', () => {
510510
fixture.componentInstance.mode = InteractionMode.DropDown;
511511
fixture.detectChanges();
512512

513513
const today = new Date();
514514
startDate = new Date(today.getFullYear(), today.getMonth(), 4, 0, 0, 0);
515-
endDate = null;
515+
endDate = startDate;
516516

517517
selectDateRangeFromCalendar(startDate.getDate(), 0);
518518
verifyDateRange();

0 commit comments

Comments
 (0)