Skip to content

Commit

Permalink
feat(module: TimePicker): support 12-hour(NG-ZORRO#1513)
Browse files Browse the repository at this point in the history
  • Loading branch information
kekehaoz committed Mar 13, 2019
1 parent f86810d commit 479bad3
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 15 deletions.
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="!nzHideDisabledOption"
(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
109 changes: 95 additions & 14 deletions components/time-picker/nz-time-picker-panel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import { reqAnimFrame } from '../core/polyfill/request-animation';
import { NzUpdateHostClassService as UpdateCls } from '../core/services/update-host-class.service';
import { isNotNil } from '../core/util/check';
import { NzTimeValueAccessorDirective } from './nz-time-value-accessor.directive';
import { TimeHolder } from './time-holder';
import { HourTypes, TimeHolder } from './time-holder';

function makeRange(length: number, step: number = 1): number[] {
return new Array(Math.ceil(length / step)).fill(0).map((_, i) => i * step);
function makeRange(length: number, step: number = 1, start: number = 0): number[] {
return new Array(Math.ceil(length / step)).fill(0).map((_, i) => (i + start) * step);
}

@Component({
Expand All @@ -49,6 +49,7 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
private _defaultOpenValue = new Date();
private _opened = false;
private _allowEmpty = true;
private _nzUse12Hours = false;
prefixCls: string = 'ant-time-picker-panel';
time = new TimeHolder();
hourEnabled = true;
Expand All @@ -58,10 +59,12 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
hourRange: ReadonlyArray<{ index: number, disabled: boolean }>;
minuteRange: ReadonlyArray<{ index: number, disabled: boolean }>;
secondRange: ReadonlyArray<{ index: number, disabled: boolean }>;
use12HoursRange: ReadonlyArray<{index: number, value: string}>;
@ViewChild(NzTimeValueAccessorDirective) nzTimeValueAccessorDirective: NzTimeValueAccessorDirective;
@ViewChild('hourListElement') hourListElement;
@ViewChild('minuteListElement') minuteListElement;
@ViewChild('secondListElement') secondListElement;
@ViewChild('use12HoursListElement') use12HoursListElement;
@Input() nzInDatePicker: boolean = false; // If inside a date-picker, more diff works need to be done
@Input() nzAddOn: TemplateRef<void>;
@Input() nzHideDisabledOptions = false;
Expand Down Expand Up @@ -201,6 +204,21 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
return this._nzSecondStep;
}

@Input()
set nzUse12Hours(value: boolean) {
if (isNotNil(value)) {
if (value) {
this.build12Hours();
this.enabledColumns++;
}
this._nzUse12Hours = value;
}
}

get nzUse12Hours(): boolean {
return this._nzUse12Hours;
}

selectInputRange(): void {
setTimeout(() => {
if (this.nzTimeValueAccessorDirective) {
Expand All @@ -210,13 +228,32 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
}

buildHours(): void {
this.hourRange = makeRange(24, this.nzHourStep).map(r => {
return {
index : r,
disabled: this.nzDisabledHours && (this.nzDisabledHours().indexOf(r) !== -1)
};
let hourRanges = 24;
let disabledHours = this.nzDisabledHours && this.nzDisabledHours();
let startIndex = 0;
if (this.nzUse12Hours) {
hourRanges = 12;
if (disabledHours) {
if (this.time.selected12Hours === 'PM') {
disabledHours = disabledHours.filter(i => i >= 12).map(i => (i > 12 ? i - 12 : i));
} else {
disabledHours = disabledHours.filter(i => i < 12 || i === 24).map(i => (i === 24 ? 0 : i));
}
}
);
startIndex = 1;
}
this.hourRange = makeRange(hourRanges, this.nzHourStep, startIndex).map(r => {
return {
index : r,
disabled: this.nzDisabledHours && (disabledHours.indexOf(r) !== -1)
};
});
if (this.nzUse12Hours && this.hourRange[this.hourRange.length - 1].index === 12) {
const temp = [...this.hourRange];
temp.unshift(temp[temp.length - 1]);
temp.splice(temp.length - 1, 1);
this.hourRange = temp;
}
}

buildMinutes(): void {
Expand All @@ -239,10 +276,22 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
);
}

build12Hours(): void {
const isUpperForamt = this._format.includes('A');
this.use12HoursRange = [{
index: 0,
value: isUpperForamt ? 'AM' : 'am'
}, {
index: 1,
value: isUpperForamt ? 'PM' : 'pm'
}];
}

buildTimes(): void {
this.buildHours();
this.buildMinutes();
this.buildSeconds();
this.build12Hours();
}

selectHour(hour: { index: number, disabled: boolean }): void {
Expand Down Expand Up @@ -270,6 +319,20 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
this.scrollToSelected(this.secondListElement.nativeElement, second.index, 120, 'second');
}

select12Hours(value: {index: number, value: string}): void {
this.time.selected12Hours = value.value;
if (this._disabledHours) {
this.buildHours();
}
if (this._disabledMinutes) {
this.buildMinutes();
}
if (this._disabledSeconds) {
this.buildSeconds();
}
this.scrollToSelected(this.use12HoursListElement.nativeElement, value.index, 120, '12-hour');
}

scrollToSelected(instance: HTMLElement, index: number, duration: number = 0, unit: string): void {
const transIndex = this.translateIndex(index, unit);
const currentOption = (instance.children[ 0 ].children[ transIndex ] || instance.children[ 0 ].children[ 0 ]) as HTMLElement;
Expand All @@ -286,6 +349,8 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
} else if (unit === 'second') {
const disabledSeconds = this.nzDisabledSeconds && this.nzDisabledSeconds(this.time.hours, this.time.minutes);
return this.calcIndex(disabledSeconds, this.secondRange.map(item => item.index).indexOf(index));
} else if (unit === '12-hour') {
return this.calcIndex([], this.use12HoursRange.map(item => item.index).indexOf(index));
}
}

Expand Down Expand Up @@ -338,7 +403,9 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
}

isSelectedHour(hour: { index: number, disabled: boolean }): boolean {
return (hour.index === this.time.hours) || (!isNotNil(this.time.hours) && (hour.index === this.time.defaultHours));
return (hour.index === this.time.getHours(HourTypes.ViewHour))
|| (!isNotNil(this.time.getHours(HourTypes.ViewHour))
&& (hour.index === this.time.getHours(HourTypes.ViewHour, this.time.defaultHours)));
}

isSelectedMinute(minute: { index: number, disabled: boolean }): boolean {
Expand All @@ -349,13 +416,18 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
return (second.index === this.time.seconds) || (!isNotNil(this.time.seconds) && (second.index === this.time.defaultSeconds));
}

isSelected12Hours(value: {index: number, value: string}): boolean {
return (value.value.toUpperCase() === this.time.selected12Hours) ||
(!isNotNil(this.time.selected12Hours) && (value.value.toUpperCase() === this.time.default12Hours));
}

initPosition(): void {
setTimeout(() => {
if (this.hourEnabled && this.hourListElement) {
if (isNotNil(this.time.hours)) {
this.scrollToSelected(this.hourListElement.nativeElement, this.time.hours, 0, 'hour');
if (isNotNil(this.time.getHours(HourTypes.ViewHour))) {
this.scrollToSelected(this.hourListElement.nativeElement, this.time.getHours(HourTypes.ViewHour), 0, 'hour');
} else {
this.scrollToSelected(this.hourListElement.nativeElement, this.time.defaultHours, 0, 'hour');
this.scrollToSelected(this.hourListElement.nativeElement, this.time.getHours(HourTypes.ViewHour, this.time.defaultHours), 0, 'hour');
}
}
if (this.minuteEnabled && this.minuteListElement) {
Expand All @@ -372,6 +444,15 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
this.scrollToSelected(this.secondListElement.nativeElement, this.time.defaultSeconds, 0, 'second');
}
}
if (this.nzUse12Hours && this.use12HoursListElement) {
if (isNotNil(this.time.selected12Hours)) {
const index = this.time.selected12Hours === 'AM' ? 0 : 1;
this.scrollToSelected(this.use12HoursListElement.nativeElement, index, 0, '12-hour');
} else {
const index = this.time.default12Hours === 'AM' ? 0 : 1;
this.scrollToSelected(this.use12HoursListElement.nativeElement, index, 0, '12-hour');
}
}
});
}

Expand All @@ -397,7 +478,7 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit,
}

writeValue(value: Date): void {
this.time.value = value;
this.time.setValue(value, this.nzUse12Hours);
this.buildTimes();

// Mark this component to be checked manually with internal properties changing (see: https://github.com/angular/angular/issues/10816)
Expand Down
1 change: 1 addition & 0 deletions components/time-picker/nz-time-picker.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
[nzDisabledSeconds]="nzDisabledSeconds"
[nzPlaceHolder]="nzPlaceHolder || ('TimePicker.placeholder' | nzI18n)"
[nzHideDisabledOptions]="nzHideDisabledOptions"
[nzUse12Hours]="nzUse12Hours"
[nzDefaultOpenValue]="nzDefaultOpenValue"
[nzAddOn]="nzAddOn"
[opened]="nzOpen"
Expand Down
1 change: 1 addition & 0 deletions components/time-picker/nz-time-picker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte
@Input() nzDisabledSeconds: (hour: number, minute: number) => number[];
@Input() nzFormat = 'HH:mm:ss';
@Input() nzOpen = false;
@Input() nzUse12Hours = false;
@Output() readonly nzOpenChange = new EventEmitter<boolean>();

@Input()
Expand Down
Loading

0 comments on commit 479bad3

Please sign in to comment.