From 3aebe7c5902486be7f02ab5a67c994ebd3bc3060 Mon Sep 17 00:00:00 2001 From: Wenqi <1264578441@qq.com> Date: Thu, 2 Apr 2020 14:12:41 +0800 Subject: [PATCH] fix(module:date-picker): click date cell not work when changing month or year (#4876) * fix(module:date-picker): click date not work when changing month Fixes #3499 --- .../date-picker/calendar-footer.component.ts | 1 - .../date-picker/date-picker.component.html | 1 - .../date-picker/date-picker.component.spec.ts | 78 +++++++--- .../date-picker/date-picker.component.ts | 13 +- components/date-picker/date-picker.service.ts | 2 +- .../date-picker/date-range-popup.component.ts | 146 ++++++++---------- components/date-picker/demo/disabled-date.ts | 2 +- components/date-picker/lib/abstract-table.ts | 3 - components/date-picker/picker.component.ts | 56 ++----- components/date-picker/public-api.ts | 4 +- .../range-picker.component.spec.ts | 21 ++- components/date-picker/util.ts | 3 + 12 files changed, 166 insertions(+), 164 deletions(-) diff --git a/components/date-picker/calendar-footer.component.ts b/components/date-picker/calendar-footer.component.ts index 653c16dcf3c..c972069d670 100644 --- a/components/date-picker/calendar-footer.component.ts +++ b/components/date-picker/calendar-footer.component.ts @@ -80,7 +80,6 @@ export class CalendarFooterComponent implements OnChanges { @Input() hasTimePicker: boolean = false; @Input() isRange: boolean = false; - @Input() timePickerDisabled: boolean = false; @Input() okDisabled: boolean = false; @Input() disabledDate: (d: Date) => boolean; @Input() extraFooter: TemplateRef | string; diff --git a/components/date-picker/date-picker.component.html b/components/date-picker/date-picker.component.html index 30a38869646..9d8847e30df 100644 --- a/components/date-picker/date-picker.component.html +++ b/components/date-picker/date-picker.component.html @@ -4,7 +4,6 @@ [open]="nzOpen" [separator]="nzSeparator" [disabled]="nzDisabled" - [disabledDate]="nzDisabledDate" [format]="nzFormat" [allowClear]="nzAllowClear" [autoFocus]="nzAutoFocus" diff --git a/components/date-picker/date-picker.component.spec.ts b/components/date-picker/date-picker.component.spec.ts index 9efa358569e..0c342011a4b 100644 --- a/components/date-picker/date-picker.component.spec.ts +++ b/components/date-picker/date-picker.component.spec.ts @@ -387,6 +387,29 @@ describe('NzDatePickerComponent', () => { describe('panel switch and move forward/afterward', () => { beforeEach(() => (fixtureInstance.useSuite = 1)); + it('should support date panel changes on click month', fakeAsync(() => { + fixtureInstance.nzValue = new Date('2018-11-11'); + fixture.detectChanges(); + flush(); + fixture.detectChanges(); + openPickerByClickTrigger(); + // Click month + dispatchMouseEvent(queryFromOverlay('.ant-picker-header-month-btn'), 'click'); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + dispatchMouseEvent(getFirstCell(), 'click'); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + // click 2018-01-01 + dispatchMouseEvent(getFirstCell(), 'click'); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + expect(getPickerInput(fixture.debugElement).value).toBe('2018-01-01'); + })); + it('should support date panel changes', fakeAsync(() => { fixtureInstance.nzValue = new Date('2018-11-11'); fixture.detectChanges(); @@ -585,10 +608,10 @@ describe('NzDatePickerComponent', () => { it('should support nzShowTime', fakeAsync(() => { fixtureInstance.nzValue = new Date('2018-11-11 11:22:33'); - fixtureInstance.nzShowTime = true; + // tslint:disable-next-line:no-any + fixtureInstance.nzShowTime = '' as any; fixture.detectChanges(); openPickerByClickTrigger(); - // Why need one more detectChange ? flush(); fixture.detectChanges(); expect(queryFromOverlay('.ant-picker-ok')).toBeDefined(); @@ -627,10 +650,10 @@ describe('NzDatePickerComponent', () => { fixtureInstance.nzValue = new Date('2019-08-02 13:03:33'); fixtureInstance.nzShowTime = true; fixture.detectChanges(); + flush(); + fixture.detectChanges(); openPickerByClickTrigger(); - dispatchMouseEvent(getFirstCell(), 'click'); - fixture.detectChanges(); flush(); fixture.detectChanges(); @@ -678,6 +701,35 @@ describe('NzDatePickerComponent', () => { expect(+queryFromOverlay('.ant-picker-time-panel-column:nth-child(3) li:first-child').textContent!.trim()).toBe(1); })); + it('should nzDisabledTime invalid input not emit', fakeAsync(() => { + fixtureInstance.nzShowTime = true; + fixtureInstance.nzDisabledTime = () => { + return { + nzDisabledHours: () => [0, 1, 2], + nzDisabledMinutes: () => [0, 1], + nzDisabledSeconds: () => [0] + }; + }; + fixture.detectChanges(); + openPickerByClickTrigger(); + + // input disabled value + const input = getPickerInput(fixture.debugElement); + typeInElement('2020-03-14 00:00:00', input); + fixture.detectChanges(); + input.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + expect(getPickerContainer()).not.toBeNull(); + + dispatchMouseEvent(queryFromOverlay('.cdk-overlay-backdrop'), 'click'); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + expect(getPickerInput(fixture.debugElement).value).toBe(''); + })); + it('should support nzRenderExtraFooter', fakeAsync(() => { fixtureInstance.nzRenderExtraFooter = () => fixtureInstance.tplExtraFooter; fixture.detectChanges(); @@ -807,24 +859,6 @@ describe('NzDatePickerComponent', () => { })); }); - // describe('AbstractPicker', () => { - // beforeEach(() => { - // const fakeCdr = { markForCheck: () => void 0 }; - // componentInstance = new (AbstractPickerComponent as any)(i18n, fakeCdr); // tslint:disable-line:no-any - // }); - // - // it('should cover untouched branches', () => { - // // onOpenChange - // const emit = spyOn(componentInstance.nzOnOpenChange, 'emit'); - // componentInstance.onOpenChange(true); - // expect(emit).toHaveBeenCalled(); - // - // // setDisabledState - // componentInstance.setDisabledState(true); - // expect(componentInstance.nzDisabled).toBeTruthy(); - // }); - // }); // /AbstractPicker - //////////// function getPickerContainer(): HTMLElement { diff --git a/components/date-picker/date-picker.component.ts b/components/date-picker/date-picker.component.ts index 86e20e8d0f9..3ac41b7db2d 100644 --- a/components/date-picker/date-picker.component.ts +++ b/components/date-picker/date-picker.component.ts @@ -29,7 +29,7 @@ import { warnDeprecation } from 'ng-zorro-antd/core/logger'; import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation'; import { CandyDate, cloneDate, CompatibleValue } from 'ng-zorro-antd/core/time'; import { FunctionProp, OnChangeType, OnTouchedType } from 'ng-zorro-antd/core/types'; -import { InputBoolean, valueFunctionProp } from 'ng-zorro-antd/core/util'; +import { InputBoolean, toBoolean, valueFunctionProp } from 'ng-zorro-antd/core/util'; import { DateHelperService, NzDatePickerI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -70,6 +70,7 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Cont protected destroyed$: Subject = new Subject(); protected isCustomPlaceHolder: boolean = false; + private showTime: SupportTimeOptions | boolean; // --- Common API @Input() @InputBoolean() nzAllowClear: boolean = true; @@ -98,7 +99,6 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Cont @Input() nzMode: PanelMode | PanelMode[] = 'date'; @Input() nzRanges: PresetRanges; @Input() nzDefaultPickerValue: CompatibleDate | null = null; - @Input() nzShowTime: SupportTimeOptions | boolean = false; @Input() nzSeparator: string = '~'; @Output() readonly nzOnPanelChange = new EventEmitter(); @@ -108,6 +108,14 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Cont @ViewChild(NzPickerComponent, { static: true }) protected picker: NzPickerComponent; + @Input() get nzShowTime(): SupportTimeOptions | boolean { + return this.showTime; + } + + set nzShowTime(value: SupportTimeOptions | boolean) { + this.showTime = typeof value === 'object' ? value : toBoolean(value); + } + get realOpenState(): boolean { return this.picker.animationOpenState; } // Use picker's real open state to let re-render the picker's content when shown up @@ -143,7 +151,6 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Cont this.datePickerService.emitValue$.pipe(takeUntil(this.destroyed$)).subscribe(_ => { const value = this.datePickerService.value; this.datePickerService.initialValue = cloneDate(value); - // this.datePickerService.activeDate = cloneDate(value); if (this.isRange) { const vAsRange = value as CandyDate[]; if (vAsRange.length) { diff --git a/components/date-picker/date-picker.service.ts b/components/date-picker/date-picker.service.ts index f440d998920..5ee0cbe4616 100644 --- a/components/date-picker/date-picker.service.ts +++ b/components/date-picker/date-picker.service.ts @@ -41,7 +41,7 @@ export class DatePickerService { } } - makeValue(value: CompatibleDate): CompatibleValue { + makeValue(value: CompatibleDate | null): CompatibleValue { if (this.isRange) { return value ? (value as Date[]).map(val => new CandyDate(val)) : []; } else { diff --git a/components/date-picker/date-range-popup.component.ts b/components/date-picker/date-range-popup.component.ts index 488be92ab80..09593e6b2a5 100644 --- a/components/date-picker/date-range-popup.component.ts +++ b/components/date-picker/date-range-popup.component.ts @@ -94,12 +94,12 @@ import { getTimeConfig, isAllowedDate, PREFIX_CLASS } from './util'; [value]="getValue(partType)" [disabledDate]="disabledDate" [dateRender]="dateRender" - [selectedValue]="selectedValue" + [selectedValue]="datePickerService?.value" [hoverValue]="hoverValue" [enablePrev]="enablePrevNext('prev', partType)" [enableNext]="enablePrevNext('next', partType)" (dayHover)="onDayHover($event)" - (selectDate)="changeValueFromSelect($event)" + (selectDate)="changeValueFromSelect($event, !showTime)" (selectTime)="onSelectTime($event, partType)" (headerChange)="onActiveDateChange($event, partType)" > @@ -111,8 +111,7 @@ import { getTimeConfig, isAllowedDate, PREFIX_CLASS } from './util'; [locale]="locale" [showToday]="showToday" [hasTimePicker]="hasTimePicker" - [timePickerDisabled]="timePickerDisabled()" - [okDisabled]="okDisabled()" + [okDisabled]="!isAllowed(datePickerService?.value)" [extraFooter]="extraFooter" [rangeQuickSelector]="ranges ? tplRangeQuickSelector : null" (clickOk)="onClickOk()" @@ -166,7 +165,6 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { prefixCls: string = PREFIX_CLASS; endPanelMode: PanelMode | PanelMode[] = 'date'; timeOptions: SupportTimeOptions | SupportTimeOptions[] | null; - selectedValue: SingleValue[] = []; // Range ONLY hoverValue: SingleValue[] = []; // Range ONLY destroy$ = new Subject(); @@ -181,17 +179,8 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { constructor(public datePickerService: DatePickerService, public cdr: ChangeDetectorRef) {} ngOnInit(): void { - // Set panel active date once open - const activeDate = this.datePickerService.hasValue() - ? this.datePickerService.value - : this.datePickerService.makeValue(this.defaultPickerValue); - this.datePickerService.setActiveDate(activeDate); - this.datePickerService.valueChange$.pipe(takeUntil(this.destroy$)).subscribe(value => { - if (this.isRange) { - // Re-initialize all related values - this.clearHoverValue(); - this.selectedValue = cloneDate(value) as SingleValue[]; - } + this.datePickerService.valueChange$.pipe(takeUntil(this.destroy$)).subscribe(() => { + this.initActiveDate(); this.cdr.markForCheck(); }); } @@ -213,6 +202,13 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { this.destroy$.complete(); } + initActiveDate(): void { + const activeDate = this.datePickerService.hasValue() + ? this.datePickerService.value + : this.datePickerService.makeValue(this.defaultPickerValue); + this.datePickerService.setActiveDate(activeDate); + } + onClickOk(): void { if (this.datePickerService.hasOnePart()) { const otherPart = this.datePickerService.activeInput === 'left' ? 'right' : 'left'; @@ -223,13 +219,16 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { } onClickToday(value: CandyDate): void { - this.changeValueFromSelect(value); + this.changeValueFromSelect(value, !this.showTime); } onDayHover(value: CandyDate): void { + if (!this.isRange) { + return; + } const otherInputIndex = { left: 1, right: 0 }[this.datePickerService.activeInput]; - const base = this.selectedValue[otherInputIndex]!; - if (this.isRange && base) { + const base = (this.datePickerService.value as CandyDate[])[otherInputIndex]!; + if (base) { if (base.isBeforeDay(value)) { this.hoverValue = [base, value]; } else { @@ -270,7 +269,6 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { const newValue = cloneDate(this.datePickerService.value) as SingleValue[]; const index = this.datePickerService.getActiveIndex(partType); newValue[index] = this.overrideHms(value, newValue[index]); - this.selectedValue[index] = newValue[index]; this.datePickerService.setValue(newValue); } else { const newValue = this.overrideHms(value, this.datePickerService.value as CandyDate); @@ -279,37 +277,45 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { this.buildTimeOptions(); } - changeValueFromSelect(value: CandyDate): void { + changeValueFromSelect(value: CandyDate, emitValue: boolean = true): void { if (this.isRange) { - const [left, right] = this.selectedValue as CandyDate[]; // NOTE: the left/right maybe not the sequence it select at the date panels - - if (!left && !right && !this.showTime) { - let otherPart: RangePartType; - // If totally full or empty, clean up && re-assign left first - if (this.datePickerService.activeInput === 'left') { - otherPart = 'right'; - this.hoverValue = this.selectedValue = [value]; - } else { - otherPart = 'left'; - this.hoverValue = this.selectedValue = [null, value]; - } - this.datePickerService.setValue(cloneDate(this.selectedValue)); - this.calendarChange.emit([value.clone()]); - this.datePickerService.inputPartChange$.next(otherPart!); + let selectedValue: SingleValue[] = cloneDate(this.datePickerService.value) as CandyDate[]; + let otherPart: RangePartType; + if (this.datePickerService.activeInput === 'left') { + otherPart = 'right'; + selectedValue[0] = value; } else { - this.clearHoverValue(); // Clean up - this.selectedValue[this.datePickerService.getActiveIndex()] = value; - this.selectedValue = sortRangeValue(this.selectedValue); // Sort - this.datePickerService.activeDate = normalizeRangeValue(this.selectedValue); - this.calendarChange.emit(cloneDate(this.selectedValue)); - this.datePickerService.setValue(cloneDate(this.selectedValue)); - if (!this.showTime) { + otherPart = 'left'; + selectedValue[1] = value; + } + + if (!this.isAllowed(selectedValue)) { + return; + } + + this.hoverValue = selectedValue; + selectedValue = sortRangeValue(selectedValue); // Sort + this.datePickerService.setValue(selectedValue); + this.datePickerService.setActiveDate(selectedValue); + + if (emitValue) { + // If the other input has value + if (this.isBothAllowed(selectedValue)) { + this.calendarChange.emit(selectedValue); + this.clearHoverValue(); this.datePickerService.emitValue$.next(); + } else { + this.calendarChange.emit([value.clone()]); + this.datePickerService.inputPartChange$.next(otherPart!); } } } else { + if (!this.isAllowed(value)) { + return; + } this.datePickerService.setValue(value); - if (!this.showTime) { + this.datePickerService.setActiveDate(value); + if (emitValue) { this.datePickerService.emitValue$.next(); } } @@ -353,11 +359,6 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { } } - hasSelectedValue(): boolean { - const part = this.datePickerService.getActiveIndex(); - return this.selectedValue && !!this.selectedValue[part]; - } - disabledStartTime = (value: Date | Date[]): DisabledTimeConfig => { return this.disabledTime && this.disabledTime(value, 'start'); }; @@ -366,46 +367,25 @@ export class DateRangePopupComponent implements OnInit, OnChanges, OnDestroy { return this.disabledTime && this.disabledTime(value, 'end'); }; - isAllowedSelectedValue(): boolean { - const selectedValue = this.selectedValue; - if (selectedValue && selectedValue[0] && !selectedValue[1]) { - return isAllowedDate(selectedValue[0], this.disabledDate, this.disabledStartTime); - } - if (selectedValue && !selectedValue[0] && selectedValue[1]) { - return isAllowedDate(selectedValue[1], this.disabledDate, this.disabledEndTime); - } - if (selectedValue && selectedValue[0] && selectedValue[1]) { - return ( - isAllowedDate(selectedValue[0], this.disabledDate, this.disabledStartTime) && - isAllowedDate(selectedValue[1], this.disabledDate, this.disabledEndTime) - ); - } - return false; + isOneAllowed(selectedValue: SingleValue[]): boolean { + return ( + isAllowedDate(selectedValue[0]!, this.disabledDate, this.disabledStartTime) || + isAllowedDate(selectedValue[1]!, this.disabledDate, this.disabledStartTime) + ); } - timePickerDisabled(): boolean { - if (!this.hasTimePicker) { - return true; - } - - if (this.isRange) { - return !this.hasSelectedValue() || !!this.hoverValue.length; - } else { - return false; - } + isBothAllowed(selectedValue: SingleValue[]): boolean { + return ( + isAllowedDate(selectedValue[0]!, this.disabledDate, this.disabledStartTime) && + isAllowedDate(selectedValue[1]!, this.disabledDate, this.disabledEndTime) + ); } - okDisabled(): boolean { - if (!this.hasTimePicker) { - return true; - } - + isAllowed(value: CompatibleValue, isBoth: boolean = false): boolean { if (this.isRange) { - return !this.isAllowedSelectedValue() || !this.hasSelectedValue(); + return isBoth ? this.isBothAllowed(value as CandyDate[]) : this.isOneAllowed(value as CandyDate[]); } else { - return this.datePickerService.value - ? !isAllowedDate(this.datePickerService.value as CandyDate, this.disabledDate, this.disabledTime) - : false; + return isAllowedDate(value as CandyDate, this.disabledDate, this.disabledTime); } } diff --git a/components/date-picker/demo/disabled-date.ts b/components/date-picker/demo/disabled-date.ts index dab3f115651..1e61016eee4 100644 --- a/components/date-picker/demo/disabled-date.ts +++ b/components/date-picker/demo/disabled-date.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import differenceInCalendarDays from 'date-fns/differenceInCalendarDays'; import setHours from 'date-fns/setHours'; -import { DisabledTimeFn, DisabledTimePartial } from 'ng-zorro-antd/date-picker/standard-types'; +import { DisabledTimeFn, DisabledTimePartial } from 'ng-zorro-antd/date-picker'; @Component({ selector: 'nz-demo-date-picker-disabled-date', diff --git a/components/date-picker/lib/abstract-table.ts b/components/date-picker/lib/abstract-table.ts index d161272fee4..d8de82f67e3 100644 --- a/components/date-picker/lib/abstract-table.ts +++ b/components/date-picker/lib/abstract-table.ts @@ -57,8 +57,5 @@ export abstract class AbstractTable implements OnInit, OnChanges { if (changes.activeDate && !changes.activeDate.currentValue) { this.activeDate = new CandyDate(); } - if (changes.value && changes.value.currentValue) { - this.activeDate = this.value; - } } } diff --git a/components/date-picker/picker.component.ts b/components/date-picker/picker.component.ts index 3b4054ce47f..d69f84f55cc 100644 --- a/components/date-picker/picker.component.ts +++ b/components/date-picker/picker.component.ts @@ -12,6 +12,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, + ContentChild, ElementRef, EventEmitter, Input, @@ -27,12 +28,13 @@ import { } from '@angular/core'; import { slideMotion } from 'ng-zorro-antd/core/animation'; -import { CandyDate, CompatibleValue, SingleValue, sortRangeValue } from 'ng-zorro-antd/core/time'; +import { CandyDate, CompatibleValue } from 'ng-zorro-antd/core/time'; import { NzSafeAny } from 'ng-zorro-antd/core/types'; import { DateHelperService } from 'ng-zorro-antd/i18n'; import { Subject } from 'rxjs'; import { distinctUntilChanged, takeUntil } from 'rxjs/operators'; import { DatePickerService } from './date-picker.service'; +import { DateRangePopupComponent } from './date-range-popup.component'; import { RangePartType } from './standard-types'; import { PREFIX_CLASS } from './util'; @@ -133,7 +135,6 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe @Input() isRange: boolean = false; @Input() open: boolean | undefined = undefined; @Input() disabled: boolean; - @Input() disabledDate: (current: Date) => boolean; @Input() placeholder: string | string[]; @Input() allowClear: boolean; @Input() autoFocus: boolean; @@ -148,6 +149,8 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe @ViewChild('separatorElement', { static: false }) separatorElement: ElementRef; @ViewChildren('rangePickerInput') rangePickerInputs: QueryList; + @ContentChild(DateRangePopupComponent) panel: DateRangePopupComponent; + origin: CdkOverlayOrigin; inputSize: number; destroy$ = new Subject(); @@ -304,15 +307,12 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe } onClickBackdrop(): void { - if (this.isRange) { - if (this.isValidRange(this.datePickerService.value as CandyDate[])) { - this.datePickerService.emitValue$.next(); - } else { - this.datePickerService.setValue(this.datePickerService.initialValue); - this.hideOverlay(); - } - } else { + if (this.panel.isAllowed(this.datePickerService.value!, true)) { + this.updateInputValue(); this.datePickerService.emitValue$.next(); + } else { + this.datePickerService.setValue(this.datePickerService.initialValue); + this.hideOverlay(); } } @@ -359,46 +359,14 @@ export class NzPickerComponent implements OnInit, AfterViewInit, OnChanges, OnDe return this.dateHelper.format(value && (value as CandyDate).nativeDate, this.format); } - isDisabledDate(date: null | CandyDate): boolean { - return !date || (this.disabledDate && this.disabledDate(date.nativeDate)); - } - - // Check if it's a valid range value - private isValidRange(value: SingleValue[]): boolean { - if (Array.isArray(value)) { - const [start, end] = value; - return !!(start && end); - } - return false; - } - onInputKeyup(event: Event, isEnter: boolean = false): void { if (isEnter && !this.realOpenState) { this.showOverlay(); return; } - const date = this.checkValidInputDate((event as KeyboardEvent).target!); - if (!date || (this.disabledDate && this.disabledDate(date.nativeDate))) { - return; - } - if (this.isRange) { - let newValue: CompatibleValue; - const leftDate = this.checkValidInputDate(this.getInput('left')); - const rightDate = this.checkValidInputDate(this.getInput('right')); - if (this.isDisabledDate(leftDate) || this.isDisabledDate(rightDate)) { - return; - } - newValue = [leftDate, rightDate]; - if (this.isValidRange(newValue)) { - newValue = sortRangeValue(newValue); - this.datePickerService.setValue(newValue); - } - } else { - this.datePickerService.setValue(date); - } - if (isEnter) { - this.datePickerService.emitValue$.next(); + if (this.panel && date) { + this.panel.changeValueFromSelect(date, isEnter); } } diff --git a/components/date-picker/public-api.ts b/components/date-picker/public-api.ts index 50875d1cf62..c4ea7e90356 100644 --- a/components/date-picker/public-api.ts +++ b/components/date-picker/public-api.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ -export { PickerResult, PickerResultSingle, PickerResultRange, PresetRanges, PanelMode } from './standard-types'; -export { PREFIX_CLASS, getTimeConfig, isAllowedDate, isTimeValid, isTimeValidByConfig } from './util'; +export * from './standard-types'; +export * from './util'; export { NzDatePickerModule } from './date-picker.module'; export { NzDatePickerComponent } from './date-picker.component'; diff --git a/components/date-picker/range-picker.component.spec.ts b/components/date-picker/range-picker.component.spec.ts index ebb95e7afb1..f1765190e91 100644 --- a/components/date-picker/range-picker.component.spec.ts +++ b/components/date-picker/range-picker.component.spec.ts @@ -165,7 +165,8 @@ describe('NzRangePickerComponent', () => { fixtureInstance.modelValue = [new Date('2018-11-11 12:12:12'), null]; fixtureInstance.nzDisabledDate = (current: Date) => isSameDay(current, compareDate); fixture.detectChanges(); - + flush(); + fixture.detectChanges(); openPickerByClickTrigger(); const disabledCell = queryFromOverlay('td.ant-picker-cell-disabled .ant-picker-cell-inner'); expect(disabledCell.textContent!.trim()).toBe('15'); @@ -233,15 +234,17 @@ describe('NzRangePickerComponent', () => { fixtureInstance.nzDefaultPickerValue = [new Date('2012-03-18'), new Date('2019-12-12')]; fixtureInstance.modelValue = [new Date('2018-11-11'), new Date('2018-12-11')]; fixture.detectChanges(); + flush(); + fixture.detectChanges(); openPickerByClickTrigger(); expect(getFirstSelectedDayCell().textContent!.trim()).toBe('11'); })); it('should support nzDefaultPickerValue', fakeAsync(() => { - fixtureInstance.nzDefaultPickerValue = [new Date('2012-03-18'), new Date('2019-11-11')]; + fixtureInstance.nzDefaultPickerValue = [new Date('2012-01-18'), new Date('2019-11-11')]; fixture.detectChanges(); openPickerByClickTrigger(); - expect(queryFromOverlay('.ant-picker-panel .ant-picker-header-month-btn').textContent!.indexOf('3') > -1).toBeTruthy(); + expect(queryFromOverlay('.ant-picker-panel .ant-picker-header-month-btn').textContent!.indexOf('1') > -1).toBeTruthy(); expect(queryFromOverlay('.ant-picker-panel:last-child .ant-picker-header-month-btn').textContent!.indexOf('11') > -1).toBeTruthy(); })); @@ -280,6 +283,8 @@ describe('NzRangePickerComponent', () => { fixtureInstance.modelValue = [new Date('2018-11-11'), new Date('2018-11-11')]; const nzOnChange = spyOn(fixtureInstance, 'modelValueChange'); fixture.detectChanges(); + flush(); + fixture.detectChanges(); openPickerByClickTrigger(); const left = getFirstCell('left'); // Use the first cell @@ -594,6 +599,8 @@ describe('NzRangePickerComponent', () => { fixtureInstance.nzDisabledDate = (current: Date) => differenceInDays(current, initial[0]) < 0; fixtureInstance.nzShowTime = true; fixture.detectChanges(); + flush(); + fixture.detectChanges(); openPickerByClickTrigger(); // Click start date @@ -656,6 +663,12 @@ describe('NzRangePickerComponent', () => { typeInElement('2018-11-11', leftInput); fixture.detectChanges(); + + // should focus the other input + leftInput.dispatchEvent(new KeyboardEvent('keyup', { key: 'enter' })); + fixture.detectChanges(); + expect(getRangePickerRightInput(fixture.debugElement) === document.activeElement).toBeTruthy(); + typeInElement('2018-12-12', rightInput); rightInput.dispatchEvent(new KeyboardEvent('keyup', { key: 'enter' })); fixture.detectChanges(); @@ -672,6 +685,8 @@ describe('NzRangePickerComponent', () => { fixtureInstance.modelValue = [new Date('2019-11-11 11:22:33'), new Date('2019-12-12 11:22:33')]; fixtureInstance.nzShowTime = true; fixture.detectChanges(); + flush(); + fixture.detectChanges(); openPickerByClickTrigger(); const leftInput = getPickerInput(fixture.debugElement); diff --git a/components/date-picker/util.ts b/components/date-picker/util.ts index b3d088ad675..0e287f37e37 100644 --- a/components/date-picker/util.ts +++ b/components/date-picker/util.ts @@ -60,6 +60,9 @@ export function isTimeValid(value: CandyDate, disabledTime: DisabledTimeFn): boo } export function isAllowedDate(value: CandyDate, disabledDate?: DisabledDateFn, disabledTime?: DisabledTimeFn): boolean { + if (!value) { + return false; + } if (disabledDate) { if (disabledDate(value.nativeDate)) { return false;