Skip to content

Commit

Permalink
feat(timepicker): add inputs validation (#2187)
Browse files Browse the repository at this point in the history
* feat(timepicker): add inputs validation

* fix(timepicker): add isPM support

* feat(timepicker): add isValid output
  • Loading branch information
IlyaSurmay authored and valorkin committed Jul 14, 2017
1 parent 21e48e5 commit 7e80486
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<timepicker [(ngModel)]="mytime" (change)="changed()"></timepicker>
<timepicker [(ngModel)]="mytime" (change)="changed()" (isValid)="isValid = $event"></timepicker>

<pre class="alert alert-info">Time is: {{mytime}}</pre>
<pre *ngIf="!isValid" class="alert alert-danger">Invalid time format</pre>

<button type="button" class="btn btn-primary" (click)="update()">Set to 14:00</button>
<button type="button" class="btn btn-danger" (click)="clear()">Clear</button>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Component } from '@angular/core';
export class DemoTimepickerDynamicComponent {

public mytime: Date = new Date();
public isValid: boolean;

public update(): void {
let d = new Date();
Expand Down
16 changes: 8 additions & 8 deletions src/timepicker/timepicker-controls.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,31 +96,31 @@ export function timepickerControls(value: Date, state: TimepickerComponentState)

// compare dates
if (max) {
const _newHour = changeTime(max, { hour: hourStep });
res.canIncrementHours = max >= _newHour;
const _newHour = changeTime(value, { hour: hourStep });
res.canIncrementHours = max > _newHour;

if (!res.canIncrementHours) {
const _newMinutes = changeTime(max, { minute: minuteStep });
res.canIncrementMinutes = max >= _newMinutes;
const _newMinutes = changeTime(value, { minute: minuteStep });
res.canIncrementMinutes = showSeconds ? max > _newMinutes : max >= _newMinutes ;
}

if (!res.canIncrementMinutes) {
const _newSeconds = changeTime(max, { seconds: secondsStep });
const _newSeconds = changeTime(value, { seconds: secondsStep });
res.canIncrementSeconds = max >= _newSeconds;
}
}

if (min) {
const _newHour = changeTime(min, { hour: -hourStep });
const _newHour = changeTime(value, { hour: -hourStep });
res.canDecrementHours = min < _newHour;

if (!res.canDecrementHours) {
const _newMinutes = changeTime(min, { minute: -minuteStep });
const _newMinutes = changeTime(value, { minute: -minuteStep });
res.canDecrementMinutes = showSeconds ? min < _newMinutes : min <= _newMinutes;
}

if (!res.canDecrementMinutes) {
const _newSeconds = changeTime(min, { seconds: -secondsStep });
const _newSeconds = changeTime(value, { seconds: -secondsStep });
res.canDecrementSeconds = min <= _newSeconds;
}
}
Expand Down
20 changes: 15 additions & 5 deletions src/timepicker/timepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Component, EventEmitter,
forwardRef,
Input,
OnChanges,
OnChanges, Output,
SimpleChanges
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
Expand All @@ -15,7 +15,7 @@ import { TimepickerStore } from './reducer/timepicker.store';
import { getControlsValue } from './timepicker-controls.util';
import { TimepickerConfig } from './timepicker.config';
import { TimeChangeSource, TimepickerComponentState, TimepickerControls } from './timepicker.models';
import { isValidDate, padNumber, parseTime } from './timepicker.utils';
import { isValidDate, padNumber, parseTime, isInputValid } from './timepicker.utils';

export const TIMEPICKER_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
Expand Down Expand Up @@ -175,6 +175,8 @@ export class TimepickerComponent implements ControlValueAccessor, TimepickerComp
/** maximum time user can select */
@Input() max: Date;

@Output() isValid: EventEmitter<boolean> = new EventEmitter();

// ui variables
hours: string;
minutes: string;
Expand Down Expand Up @@ -222,11 +224,16 @@ export class TimepickerComponent implements ControlValueAccessor, TimepickerComp
_store
.select((state) => state.controls)
.subscribe((controlsState) => {
this.isValid.emit(isInputValid(this.hours, this.minutes, this.seconds, this.isPM()));
Object.assign(this, controlsState);
_cd.markForCheck();
});
}

isPM(): boolean {
return this.showMeridian && this.meridian === this.meridians[1];
}

prevDef($event: any) {
$event.preventDefault();
}
Expand Down Expand Up @@ -267,13 +274,16 @@ export class TimepickerComponent implements ControlValueAccessor, TimepickerComp
}

_updateTime() {
const isPM = this.showMeridian && this.meridian === this.meridians[1];
if (!isInputValid(this.hours, this.minutes, this.seconds, this.isPM())) {
this.ngOnChanges(null);
return;
}
this._store.dispatch(this._timepickerActions
.setTime({
hour: this.hours,
minute: this.minutes,
seconds: this.seconds,
isPM
isPM: this.isPM()
}));
}

Expand Down
11 changes: 9 additions & 2 deletions src/timepicker/timepicker.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export function isNumber(value: string): boolean {
return !isNaN(toNumber(value));
}

export function parseHours(value: string | number): number {
export function parseHours(value: string | number, isPM: boolean = false): number {
const hour = toNumber(value);
if (isNaN(hour) || hour < 0 || hour > hoursPerDay) {
if (isNaN(hour) || hour < 0 || hour > (isPM ? hoursPerDayHalf : hoursPerDay)) {
return NaN;
}

Expand Down Expand Up @@ -132,3 +132,10 @@ export function padNumber(value: number): string {

return `0${_value}`;
}

export function isInputValid(hours: string, minutes: string, seconds: string = '0', isPM: boolean): boolean {
if (isNaN(parseHours(hours, isPM)) || isNaN(parseMinutes(minutes)) || isNaN(parseSeconds(seconds))) {
return false;
}
return true;
}

0 comments on commit 7e80486

Please sign in to comment.