Skip to content

Commit

Permalink
feat(module: calendar): calendar add ngModel (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
3fuyu authored and fisherspy committed Dec 13, 2018
1 parent 6b60cca commit 327d33b
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 6 deletions.
84 changes: 82 additions & 2 deletions components/calendar/calendar.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { By } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LocaleProviderService } from '../locale-provider/locale-provider.service';
import { LocaleProviderModule } from '../locale-provider/locale-provider.module';
Expand All @@ -14,7 +15,7 @@ describe('CalendarComponent', () => {
TestBed.configureTestingModule({
declarations: [TestCalendarBasicComponent],
providers: [LocaleProviderService],
imports: [LocaleProviderModule, CalendarModule]
imports: [LocaleProviderModule, CalendarModule, FormsModule]
}).compileComponents();
}));

Expand Down Expand Up @@ -58,6 +59,82 @@ describe('CalendarComponent', () => {
);
});

it('should ngModel one', () => {
component.state.date = new Date(2018, 8, 2);
component.state.show = true;
component.state.now = new Date(2018, 8, 2);
component.state.type = 'one';
const displayDay = '2';
fixture.detectChanges();
calendarEle.nativeElement
.querySelectorAll('.date .row')[1]
.querySelector('.cell')
.click();
fixture.detectChanges();
expect(calendarEle.nativeElement.querySelectorAll('.row .cell .date.date-selected')[0].innerText).toContain(
displayDay,
'ngModel one is right'
);
});

it('should write ngModel one', () => {
component.state.date = new Date(2018, 8, 2);
component.state.now = new Date(2018, 8, 2);
component.state.type = 'one';
component.state.show = true;
const displayDay = '2';
fixture.detectChanges();
calendarEle.nativeElement
.querySelectorAll('.date .row')[1]
.querySelector('.cell')
.click();
fixture.detectChanges();
expect(calendarEle.nativeElement.querySelectorAll('.row .cell .date.date-selected')[0].innerText).toContain(
displayDay,
'write ngModel one is right'
);
});

it('should ngModel range', () => {
component.state.show = true;
component.state.now = new Date(2018, 8, 2);
component.state.type = 'range';
component.state.date = [new Date(2018, 8, 2), new Date(new Date(2018, 8, 2).getFullYear(), new Date(2018, 8, 2).getMonth(), new Date(2018, 8, 2).getDate() + 1)];
const displayDay = '2';
fixture.detectChanges();
calendarEle.nativeElement
.querySelectorAll('.date .row')[1]
.querySelector('.cell')
.click();
fixture.detectChanges();
expect(calendarEle.nativeElement.querySelectorAll('.row .cell .date.date-selected')[0].innerText).toContain(
displayDay,
'ngModel range is right'
);
});

it('should write ngModel range', () => {
component.state.show = true;
component.state.now = new Date(2018, 8, 2);
component.state.type = 'range';
component.state.date = [new Date(2018, 8, 2), new Date(new Date(2018, 8, 2).getFullYear(), new Date(2018, 8, 2).getMonth(), new Date(2018, 8, 2).getDate() + 1)];
const displayDay = '2';
fixture.detectChanges();
calendarEle.nativeElement
.querySelectorAll('.date .row')[1]
.querySelector('.cell')
.click();
calendarEle.nativeElement
.querySelectorAll('.date .row')[2]
.querySelector('.cell')
.click();
fixture.detectChanges();
expect(calendarEle.nativeElement.querySelectorAll('.row .cell .date.date-selected')[0].innerText).toContain(
displayDay,
'write ngModel range is right'
);
});

