Skip to content

Commit

Permalink
feat(module:time-picker): support 12-hour with nzUse12Hours (#3127)
Browse files Browse the repository at this point in the history
  • Loading branch information
kekehaoz authored and wilsoncook committed Apr 18, 2019
1 parent e30a9be commit 7c52774
Show file tree
Hide file tree
Showing 12 changed files with 518 additions and 17 deletions.
14 changes: 14 additions & 0 deletions components/time-picker/demo/use12Hours.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
order: 9
title:
zh-CN: 12小时制
en-US: 12 hours
---

## zh-CN

12小时制的时间选择器,默认format为 `h:mm:ss a`

## en-US

TimePicker of 12 hours with default format `h:mm:ss a`
19 changes: 19 additions & 0 deletions components/time-picker/demo/use12Hours.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-time-picker-use12Hours',
template: `
<nz-time-picker [(ngModel)]="time" [nzUse12Hours]="true"></nz-time-picker>
<nz-time-picker [(ngModel)]="time" [nzUse12Hours]="true" nzFormat="h:mm a"></nz-time-picker>
`,
styles: [
`
nz-time-picker {
margin: 0 8px 12px 0;
}
`
]
})
export class NzDemoTimePickerUse12HoursComponent {
time: Date | null = null;
}
1 change: 1 addition & 0 deletions components/time-picker/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ By clicking the input box, you can select a time from a popup panel.
| `[nzOpen]` | whether to popup panel, double binding | `boolean` | `false` |
| `[nzPlaceHolder]` | display when there's no value | `string` | `"Select a time"` |
| `[nzPopupClassName]` | className of panel | `string` | `''` |
| `[nzUse12Hours]` | display as 12 hours format, with default format `h:mm:ss a` | `boolean` | `false` |
| `(ngModelChange)` | a callback function, can be executed when the selected time is changing | `EventEmitter<Date>` | - |
| `(nzOpenChange)` | a callback function which will be called while panel opening/closing | `EventEmitter<boolean>` | - |

Expand Down
1 change: 1 addition & 0 deletions components/time-picker/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ title: TimePicker
| `[nzOpen]` | 面板是否打开,可双向绑定 | `boolean` | `false` |
| `[nzPlaceHolder]` | 没有值的时候显示的内容 | `string` | `"请选择时间"` |
| `[nzPopupClassName]` | 弹出层类名 | `string` | `''` |
| `[nzUse12Hours]` | 使用12小时制,为true时format默认为`h:mm:ss a` | `boolean` | `false` |
| `(ngModelChange)` | 时间发生变化的回调 | `EventEmitter<Date>` | - |
| `(nzOpenChange)` | 面板打开/关闭时的回调 | `EventEmitter<boolean>` | - |

Expand Down
18 changes: 18 additions & 0 deletions components/time-picker/nz-time-picker-panel.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,24 @@
</ng-container>
</ul>
</div>
<div
*ngIf="nzUse12Hours"
#use12HoursListElement
class="{{ prefixCls }}-select">
<ul>
<ng-container *ngFor="let range of use12HoursRange ">
<li
*ngIf="!nzHideDisabledOptions"
(click)="select12Hours(range)"
class="
{{ isSelected12Hours(range) ? prefixCls + '-select-option-selected' : '' }}
"
>
{{ range.value }}
</li>
</ng-container>
</ul>
</div>
</div>
<div class="{{ prefixCls }}-addon" *ngIf="nzAddOn">
<ng-template [ngTemplateOutlet]="nzAddOn"></ng-template>
Expand Down
195 changes: 193 additions & 2 deletions components/time-picker/nz-time-picker-panel.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NzI18nModule } from '../i18n/nz-i18n.module';
import { NzTimePickerPanelComponent } from './nz-time-picker-panel.component';

