diff --git a/src/components/calendar/nz-calendar.component.ts b/src/components/calendar/nz-calendar.component.ts index 9923012ff0d..1557759392c 100644 --- a/src/components/calendar/nz-calendar.component.ts +++ b/src/components/calendar/nz-calendar.component.ts @@ -35,6 +35,7 @@ export interface DayInterface { isNextMonth: boolean; isCurrentDay: boolean; isSelectedDay: boolean; + isInRange?: boolean; title: string; date: Moment; disabled: boolean; @@ -46,6 +47,8 @@ export interface WeekInterface { days: DayInterface[]; } +export enum RangePart { Start = 0, End = 1 } + @Component({ selector : 'nz-calendar', encapsulation: ViewEncapsulation.None, @@ -99,57 +102,62 @@ export interface WeekInterface { [class.ant-patch-full-height]="nzDatePicker" *ngIf="nzMode == 'year'"> - - - {{ _min }} - - + + + {{ _min }} + + - - - -
-
{{ day.number }}
-
- - -
+ + + +
+
{{ day.number }}
+
+ +
- - - - -
{{ day.number }}
- -
- +
+ +
+ + +
+ {{ day.number }} +
+ +
+ - - - - - - + + - - + + + + + + +
-
-
{{ month.name }}
-
- - -
-
-
-
- {{ month.name }} +
+
+
{{ month.name }}
+
+ +
-
+
+ {{ month.name }} +
+
@@ -206,6 +214,7 @@ export class NzCalendarComponent implements OnInit { private _datePicker = false; private _fullScreen = true; private _showHeader = true; + private _isRange = false; _el: HTMLElement; _weeksCalendar: WeekInterface[] = []; @@ -213,17 +222,21 @@ export class NzCalendarComponent implements OnInit { _listOfWeekName: string[] = []; _listOfMonthName: string[] = []; _listOfYearName: number[] = []; + _disabledDate: (value: Date) => boolean; _yearUnit = '年'; _monthUnit = '月'; _showMonth = moment(new Date()).month(); _showYear = moment(new Date()).year(); _value: Date = new Date(); + _rangeValue: Date[] = [null, null]; + _hoveringSelectValue: Date; _locale = this._localeService.getLocale().locale; @ContentChild('dateCell') dateCell: TemplateRef; @ContentChild('monthCell') monthCell: TemplateRef; @Output() nzClickDay: EventEmitter = new EventEmitter(); @Output() nzClickMonth: EventEmitter = new EventEmitter(); + @Output() nzHoverDay: EventEmitter = new EventEmitter(); @Input() nzClearTime = true; @Input() nzMode = 'year'; @@ -245,7 +258,24 @@ export class NzCalendarComponent implements OnInit { return this._showHeader; } - @Input() nzDisabledDate: (date: Date) => boolean = () => false; + @Input() + set nzIsRange(value: boolean) { + this._isRange = toBoolean(value); + } + + get nzIsRange(): boolean { + return this._isRange; + } + + @Input() + set nzDisabledDate(value: (value: Date) => boolean) { + this._disabledDate = value; + this._buildCalendar(); + } + + get nzDisabledDate(): (value: Date) => boolean { + return this._disabledDate; + } @Input() @HostBinding('class.ant-patch-full-height') @@ -272,6 +302,29 @@ export class NzCalendarComponent implements OnInit { return this._value || new Date(); } + @Input() + get nzRangeValue(): Date[] { + return this._rangeValue; + } + + set nzRangeValue(value: Date[]) { + this._rangeValue = value; + this._buildCalendar(); + } + + @Input() + get nzHoveringSelectValue(): Date { + return this._hoveringSelectValue; + } + + set nzHoveringSelectValue(value: Date) { + if (this._hoveringSelectValue === value) { + return; + } + this._hoveringSelectValue = value; + this._buildCalendar(); + } + @Input() set nzShowYear(value: number) { this._showYear = value; @@ -328,6 +381,44 @@ export class NzCalendarComponent implements OnInit { this.nzClickMonth.emit(month); } + _onDayHover($event: MouseEvent, day: DayInterface): void { + $event.preventDefault(); + $event.stopPropagation(); + if (day.disabled || day.date.isSame(this._hoveringSelectValue)) { + return; + } + this.nzHoverDay.emit(day); + } + + _isSelectedDay(date: Moment, month: Moment): boolean { + if (this.nzIsRange) { + return (date.isSame(this._rangeValue[RangePart.Start], 'day') + || date.isSame(this._rangeValue[RangePart.End], 'day') + || date.isSame(this._hoveringSelectValue, 'day')) + && date.month() === month.month(); + } else { + return date.isSame(this.nzValue, 'day'); + } + } + + _isInRange(date: Moment, month: Moment): boolean { + let ghostDate: Date; + if (this.nzIsRange && date.month() === month.month()) { + if (this._rangeValue.every(e => moment(e).isValid())) { + return date.isBetween.apply(date, this._rangeValue); + } + ghostDate = this._rangeValue.find(e => moment(e).isValid()); + if (ghostDate && this._hoveringSelectValue) { + const start = moment.min(moment(ghostDate), moment(this._hoveringSelectValue)).toDate(); + const end = moment.max(moment(ghostDate), moment(this._hoveringSelectValue)).toDate(); + return date.isBetween(start, end); + } + return false; + } else { + return false; + } + } + _buildMonth(d: Moment): WeekInterface[] { const weeks: WeekInterface[] = []; const _rawDate = this._removeTime(d); @@ -355,7 +446,8 @@ export class NzCalendarComponent implements OnInit { isLastMonth : date.month() < month.month(), isNextMonth : date.month() > month.month(), isCurrentDay : date.isSame(new Date(), 'day'), - isSelectedDay: date.isSame(this.nzValue, 'day'), + isSelectedDay: this._isSelectedDay(date, month), + isInRange : this._isInRange(date, month), title : date.format('YYYY-MM-DD'), date, disabled : this.nzDisabledDate && this.nzDisabledDate(date.toDate()), diff --git a/src/components/datepicker/nz-datepicker.module.ts b/src/components/datepicker/nz-datepicker.module.ts index b6d8bbc39d1..bfee51fb829 100644 --- a/src/components/datepicker/nz-datepicker.module.ts +++ b/src/components/datepicker/nz-datepicker.module.ts @@ -8,11 +8,12 @@ import { NzLocaleModule } from '../locale/index'; import { NzTimePickerModule } from '../time-picker/nz-timepicker.module'; import { NzUtilModule } from '../util/nz-util.module'; import { NzDatePickerComponent } from './nz-datepicker.component'; +import { NzRangePickerComponent } from './nz-rangepicker.component'; @NgModule({ imports : [ CommonModule, NzTimePickerModule, NzUtilModule, NzInputModule, NzCalendarModule, FormsModule, OverlayModule, NzLocaleModule ], - declarations: [ NzDatePickerComponent ], - exports : [ NzDatePickerComponent ] + declarations: [ NzDatePickerComponent, NzRangePickerComponent ], + exports : [ NzDatePickerComponent, NzRangePickerComponent ] }) export class NzDatePickerModule { } diff --git a/src/components/datepicker/nz-rangepicker.component.ts b/src/components/datepicker/nz-rangepicker.component.ts new file mode 100644 index 00000000000..904f40c3656 --- /dev/null +++ b/src/components/datepicker/nz-rangepicker.component.ts @@ -0,0 +1,612 @@ +import { ConnectedOverlayPositionChange, ConnectionPositionPair } from '@angular/cdk/overlay'; +import { + forwardRef, + ChangeDetectorRef, + Component, + ElementRef, + Input, + OnInit, + QueryList, + ViewChild, + ViewChildren, + ViewEncapsulation +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import * as moment from 'moment'; +import { DayInterface, MonthInterface, RangePart } from '../calendar/nz-calendar.component'; +import { dropDownAnimation } from '../core/animation/dropdown-animations'; +import { DEFAULT_DATEPICKER_POSITIONS } from '../core/overlay/overlay-position-map'; +import { NzLocaleService } from '../locale/index'; +import { NzTimePickerInnerComponent } from '../time-picker/nz-timepicker-inner.component'; +import { toBoolean } from '../util/convert'; + +@Component({ + selector: 'nz-rangepicker', + encapsulation: ViewEncapsulation.None, + animations: [ + dropDownAnimation + ], + template: ` + + + + ~ + + + + + + + + + + + + + + + + + + + `, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => NzRangePickerComponent), + multi: true + } + ], + styleUrls: [ + './style/index.less', + './style/patch.less' + ] +}) +export class NzRangePickerComponent implements ControlValueAccessor, OnInit { + private _disabled = false; + private _showTime: Partial = null; + private _now = moment(); + private _el; + private _oldValue: Date[] = this._defaultRangeValue; + private _value: Date[] = this._defaultRangeValue; + + // avoid reference types + private get _defaultRangeValue(): Date[] { + return [null, null]; + } + + private get start(): moment.Moment { + return moment(this._value[RangePart.Start]); + } + + private get end(): moment.Moment { + return moment(this._value[RangePart.End]); + } + + _part = RangePart; // provided to template + hoveringSelectValue: Date; + _open; + _disabledDate: (value: Date) => boolean; + _disabledDatePart: Array<(value: Date) => boolean> = [null, null]; + _mode = ['year', 'year']; + _selectedMonth: number[] = []; + _selectedYear: number[] = []; + _selectedDate: number[] = []; + _showMonth = [this._now.month(), this._now.clone().add(1, 'month').month()]; + _showYear = [this._now.year(), this._now.year()]; + _yearPanel: string[][] = []; + _startDecade = new Array(2).fill(Math.floor(this._showYear[RangePart.Start] / 10) * 10); + _triggerWidth = 0; + _dropDownPosition = 'bottom'; + _positions: ConnectionPositionPair[] = [...DEFAULT_DATEPICKER_POSITIONS]; + @ViewChild('trigger') trigger; + onTouched: () => void = () => null; + onChange: (value: Date[]) => void = () => null; + @Input() nzSize = ''; + @Input() nzFormat = 'YYYY-MM-DD'; + @Input() nzAllowClear = true; + @Input() nzPlaceholder: string[] = [this._locale.translate('DateTime.chooseStartDatePlease'), this._locale.translate('DateTime.chooseEndDatePlease')]; + @ViewChildren(NzTimePickerInnerComponent) timePickerInner: QueryList; + + get showClearIcon(): boolean { + return this._isComplete() && !this.nzDisabled && this.nzAllowClear; + } + + @Input() + set nzShowTime(value: Partial) { + if (typeof value === 'string' || typeof value === 'boolean') { + this._showTime = toBoolean(value) ? {} : null; + } else { + this._showTime = value; + } + } + + get nzShowTime(): Partial { + return this._showTime; + } + + @Input() + set nzDisabled(value: boolean) { + this._disabled = toBoolean(value); + this._closeCalendar(); + } + + get nzDisabled(): boolean { + return this._disabled; + } + + get nzValue(): Date[] { + return this._value || this._defaultRangeValue; + } + + set nzValue(value: Date[]) { + this._updateValue(value); + } + + @Input() + set nzDisabledDate(value: (value: Date) => boolean) { + this._disabledDate = value; + this._bindDisabledDateToPart(); + } + + get nzDisabledDate(): (value: Date) => boolean { + return this._disabledDate; + } + + constructor(private _elementRef: ElementRef, private _cdr: ChangeDetectorRef, private _locale: NzLocaleService) { + this._el = this._elementRef.nativeElement; + } + + ngOnInit(): void { + this._generateYearPanel(); + } + + _bindDisabledDateToPart(): void { + // when the mode is month, not needed disable it + this._disabledDatePart[RangePart.Start] = this._mode[RangePart.Start] === 'month' ? null : this._disabledDate; + this._disabledDatePart[RangePart.End] = this._mode[RangePart.End] === 'month' ? null : this._disabledDate; + } + + _generateYearPanel(): void { + let _t = []; + for (let i = 0; i < 10; i++) { + if (i === 1 || i === 4 || i === 7 || i === 9) { + _t.push(i); + this._yearPanel.push(_t); + _t = []; + } else { + _t.push(i); + } + } + this._yearPanel[0].unshift('start'); + this._yearPanel[3].push('end'); + } + + _openCalendar(): void { + if (this.nzDisabled) { + return; + } + this._mode = ['year', 'year']; + this._open = true; + this._setTriggerWidth(); + this._initShow(); + } + + _closeCalendar(): void { + if (!this._open) { + return; + } + if (this._isComplete()) { + this._onChange(); + } else { + this._value = [...this._oldValue]; + } + this._open = false; + } + + _clearValue(e: MouseEvent): void { + e.preventDefault(); + e.stopPropagation(); + this.nzValue = this._defaultRangeValue; + this.onChange(this._value); + } + + _setTriggerWidth(): void { + this._triggerWidth = this.trigger.nativeElement.getBoundingClientRect().width; + } + + _setShowYear(year: number, part: RangePart, $event: MouseEvent): void { + $event.stopPropagation(); + this._showYear[part] = year; + this._mode[part] = 'month'; + } + + _isValid(part: RangePart): boolean { + return moment(this._value[part]).isValid(); + } + + _isComplete(): boolean { + return this.start.isValid() && this.end.isValid(); + } + + _changeTime($event: Date, part: RangePart): void { + this._value[part] = $event; + } + + _blurInput(box: HTMLInputElement, part: RangePart): void { + if (Date.parse(box.value)) { + this._value[part] = new Date(box.value); + this._onChange(); + } + } + + _hoverDay(day: DayInterface): void { + if (!this._isComplete() && this._value.some(e => moment(e).isValid())) { + this.hoveringSelectValue = day.date.toDate(); + } else { + this.hoveringSelectValue = null; + } + } + + _clickDay(day: DayInterface, part: RangePart): void { + const newDate = day.date.toDate(); + // if have completed, then reset + if (this._isComplete()) { + this._value = this._defaultRangeValue; + this._value[part] = newDate; + this.rangeValueSort(); + return; + } + if (moment(this._value[part]).isValid()) { + if (part === RangePart.Start) { + this._value[RangePart.End] = newDate; + } else { + this._value[RangePart.Start] = newDate; + } + } else { + this._value[part] = newDate; + } + // the result depends the before step + if (this._isComplete()) { + this.rangeValueSort(); + if (!this.nzShowTime) { + this._closeCalendar(); + return; + } + this._initShow(); + } + this.rangeValueSort(); + } + + _clickMonth(month: MonthInterface, part: RangePart): void { + this._showMonth[part] = month.index; + this._mode[part] = 'year'; + this._bindDisabledDateToPart(); + this.adjustShowMonth(); + } + + _changeTimeView($event: MouseEvent): void { + $event.stopPropagation(); + this._mode = ['time', 'time']; + this.setSelectedValue(); + setTimeout(_ => { + this.timePickerInner.forEach(e => e._initPosition()); + }); + } + + _changeYearView($event: MouseEvent): void { + $event.stopPropagation(); + this._mode = ['year', 'year']; + } + + _showBtn(part: RangePart): boolean { + if (this._mode[part] === 'month') { + return true; + } + const showStart = moment().month(this._showMonth[RangePart.Start]).year(this._showYear[RangePart.Start]); + const showEnd = moment().month(this._showMonth[RangePart.End]).year(this._showYear[RangePart.End]); + return !showStart.add(1, 'month').isSame(showEnd, 'month'); + } + + _preYear(part: RangePart): void { + this._showYear[part] = this._showYear[part] - 1; + this.adjustShowMonth(); + } + + _nextYear(part: RangePart): void { + this._showYear[part] = this._showYear[part] + 1; + this.adjustShowMonth(); + } + + _preMonth(part: RangePart): void { + if (this._showMonth[part] - 1 < 0) { + this._showMonth[part] = 11; + this._preYear(part); + } else { + this._showMonth[part] = this._showMonth[part] - 1; + } + } + + _nextMonth(part: RangePart): void { + if (this._showMonth[part] + 1 > 11) { + this._showMonth[part] = 0; + this._nextYear(part); + } else { + this._showMonth[part] = this._showMonth[part] + 1; + } + } + + _preDecade(part: RangePart): void { + this._startDecade[part] = this._startDecade[part] - 10; + } + + _nextDecade(part: RangePart): void { + this._startDecade[part] = this._startDecade[part] + 10; + } + + rangeValueSort(): void { + if (this.start.isValid() && this.end.isValid() && this.start.isAfter(this.end)) { + this._value = this._value.reverse(); + } else { + this._value = this._value.concat(); + } + } + + _initShow(): void { + if (this.start.isValid()) { + this._showMonth[RangePart.Start] = this.start.month(); + this._showYear[RangePart.Start] = this.start.year(); + } else { + this._showMonth[RangePart.Start] = this._now.month(); + this._showYear[RangePart.Start] = this._now.year(); + } + if (this.end.isValid() && !this.start.isSameOrAfter(this.end, 'month')) { + this._showMonth[RangePart.End] = this.end.month(); + this._showYear[RangePart.End] = this.end.year(); + } else { + const nextMonthOfStart = this.start.clone().add(1, 'month'); + const nextMonthOfNow = this._now.clone().add(1, 'month'); + this._showMonth[RangePart.End] = this.start.isValid() ? nextMonthOfStart.month() : nextMonthOfNow.month(); + this._showYear[RangePart.End] = this.start.isValid() ? nextMonthOfStart.year() : nextMonthOfNow.year(); + } + this._showMonth = this._showMonth.concat(); + this._showYear = this._showYear.concat(); + } + + adjustShowMonth(): void { + if (this._showYear[RangePart.Start] === this._showYear[RangePart.End] && this._showMonth[RangePart.Start] === this._showMonth[RangePart.End]) { + this._nextMonth(RangePart.End); + } + } + + onPositionChange(position: ConnectedOverlayPositionChange): void { + const _position = position.connectionPair.originY === 'bottom' ? 'top' : 'bottom'; + if (this._dropDownPosition !== _position) { + this._dropDownPosition = _position; + this._cdr.detectChanges(); + } + } + + setSelectedValue(): void { + this._selectedYear = [this.start.year(), this.end.year()]; + this._selectedMonth = [this.start.month(), this.end.month()]; + this._selectedDate = [this.start.date(), this.end.date()]; + } + + isValueChange(): boolean { + return this._value.some((value: Date, index: number) => { + return this._oldValue[index] === null + || (moment.isDate(this._oldValue[index]) + && moment.isDate(value) + && this._oldValue[index].getTime() !== value.getTime()); + }); + } + + writeValue(value: Date[]): void { + this._updateValue(value); + } + + registerOnChange(fn: (_: Date[]) => {}): void { + this.onChange = fn; + } + + registerOnTouched(fn: () => {}): void { + this.onTouched = fn; + } + + setDisabledState(isDisabled: boolean): void { + this.nzDisabled = isDisabled; + } + + private _updateValue(value: Date[]): void { + if (Array.isArray(value) && value.length === 2) { + this._value = [value[RangePart.Start], value[RangePart.End]]; + } else { + this._value = this._defaultRangeValue; + } + this._oldValue = [...this._value]; + } + + private _onChange(): void { + if (this._isValid(RangePart.Start) && this._isValid(RangePart.End) && this.isValueChange()) { + this.onChange(this._value); + this._oldValue = [...this._value]; + } + } +} diff --git a/src/components/datepicker/style/patch.less b/src/components/datepicker/style/patch.less index 73a9ee1484a..fa731742aeb 100644 --- a/src/components/datepicker/style/patch.less +++ b/src/components/datepicker/style/patch.less @@ -14,3 +14,27 @@ nz-datepicker { top: -2px; } } + +.ant-input > .@{calendar-prefix-cls}-range-picker-input { + background-color: transparent; + border: 0; + height: 99%; + outline: 0; + width: 43%; + text-align: center; + vertical-align: top; + .placeholder(); + + &[disabled] { + cursor: not-allowed; + } + + &:focus { + border: 0; + box-shadow: none; + } +} + +.@{calendar-prefix-cls}-time-picker-body { + height: 247px; +} diff --git a/src/components/locale/locales/en-US.ts b/src/components/locale/locales/en-US.ts index 04cff08cafd..2edb6f361b0 100644 --- a/src/components/locale/locales/en-US.ts +++ b/src/components/locale/locales/en-US.ts @@ -34,6 +34,8 @@ export const enUS: NzLocale = { chooseDate: 'Select date', chooseTimePlease: 'Select time', chooseDatePlease: 'Select date', + chooseStartDatePlease: 'Start date', + chooseEndDatePlease: 'End date', thisMoment: 'This moment', today: 'Today', ok: 'Ok', diff --git a/src/components/locale/locales/ru-RU.ts b/src/components/locale/locales/ru-RU.ts index b8dc4ecaed0..20ed84b439e 100644 --- a/src/components/locale/locales/ru-RU.ts +++ b/src/components/locale/locales/ru-RU.ts @@ -34,6 +34,8 @@ export const ruRU: NzLocale = { chooseDate: 'Выберите дату', chooseTimePlease: 'Выберите время', chooseDatePlease: 'Выберите дату', + chooseStartDatePlease: 'Дата начала', + chooseEndDatePlease: 'Дата окончания', thisMoment: 'Сейчас', today: 'Сегодня', ok: 'Ок', diff --git a/src/components/locale/locales/tr-TR.ts b/src/components/locale/locales/tr-TR.ts index b5076ac1fc8..eff1f26303c 100644 --- a/src/components/locale/locales/tr-TR.ts +++ b/src/components/locale/locales/tr-TR.ts @@ -34,6 +34,8 @@ export const trTR: NzLocale = { chooseDate: 'Tarih seçin', chooseTimePlease: 'Saat seçin', chooseDatePlease: 'Tarih seçin', + chooseStartDatePlease: 'Başlangıç tarihi', + chooseEndDatePlease: 'Bitiş tarihi', thisMoment: 'Şimdi', today: 'Bugün', ok: 'Tamam', diff --git a/src/components/locale/locales/zh-CN.ts b/src/components/locale/locales/zh-CN.ts index 9984753a68e..53e2a4b9350 100644 --- a/src/components/locale/locales/zh-CN.ts +++ b/src/components/locale/locales/zh-CN.ts @@ -34,6 +34,8 @@ export const zhCN: NzLocale = { chooseDate: '选择日期', chooseTimePlease: '请选择时间', chooseDatePlease: '请选择日期', + chooseStartDatePlease: '开始日期', + chooseEndDatePlease: '结束日期', thisMoment: '此刻', today: '今天', ok: '确 定', diff --git a/src/components/locale/locales/zh-TW.ts b/src/components/locale/locales/zh-TW.ts index 70fc71de9ff..eb77e22b908 100644 --- a/src/components/locale/locales/zh-TW.ts +++ b/src/components/locale/locales/zh-TW.ts @@ -34,6 +34,8 @@ export const zhTW: NzLocale = { chooseDate: '選擇日期', chooseTimePlease: '请選擇時間', chooseDatePlease: '请選擇日期', + chooseStartDatePlease: '開始日期', + chooseEndDatePlease: '結束日期', thisMoment: '此刻', today: '今天', ok: '確 定', diff --git a/src/components/locale/nz-locale.class.ts b/src/components/locale/nz-locale.class.ts index c3ba09a5c17..824ba100a27 100644 --- a/src/components/locale/nz-locale.class.ts +++ b/src/components/locale/nz-locale.class.ts @@ -33,6 +33,8 @@ export class NzLocale { chooseDate: string; chooseTimePlease: string; chooseDatePlease: string; + chooseStartDatePlease: string; + chooseEndDatePlease: string; thisMoment: string; today: string; ok: string; diff --git a/src/components/ng-zorro-antd.module.ts b/src/components/ng-zorro-antd.module.ts index 1a8a8b3ce27..3a442499c0c 100644 --- a/src/components/ng-zorro-antd.module.ts +++ b/src/components/ng-zorro-antd.module.ts @@ -134,6 +134,7 @@ export { NzCascaderComponent } from './cascader/nz-cascader.component'; export { NzCheckboxGroupComponent } from './checkbox/nz-checkbox-group.component'; export { NzCheckboxComponent } from './checkbox/nz-checkbox.component'; export { NzDatePickerComponent } from './datepicker/nz-datepicker.component'; +export { NzRangePickerComponent } from './datepicker/nz-rangepicker.component'; export { NzFormControlComponent } from './form/nz-form-control.component'; export { NzFormExplainComponent } from './form/nz-form-explain.directive'; export { NzFormExtraDirective } from './form/nz-form-extra.directive'; diff --git a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-basic.component.ts b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-basic.component.ts index 5adeef5fac8..b98665d8642 100644 --- a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-basic.component.ts +++ b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-basic.component.ts @@ -3,9 +3,17 @@ import { Component } from '@angular/core'; @Component({ selector: 'nz-demo-datepicker-basic', template: ` - `, + + + `, styles : [] }) export class NzDemoDatePickerBasicComponent { _date = null; + _dateRange = [null, null]; + + constructor() { + } + } diff --git a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disable-date.component.ts b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disable-date.component.ts index 4c4e8ed62ca..5a12a9eb197 100644 --- a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disable-date.component.ts +++ b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disable-date.component.ts @@ -6,17 +6,20 @@ import * as moment from 'moment'; template: ` + `, styles : [] }) export class NzDemoDatePickerDisableDateComponent { _date = null; _moment = null; - _disabledDate = function (current) { + _dateRange = [null, null]; + + _disabledDate(current: Date): boolean { return current && current.getTime() > Date.now(); - }; + } - _disabledMonth = function (current) { + _disabledMonth(current: Date): boolean { return current && moment(current).day(0).valueOf() > moment().valueOf(); - }; + } } diff --git a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disabled.component.ts b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disabled.component.ts index 36e28373028..49ae7f873c3 100644 --- a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disabled.component.ts +++ b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-disabled.component.ts @@ -3,9 +3,15 @@ import { Component } from '@angular/core'; @Component({ selector: 'nz-demo-datepicker-disabled', template: ` - `, + + `, styles : [] }) export class NzDemoDatePickerDisabledComponent { _date = new Date(); + _dateRange = [new Date(), new Date(Date.now() + 3600 * 24 * 5 * 1000)]; + + constructor() { + } + } diff --git a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-formatter.component.ts b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-formatter.component.ts index 619ab596be3..de8b9a4d2a8 100644 --- a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-formatter.component.ts +++ b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-formatter.component.ts @@ -5,10 +5,16 @@ import { Component } from '@angular/core'; template: ` + + `, styles : [] }) export class NzDemoDatePickerFormatterComponent { _date = new Date(); _month = new Date(); + _dateRange = [new Date(), new Date(Date.now() + 3600 * 24 * 5 * 1000)]; + constructor() { + } + } diff --git a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-size.component.ts b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-size.component.ts index ff7980a611d..39d9c9b0734 100644 --- a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-size.component.ts +++ b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-size.component.ts @@ -3,11 +3,24 @@ import { Component } from '@angular/core'; @Component({ selector: 'nz-demo-datepicker-size', template: ` - - - `, + + + + + + + + + `, styles : [] }) export class NzDemoDatePickerSizeComponent { + size = 'default'; _date = null; + _month = null; + _dateRange = [null, null]; + + constructor() { + } + } diff --git a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-time.component.ts b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-time.component.ts index b1e3b0a2d6a..eadad00b594 100644 --- a/src/showcase/nz-demo-datepicker/nz-demo-datepicker-time.component.ts +++ b/src/showcase/nz-demo-datepicker/nz-demo-datepicker-time.component.ts @@ -3,10 +3,13 @@ import { Component } from '@angular/core'; @Component({ selector: 'nz-demo-datepicker-time', template: ` - `, + + + `, styles : [] }) export class NzDemoDatePickerTimeComponent { _date = null; + _dateRange = [null, null]; } diff --git a/src/showcase/nz-demo-datepicker/nz-demo-datepicker.html b/src/showcase/nz-demo-datepicker/nz-demo-datepicker.html index e405346e067..aa25eac407d 100644 --- a/src/showcase/nz-demo-datepicker/nz-demo-datepicker.html +++ b/src/showcase/nz-demo-datepicker/nz-demo-datepicker.html @@ -28,7 +28,7 @@

代码演示选择框的不可用状态。

- +

可以设置 nzDisabledDate 方法,来约束开始和结束日期。

@@ -61,6 +61,64 @@

代码演示API

+

日期类组件包括以下三种形式。

+
    +
  • nz-datepicker
  • +
  • nz-datepicker [nzMode='month']
  • +
  • nz-rangepicker
  • +
+

共同的 API

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数说明类型默认值
nzSize输入框大小,large 高度为 32px,small 为 22px,默认是 28pxStringmonth
nzFormat展示的日期格式,配置参考 + Moment.js文档 + String"YYYY-MM-DD"
nzDisabled禁用booleanfalse
nzAllowClear是否显示清除按钮booleantrue
nzShowTime时间选项,参见 nz-timepicker 参数boolean | NzTimePickerInnerComponentnull
nzDisabledDate用于禁用日期的回调函数,返回true表示禁用此日期(Date) => boolean
+

nz-datepicker

@@ -78,44 +136,43 @@

API

- - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + + + +
当前日期
nzMode选择器模式, month 只选择到月份,day 选择到天String"day"
nzSize输入框大小,large 高度为 32px,small 为 22px,默认是 28pxStringmonth
nzFormat展示的日期格式,配置参考 - Moment.js文档 - nzPlaceholder输入框提示文字 String"YYYY-MM-DD"
nzDisabled禁用boolfalse
nzDisabledDate用于禁用日期的回调函数,返回true表示禁用此日期function(date)
nzShowTime时间选项,参见nz-timepicker参数nullnzMode选择器模式, month 只选择到月份,day 选择到天String"day"
+

nz-rangepicker

+ + + + + + + + + + + + + + + + + + + + + + + +
参数说明类型默认值
ngModel展示日期[Date, Date]当前日期
nzPlaceholder输入框提示文字[String, String]
diff --git a/src/showcase/nz-demo-locale/nz-demo-locale-all.component.ts b/src/showcase/nz-demo-locale/nz-demo-locale-all.component.ts index 6dbc08c64fb..8244ca59944 100644 --- a/src/showcase/nz-demo-locale/nz-demo-locale-all.component.ts +++ b/src/showcase/nz-demo-locale/nz-demo-locale-all.component.ts @@ -78,6 +78,7 @@ export class NzDemoLocaleAllComponent implements OnInit { +