it('should min date', () => {
component.state.show = true;
component.state.now = new Date(2018, 8, 2);
Expand Down Expand Up @@ -203,7 +280,8 @@ for (const key in extra) {
@Component({
selector: 'demo-calendar',
template: `
<Calendar [locale]="this.state.en ? 'enUS' : 'zhCN'"
<Calendar [(ngModel)]="this.state.date"
[locale]="this.state.en ? 'enUS' : 'zhCN'"
[enterDirection]="this.state._enterDirection"
[visible]="this.state.show"
[getDateExtra]="this.state.getDateExtra"
Expand All @@ -225,6 +303,7 @@ for (const key in extra) {
export class TestCalendarBasicComponent {
state: any = {
en: false,
date: null,
show: false,
pickTime: false,
now: new Date(2018, 8, 2),
Expand All @@ -247,6 +326,7 @@ export class TestCalendarBasicComponent {
...this.state,
...{
show: false,
date: null,
pickTime: false,
now: new Date(),
type: 'range',
Expand Down
81 changes: 79 additions & 2 deletions components/calendar/calendar.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Component,
forwardRef,
OnInit,
OnDestroy,
ViewEncapsulation,
Expand All @@ -8,6 +9,7 @@ import {
HostBinding,
EventEmitter
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Models } from './date/DataTypes';
import zhCN from './locale/zh_CN';
import enUS from './locale/en_US';
Expand All @@ -31,9 +33,10 @@ export interface StateType {
@Component({
selector: 'Calendar, nzm-calendar',
templateUrl: './calendar.component.html',
encapsulation: ViewEncapsulation.None
encapsulation: ViewEncapsulation.None,
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CalendarComponent), multi: true }]
})
export class CalendarComponent implements OnInit, OnDestroy {
export class CalendarComponent implements ControlValueAccessor, OnInit, OnDestroy {
isShow: boolean = false;
contentAnimateClass: string;
maskAnimateClass: string;
Expand Down Expand Up @@ -61,6 +64,11 @@ export class CalendarComponent implements OnInit, OnDestroy {

private _unsubscribe$ = new Subject<void>();
private _enterDirection: string;
private _dateModelType: number;
private _dateModelValue: any;
private _dateModelTime: number = 0;
private onChangeFn: (date: Date|Array<Date>) => void = () => {};
private onTouchFn: (date: Date|Array<Date>) => void = () => {};

@Input()
set locale(value) {
Expand Down Expand Up @@ -165,6 +173,39 @@ export class CalendarComponent implements OnInit, OnDestroy {

constructor(private _localeProviderService: LocaleProviderService) {}

writeValue(value: Date|Array<Date>|null): void {
this._dateModelType = null;
if (value && value instanceof Array) {
if (value.length === 0) {
console.error('[ng-zorro-antd-mobile]: calendar ngModel array need params!');
return;
}
if (this.props.type === 'one' && value.length >= 2) {
this._dateModelType = 1;
console.error('[ng-zorro-antd-mobile]: type is one, but ngmodel has more than one param, just use first one');
this.onSelectedDate(value[0]);
} else if (value.length === 1) {
this._dateModelType = 1;
this.onSelectedDate(value[0]);
} else {
this._dateModelType = 2;
this.onSelectedDate(value[0]);
this.onSelectedDate(value[1]);
}
} else if (value && value instanceof Date) {
this._dateModelType = 3;
this.onSelectedDate(value);
}
}

registerOnChange(fn: (date: Date|Array<Date>) => void): void {
this.onChangeFn = fn;
}

registerOnTouched(fn: () => void): void {
this.onTouchFn = fn;
}

receiveProps(nextProps: PropsType) {
if (nextProps.visible && nextProps.defaultValue) {
this.shortcutSelect(nextProps.defaultValue[0], nextProps.defaultValue[1], nextProps);
Expand Down Expand Up @@ -247,9 +288,45 @@ export class CalendarComponent implements OnInit, OnDestroy {
}
break;
}

this.writeModelData(date);
return newState;
}

writeModelData(date) {
if (this._dateModelValue instanceof Array) {
this._dateModelTime = this._dateModelValue.length;
} else {
this._dateModelTime = 0;
}

switch (this._dateModelType) {
case 1:
this._dateModelValue = [date];
this.onChangeFn(this._dateModelValue);
break;
case 2:
if (this._dateModelTime === 1) {
if (+date < +this._dateModelValue[0]) {
this._dateModelValue.unshift(date);
} else {
this._dateModelValue.push(date);
}
this.onChangeFn(this._dateModelValue);
} else {
this._dateModelValue = [];
this._dateModelValue.push(date);
}
break;
case 3:
this._dateModelValue = date;
this.onChangeFn(this._dateModelValue);
break;
default:
break;
}
}

onSelectedDate = (date: Date) => {
const { startDate, endDate } = this.state;
const { onSelect } = this.props;
Expand Down
15 changes: 14 additions & 1 deletion components/calendar/demo/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ for (let key in extra) {
<ListItem className="item" [extra]="_switch">
{{this.state.en ? 'Chinese' : '中文'}}
</ListItem>
<ListItem [arrow]="'horizontal'" (onClick)="onClick_0()">
{{this.state.en ? 'ngModel' : 'ngModel'}}
</ListItem>
<ListItem [arrow]="'horizontal'" (onClick)="onClick_1()">
{{this.state.en ? 'Select Date Range' : '选择日期区间'}}
</ListItem>
Expand Down Expand Up @@ -71,7 +74,8 @@ for (let key in extra) {
<ng-template #_switch>
<Switch className="right" [checked]="!this.state.en" (onChange)="this.changeLanguage()"></Switch>
</ng-template>
<Calendar [locale]="this.state.en ? 'enUS' : 'zhCN'"
<Calendar [(ngModel)]="this.state.date"
[locale]="this.state.en ? 'enUS' : 'zhCN'"
[enterDirection]="this.state.enterDirection"
[visible]="this.state.show"
[getDateExtra]="this.state.getDateExtra"
Expand All @@ -95,6 +99,7 @@ for (let key in extra) {
export class DemoCalendarBasicComponent {
state: any = {
en: false,
date: null,
show: false,
pickTime: false,
now: new Date(),
Expand All @@ -119,6 +124,7 @@ export class DemoCalendarBasicComponent {
...this.state,
...{
show: false,
date: null,
pickTime: false,
now: new Date(),
type: 'range',
Expand All @@ -141,6 +147,13 @@ export class DemoCalendarBasicComponent {
this.state.en = !this.state.en;
}

onClick_0() {
this.initPara();
this.state.show = true;
this.state.type = 'one';
this.state.date = new Date();
}

onClick_1() {
this.initPara();
this.state.show = true;
Expand Down
3 changes: 2 additions & 1 deletion components/calendar/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ Used to select a date range.

## API

Properties | Descrition | Type | Default | Required
Properties | Description | Type | Default | Required
-----------|------------|------|--------|--------
\[(ngModel)\]|ngModel|Array\<Date\> \| Date|<span> </span>|false
enterDirection|enter direction |'horizontal' \| 'vertical'| vertical|false
locale|locale|Models.Locale|<span> </span>|false
onCancel|on cancel|() => void|<span> </span>|false
Expand Down
1 change: 1 addition & 0 deletions components/calendar/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ subtitle: 日历

属性 | 说明 | 类型 | 默认值 | 必选
----|-----|------|------|------
\[(ngModel)\]|ngModel|Array\<Date\> \| Date|<span> </span>|false
enterDirection | 入场方向 vertical: 垂直 horizontal: 水平 | 'horizontal' \| 'vertical'| vertical | false
locale | 本地化 | Models.Locale | <span> </span> | false
onCancel | 关闭时回调 | () => void | <span> </span> | false
Expand Down

0 comments on commit 327d33b

Please sign in to comment.