describe('time-picker-panel', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule, NzI18nModule],
schemas: [NO_ERRORS_SCHEMA],
declarations: [NzTimePickerPanelComponent, NzTestTimePanelComponent, NzTestTimePanelDisabledComponent]
declarations: [
NzTimePickerPanelComponent,
NzTestTimePanelComponent,
NzTestTimePanelDisabledComponent,
NzTest12HourTimePanelComponent,
NzTest12HourTimePanelDisabeledComponent
]
});
TestBed.compileComponents();
}));
Expand Down Expand Up @@ -149,6 +154,134 @@ describe('time-picker-panel', () => {
expect(listOfSelectContainer[2].firstElementChild.children.length).toBe(54);
}));
});
describe('12-hour time-picker-panel', () => {
let panelElement: DebugElement;
let fixture12Hour: ComponentFixture<NzTest12HourTimePanelComponent>;
let testComponent: NzTest12HourTimePanelComponent;
beforeEach(() => {
fixture12Hour = TestBed.createComponent(NzTest12HourTimePanelComponent);
testComponent = fixture12Hour.debugElement.componentInstance;
fixture12Hour.detectChanges();
panelElement = fixture12Hour.debugElement.query(By.directive(NzTimePickerPanelComponent));
});
it('basic 12-hour time-picker-panel', fakeAsync(() => {
fixture12Hour.detectChanges();
expect(testComponent.nzTimePickerPanelComponent.enabledColumns).toBe(4);
const listColumns: HTMLElement[] = panelElement.nativeElement.querySelectorAll('.ant-time-picker-panel-select');
expect(listColumns[0].querySelectorAll('li')[0].innerText).toBe('12');
const hour12labels = listColumns[3].querySelectorAll('li');
expect(hour12labels[0].innerText).toBe('am');
expect(hour12labels[1].innerText).toBe('pm');
}));
it('default value 12-hour time-picker-panel', fakeAsync(() => {
testComponent.nzTimePickerPanelComponent.opened = true;
fixture12Hour.detectChanges();
tick(1000);
fixture12Hour.detectChanges();
const listOfSelectedLi = panelElement.nativeElement.querySelectorAll(
'.ant-time-picker-panel-select-option-selected'
);
expect(listOfSelectedLi[0].innerText).toBe('12');
expect(listOfSelectedLi[1].innerText).toBe('00');
expect(listOfSelectedLi[2].innerText).toBe('00');
expect(listOfSelectedLi[3].innerText).toBe('am');
}));
it('should scroll work in 12-hour', fakeAsync(() => {
fixture12Hour.componentInstance.openValue = new Date(0, 0, 0, 5, 6, 7);
fixture12Hour.componentInstance.nzTimePickerPanelComponent.select12Hours({ index: 1, value: 'pm' });
fixture12Hour.componentInstance.nzTimePickerPanelComponent.opened = true;
fixture12Hour.detectChanges();
tick(1000);
fixture12Hour.detectChanges();
let listOfSelectedLi = panelElement.nativeElement.querySelectorAll(
'.ant-time-picker-panel-select-option-selected'
);
expect(listOfSelectedLi[0].innerText).toBe('05');
expect(listOfSelectedLi[1].innerText).toBe('06');
expect(listOfSelectedLi[2].innerText).toBe('07');
expect(listOfSelectedLi[3].innerText).toBe('pm');
fixture12Hour.componentInstance.nzTimePickerPanelComponent.opened = false;
fixture12Hour.detectChanges();
tick(1000);
fixture12Hour.detectChanges();
fixture12Hour.componentInstance.value = new Date(0, 0, 0, 6, 7, 8);
fixture12Hour.detectChanges();
fixture12Hour.componentInstance.nzTimePickerPanelComponent.opened = true;
fixture12Hour.detectChanges();
tick(1000);
fixture12Hour.detectChanges();
listOfSelectedLi = panelElement.nativeElement.querySelectorAll('.ant-time-picker-panel-select-option-selected');
expect(listOfSelectedLi[0].innerText).toBe('06');
expect(listOfSelectedLi[1].innerText).toBe('07');
expect(listOfSelectedLi[2].innerText).toBe('08');
}));
it('select hour and 12-hour in 12-hour-time-picker-panel', fakeAsync(() => {
fixture12Hour.detectChanges();
testComponent.nzTimePickerPanelComponent.selectHour({ index: 3, disabled: false });
testComponent.nzTimePickerPanelComponent.select12Hours({ index: 1, value: 'pm' });
fixture12Hour.detectChanges();
flush();
fixture12Hour.detectChanges();
expect(testComponent.value.getHours()).toBe(15);
testComponent.nzTimePickerPanelComponent.select12Hours({ index: 0, value: 'am' });
fixture12Hour.detectChanges();
flush();
fixture12Hour.detectChanges();
expect(testComponent.value.getHours()).toBe(3);
}));
it('hour step in 12-hour-time-picker-panel', fakeAsync(() => {
testComponent.hourStep = 2;
fixture12Hour.detectChanges();
const listOfHourContainer = panelElement.nativeElement.querySelectorAll('.ant-time-picker-panel-select');
expect(listOfHourContainer[0].firstElementChild.children.length).toEqual(6);
}));
});

