projects/rebirth-ng/src/lib/time-picker/time-picker.component.ts
| exportAs | timePicker | 
            
| providers | 
                            {
    : , : (() => ), : true
}
                 | 
            
| selector | re-time-picker | 
            
| styleUrls | time-picker.component.scss | 
            
| templateUrl | ./time-picker.component.html | 
            
constructor(changeDetectorRef: ChangeDetectorRef)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                    
  | 
                
                        
                        maxTime
                     | 
                    
                             
                            Type:     
                            Default value:   | 
                
                        
                        minTime
                     | 
                    
                             
                            Type:     
                            Default value:   | 
                
                        
                        showSeconds
                     | 
                    
                         
                            Default value:   | 
                
| getCurrentTimestamp | ||||
getCurrentTimestamp(time: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                number
                             | 
                
| getDateByTime | ||||||
getDateByTime(time: TimePickerModel)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                any
                             | 
                
| Private getTimePickerModel | 
                            
                        getTimePickerModel()
                     | 
                
| 
                             
                                Returns :      
                    TimePickerModel
                             | 
                
| getValue | ||||||
getValue(value: , defaultValue: )
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                any
                             | 
                
| handleKeyEvent | ||||||
handleKeyEvent(event: , type: )
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| initConditionDate | 
initConditionDate()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| isSafetyKeyPress | 
isSafetyKeyPress(keyType: any, target: string, key: string)
                     | 
                
| 
                            
                             
                                Returns :      
                                boolean
                             | 
                
| isSupportedKeyPress | ||||
isSupportedKeyPress(event: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                boolean
                             | 
                
| modifyTimeByKey | 
modifyTimeByKey(value: number, key: string)
                     | 
                
| 
                            
                             
                                Returns :      
                                void
                             | 
                
| modifyTimeByKeyPress | 
modifyTimeByKeyPress(key: string, type: string, step: number)
                     | 
                
| 
                            
                             
                                Returns :      
                                void
                             | 
                
| modifyTimeByKeyPressEvent | 
modifyTimeByKeyPressEvent(type: string, keyEventType: string)
                     | 
                
| 
                            
                             
                                Returns :      
                                void
                             | 
                
| ngOnInit | 
ngOnInit()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| onModelChange | 
onModelChange()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| onTimeChange | ||||||
onTimeChange(key: string)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| registerOnChange | ||||
registerOnChange(fn: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| registerOnTouched | ||||
registerOnTouched(fn: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| setDisabledState | ||||
setDisabledState(disabled: )
                     | 
                ||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| updateTimeByMargin | |||||||||
updateTimeByMargin(key: string, marginDate: )
                     | 
                |||||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| writeValue | ||||||
writeValue(value: TimePickerModel)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| disabled | 
                        disabled:     
                     | 
                
                            Type :     boolean
                         | 
                    
| hour | 
                        hour:     
                     | 
                
                            Type :     string
                         | 
                    
                            Default value : '00'
                         | 
                    
| maxDate | 
                        maxDate:     
                     | 
                
                            Type :     Date
                         | 
                    
| minDate | 
                        minDate:     
                     | 
                
                            Type :     Date
                         | 
                    
| minute | 
                        minute:     
                     | 
                
                            Type :     string
                         | 
                    
                            Default value : '00'
                         | 
                    
| Private onChange | 
                        onChange:     
                     | 
                
                            Default value : (_: TimePickerModel) => null
                         | 
                    
| Private onTouched | 
                        onTouched:     
                     | 
                
                            Default value : () => null
                         | 
                    
| second | 
                        second:     
                     | 
                
                            Type :     string
                         | 
                    
                            Default value : '00'
                         | 
                    
| timeUnit | 
                        timeUnit:     
                     | 
                
                            Default value : TIME_UNIT
                         | 
                    
import { ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { keyBoardHelper } from '../utils/keyboard-utils';
function fillLeft(num: number) {
  return (num || 0) < 10 ? `0${num}` : `${num}`;
}
const ARROW_DOWN = 'ArrowDown';
const ARROW_UP = 'ArrowUp';
const supportKeyType = [ARROW_UP, ARROW_DOWN];
export class TimePickerModel {
  constructor(public  hour: number, public  minute: number, public second?: number) {
  }
  toString() {
    return `${fillLeft(this.hour)}:${fillLeft(this.minute)}:${fillLeft(this.second)}`;
  }
}
const BACKSPACE_KEY_CODE = 8;
const ENTER_KEY_CODE = 13;
const TAB_KEY_CODE = 9;
const SUPPORTED_KEY_CODE = [
  BACKSPACE_KEY_CODE,
  ENTER_KEY_CODE,
  TAB_KEY_CODE
];
export const TIME_UNIT = {
  HOUR: 'hour',
  MINUTE: 'minute',
  SECOND: 'second',
};
export const MAX_TIME_RANGE = {
  hour: 23,
  minute: 59,
  second: 59,
};
@Component({
  selector: 're-time-picker',
  styleUrls: ['./time-picker.component.scss'],
  templateUrl: './time-picker.component.html',
  exportAs: 'timePicker',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => TimePickerComponent),
      multi: true
    }
  ]
})
export class TimePickerComponent implements OnInit, ControlValueAccessor {
  @Input() showSeconds = true;
  @Input() minTime = new TimePickerModel(0, 0, 0);
  @Input() maxTime = new TimePickerModel(23, 59, 59);
  hour = '00';
  minute = '00';
  second = '00';
  timeUnit = TIME_UNIT;
  minDate: Date;
  maxDate: Date;
  disabled: boolean;
  private onChange = (_: TimePickerModel) => null;
  private onTouched = () => null;
  constructor(private changeDetectorRef: ChangeDetectorRef) {
  }
  ngOnInit(): void {
    this.initConditionDate();
  }
  initConditionDate() {
    this.minDate = this.getDateByTime(this.minTime);
    this.maxDate = this.getDateByTime(this.maxTime);
  }
  getDateByTime(time: TimePickerModel) {
    return new Date((new Date()).setHours(time.hour || 0, time.minute || 0, time.second || 0));
  }
  getValue(value, defaultValue) {
    if (value || value === 0) {
      return value;
    }
    return defaultValue;
  }
  getCurrentTimestamp(time): number {
    const hour = this.getValue(time.hour, parseInt(this.hour, 10));
    const minute = this.getValue(time.minute, parseInt(this.minute, 10));
    const second = this.getValue(time.second, parseInt(this.second, 10));
    return (new Date()).setHours(hour, minute, second);
  }
  writeValue(value: TimePickerModel) {
    if (value) {
      this.hour = fillLeft(value.hour || 0);
      this.minute = fillLeft(value.minute || 0);
      this.second = fillLeft(value.second || 0);
      this.changeDetectorRef.markForCheck();
    }
  }
  registerOnChange(fn) {
    this.onChange = fn;
  }
  registerOnTouched(fn) {
    this.onTouched = fn;
  }
  setDisabledState(disabled) {
    this.disabled = disabled;
    this.changeDetectorRef.markForCheck();
  }
  updateTimeByMargin(key: string, marginDate) {
    switch (key) {
      case TIME_UNIT.HOUR:
        this.hour = fillLeft(marginDate[TIME_UNIT.HOUR]);
        this.minute = fillLeft(marginDate[TIME_UNIT.MINUTE]);
        if (marginDate[TIME_UNIT.SECOND]) {
          this.second = fillLeft(marginDate[TIME_UNIT.SECOND]);
        }
        break;
      case TIME_UNIT.MINUTE:
        this.minute = fillLeft(marginDate[TIME_UNIT.MINUTE]);
        if (marginDate[TIME_UNIT.SECOND]) {
          this.second = fillLeft(marginDate[TIME_UNIT.SECOND]);
        }
        break;
      case TIME_UNIT.SECOND:
        this.second = fillLeft(marginDate[TIME_UNIT.SECOND]);
        break;
    }
  }
  modifyTimeByKey(value: number, key: string) {
    if (isNaN(value)) {
      if (this.getCurrentTimestamp({ [key]: 0 }) < this.minDate.getTime()) {
        this.updateTimeByMargin(key, this.minTime);
      } else if (this.getCurrentTimestamp({ [key]: 0 }) > this.maxDate.getTime()) {
        this.updateTimeByMargin(key, this.maxTime);
      } else {
        this.updateTimeByMargin(key, this.minTime);
      }
    } else if (value < 0) {
      this[key] = fillLeft(0) || fillLeft(this.minTime[key]);
    } else if (value > MAX_TIME_RANGE[key] || this.getCurrentTimestamp({ [key]: value }) > this.maxDate.getTime()) {
      this.updateTimeByMargin(key, this.maxTime);
    } else if (this.getCurrentTimestamp({ [key]: value }) < this.minDate.getTime()) {
      this.updateTimeByMargin(key, this.minTime);
    } else {
      this[key] = fillLeft(value);
    }
  }
  onTimeChange(key: string) {
    this.onTouched();
    this.modifyTimeByKey(parseInt(this[key], 10), key);
    this.onModelChange();
  }
  onModelChange() {
    this.onChange(this.getTimePickerModel());
  }
  private getTimePickerModel() {
    const model = new TimePickerModel(parseInt(this.hour, 10), parseInt(this.minute, 10));
    if (this.showSeconds) {
      model.second = parseInt(this.second, 10);
    }
    return model;
  }
  isSafetyKeyPress(keyType: any, target: string, key: string) {
    const parsedTarget = parseInt(target, 10);
    return !(keyType === ARROW_DOWN && parsedTarget < 1) &&
      (
        (keyType === ARROW_DOWN && key === TIME_UNIT.HOUR && parsedTarget <= MAX_TIME_RANGE.hour) ||
        (keyType === ARROW_DOWN && (key === TIME_UNIT.MINUTE || key === TIME_UNIT.SECOND) && parsedTarget <= MAX_TIME_RANGE.minute) ||
        (keyType === ARROW_UP && key === TIME_UNIT.HOUR && parsedTarget < MAX_TIME_RANGE.hour) ||
        (keyType === ARROW_UP && (key === TIME_UNIT.MINUTE || key === TIME_UNIT.SECOND) && parsedTarget < MAX_TIME_RANGE.minute)
      );
  }
  isSupportedKeyPress(event): boolean {
    return SUPPORTED_KEY_CODE.indexOf(event.keyCode) > -1 ||
      keyBoardHelper.numberKeyBoard(event) ||
      keyBoardHelper.smallKeyBoard(event) ||
      keyBoardHelper.arrowKeyBoard(event);
  }
  handleKeyEvent(event, type) {
    if (!this.isSupportedKeyPress(event)) {
      event.preventDefault();
      return;
    }
    const keyEventType = event.code;
    if (supportKeyType.indexOf(keyEventType) === -1) {
      return;
    }
    this.modifyTimeByKeyPressEvent(type, keyEventType);
  }
  modifyTimeByKeyPress(key: string, type: string, step: number) {
    if (this.isSafetyKeyPress(type, this[key], key)) {
      this[key] = fillLeft(parseInt(this[key], 10) + step);
    }
  }
  modifyTimeByKeyPressEvent(type: string, keyEventType: string) {
    let step = 1;
    if (keyEventType === ARROW_DOWN) {
      step = -1;
    }
    switch (type) {
      case this.timeUnit.HOUR:
        this.modifyTimeByKeyPress(TIME_UNIT.HOUR, keyEventType, step);
        break;
      case this.timeUnit.MINUTE:
        this.modifyTimeByKeyPress(TIME_UNIT.MINUTE, keyEventType, step);
        break;
      case this.timeUnit.SECOND:
        this.modifyTimeByKeyPress(TIME_UNIT.SECOND, keyEventType, step);
        break;
    }
  }
}
    <form class="form-inline time-picker">
  <div class="form-group">
    <input type="text"
           #hours
           [disabled]="disabled"
           name="hours"
           class="form-control"
           maxlength="2"
           max="23"
           min="0"
           autocomplete="off"
           [(ngModel)]="hour"
           (keydown)="handleKeyEvent($event, timeUnit.HOUR)"
           (blur)="onTimeChange(timeUnit.HOUR)">
  </div>
  <span>:</span>
  <div class="form-group">
    <input type="text"
           #minutes
           [disabled]="disabled"
           name="minutes"
           class="form-control"
           maxlength="2"
           max="59"
           min="0"
           autocomplete="off"
           [(ngModel)]="minute"
           (keydown)="handleKeyEvent($event, timeUnit.MINUTE)"
           (blur)="onTimeChange(timeUnit.MINUTE)">
  </div>
  <ng-container *ngIf="showSeconds">
    <span>:</span>
    <div class="form-group">
      <input type="text"
             #seconds
             [disabled]="disabled"
             name="seconds"
             class="form-control"
             max="59"
             min="0"
             maxlength="2"
             autocomplete="off"
             [(ngModel)]="second"
             (keydown)="handleKeyEvent($event, timeUnit.SECOND)"
             (blur)="onTimeChange(timeUnit.SECOND)">
    </div>
  </ng-container>
</form>