describe('disabled and format 12-hour time-picker-panel', () => {
let panelElement: DebugElement;
let fixture12Hour: ComponentFixture<NzTest12HourTimePanelDisabeledComponent>;
let testComponent: NzTest12HourTimePanelDisabeledComponent;

beforeEach(() => {
fixture12Hour = TestBed.createComponent(NzTest12HourTimePanelDisabeledComponent);
testComponent = fixture12Hour.debugElement.componentInstance;
fixture12Hour.detectChanges();
panelElement = fixture12Hour.debugElement.query(By.directive(NzTimePickerPanelComponent));
});

it('format in 12-hour-time-pick-panel', fakeAsync(() => {
testComponent.format = 'hh:mm:ss A';
fixture12Hour.detectChanges();
const list12HourLi = panelElement.nativeElement
.querySelectorAll('.ant-time-picker-panel-select')[3]
.querySelectorAll('li');
expect(list12HourLi[0].innerText).toBe('AM');
expect(list12HourLi[1].innerText).toBe('PM');
}));

it('disabled hour in 12-hour-time-picker-panel', fakeAsync(() => {
fixture12Hour.detectChanges();
flush();
testComponent.disabledHours = (): number[] => [0, 3, 4, 5, 12, 18, 19, 20, 24];
fixture12Hour.detectChanges();
let listHourLi = panelElement.nativeElement
.querySelectorAll('.ant-time-picker-panel-select')[0]
.querySelectorAll('li');
expect(listHourLi[0].classList).toContain('ant-time-picker-panel-select-option-disabled');
expect(listHourLi[3].classList).toContain('ant-time-picker-panel-select-option-disabled');
expect(listHourLi[4].classList).toContain('ant-time-picker-panel-select-option-disabled');
expect(listHourLi[5].classList).toContain('ant-time-picker-panel-select-option-disabled');
testComponent.nzTimePickerPanelComponent.select12Hours({ index: 1, value: 'pm' });
fixture12Hour.detectChanges();
listHourLi = panelElement.nativeElement
.querySelectorAll('.ant-time-picker-panel-select')[0]
.querySelectorAll('li');
expect(listHourLi[0].classList).toContain('ant-time-picker-panel-select-option-disabled');
expect(listHourLi[6].classList).toContain('ant-time-picker-panel-select-option-disabled');
expect(listHourLi[7].classList).toContain('ant-time-picker-panel-select-option-disabled');
expect(listHourLi[8].classList).toContain('ant-time-picker-panel-select-option-disabled');
}));
});
});

@Component({
Expand Down Expand Up @@ -229,3 +362,61 @@ export class NzTestTimePanelDisabledComponent {
}
}
}
@Component({
selector: 'nz-test-12-hour-time-panel',
encapsulation: ViewEncapsulation.None,
template: `
<nz-time-picker-panel
[(ngModel)]="value"
[nzUse12Hours]="true"
[nzDefaultOpenValue]="openValue"
[nzHourStep]="hourStep"
[format]="format"
>
</nz-time-picker-panel>
`,
styleUrls: ['../style/index.less', './style/index.less']
})
export class NzTest12HourTimePanelComponent {
@ViewChild(NzTimePickerPanelComponent) nzTimePickerPanelComponent: NzTimePickerPanelComponent;
format = 'hh:mm:ss a';
hourStep = 1;
value: Date;
openValue = new Date(0, 0, 0, 0, 0, 0);
}
@Component({
selector: 'nz-test-12-hour-time-panel',
encapsulation: ViewEncapsulation.None,
template: `
<nz-time-picker-panel
[format]="format"
[(ngModel)]="value"
[nzUse12Hours]="true"
[nzDisabledHours]="disabledHours"
[nzDisabledMinutes]="disabledMinutes"
[nzDisabledSeconds]="disabledSeconds"
>
</nz-time-picker-panel>
`,
styleUrls: ['../style/index.less', './style/index.less']
})
export class NzTest12HourTimePanelDisabeledComponent {
@ViewChild(NzTimePickerPanelComponent) nzTimePickerPanelComponent: NzTimePickerPanelComponent;
format = 'hh:mm:ss a';
value = new Date(0, 0, 0, 1, 1, 1);
disabledHours = (): number[] => [];
disabledMinutes(hour: number): number[] {
if (hour === 4) {
return [20, 21, 22, 23, 24, 25];
} else {
return [];
}
}
disabledSeconds(hour: number, minute: number): number[] {
if (hour === 5 && minute === 1) {
return [20, 21, 22, 23, 24, 25];
} else {
return [];
}
}
}
Loading

0 comments on commit 7c52774

Please sign in to comment.