UNPKG

novo-elements

Version:

Bullhorn's NOVO Element Repository for Angular 2

182 lines (162 loc) 6.76 kB
// NG2 import { ElementRef, Component, EventEmitter, Input, Output, forwardRef, trigger, state, style, transition, animate } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; // Vendor import * as dateFns from 'date-fns'; // APP import { Helpers } from '../../utils/Helpers'; import { NovoLabelService } from '../../services/novo-label-service'; // Value accessor for the component (supports ngModel) const DATE_TIME_PICKER_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NovoDateTimePickerElement), multi: true }; @Component({ selector: 'novo-date-time-picker', providers: [DATE_TIME_PICKER_VALUE_ACCESSOR], animations: [ trigger('dateTextState', [ state('date', style({ 'opacity': '1.0' })), state('time', style({ 'opacity': '0.6' })), transition('date <=> time', animate('200ms ease-in')) ]), trigger('timeTextState', [ state('date', style({ 'opacity': '0.6' })), state('time', style({ 'opacity': '1.0' })), transition('date <=> time', animate('200ms ease-in')) ]), trigger('indicatorState', [ state('date', style({ 'transform': 'translateX(0%)' })), state('time', style({ 'transform': 'translateX(100%)' })), transition('date <=> time', animate('200ms ease-in')) ]), trigger('containerState', [ state('date', style({ 'transform': 'translateX(0%)' })), state('time', style({ 'transform': 'translateX(-100%)' })), transition('date <=> time', animate('200ms ease-in')) ]) ], template: ` <div class="date-time-container"> <div class="date-time-tabs"> <span class="date-tab" (click)="toggleView('date')" [@dateTextState]="componentTabState">{{selectedLabel}}</span> <span class="time-tab" (click)="toggleView('time')" [@timeTextState]="componentTabState"> <span class="hours" data-automation-id="novo-time-picker-hours">{{hours}}</span>:<span class="minutes" data-automation-id="novo-time-picker-minutes">{{minutes}}</span> <span *ngIf="!military" class="meridian">{{meridian}}</span> </span> <i class="date-time-indicator" [@indicatorState]="componentTabState"></i> </div> <div class="view-container" [@containerState]="componentTabState"> <div class="calendar"> <novo-date-picker (onSelect)="onDateSelected($event)" [(ngModel)]="model" inline="true" [minYear]="minYear" [maxYear]="maxYear" [start]="start" [end]="end"></novo-date-picker> </div> <div class="time-picker"> <novo-time-picker (onSelect)="onTimeSelected($event)" [(ngModel)]="model" [military]="military" inline="true"></novo-time-picker> </div> </div> </div> ` }) export class NovoDateTimePickerElement implements ControlValueAccessor { @Input() minYear: any; @Input() maxYear: any; @Input() start: any; @Input() end: any; @Input() military: any; // Select callback for output @Output() onSelect: EventEmitter<any> = new EventEmitter(false); componentTabState: string = 'date'; selectedLabel: string; hours: string; minutes: string; meridian: string; datePickerValue: Date = new Date(); timePickerValue: Date = new Date(); model: any; onModelChange: Function = () => { }; onModelTouched: Function = () => { }; constructor(public labels: NovoLabelService, private element: ElementRef) { } toggleView(tab: string): void { this.componentTabState = tab; } setDateLabels(value: Date) { this.selectedLabel = this.labels.formatDateWithFormat(value, { month: 'short', day: '2-digit', year: 'numeric' }); } setTimeLabels(value: Date) { let hours = value.getHours(); let minutes = value.getMinutes(); this.meridian = value.toLocaleTimeString().slice(-2); if (!this.military) { hours = this.meridian === 'PM' && hours > 12 ? hours - 12 : hours; // Special case for 12 if (this.meridian === 'PM' && hours === 24) { hours = 12; } else if (this.meridian === 'AM' && hours === 0) { hours = 12; } } this.hours = hours.toString().length === 1 ? `0${hours.toString()}` : hours.toString(); this.minutes = minutes.toString().length === 1 ? `0${minutes.toString()}` : minutes.toString(); } onDateSelected(event: { month?: any, year?: any, day?: any, date?: Date }) { this.datePickerValue = event.date; this.model = this.createFullDateValue(this.datePickerValue, this.timePickerValue); this.setDateLabels(this.model); this.onModelChange(this.model); this.onSelect.emit({ date: this.model }); this.toggleView('time'); } onTimeSelected(event: { hours?: number, minutes?: number, meridian?: string, date?: Date, text?: string }) { this.timePickerValue = event.date; this.model = this.createFullDateValue(this.datePickerValue, this.timePickerValue); this.setTimeLabels(this.model); this.onModelChange(this.model); this.onSelect.emit({ date: this.model }); } createFullDateValue(datePickerValue: Date, timePickerValue: Date) { return dateFns.setMilliseconds(dateFns.setSeconds(dateFns.setMinutes(dateFns.setHours(datePickerValue, dateFns.getHours(timePickerValue)), dateFns.getMinutes(timePickerValue)), dateFns.getSeconds(timePickerValue)), dateFns.getMilliseconds(timePickerValue)); } // ValueAccessor Functions writeValue(model: any): void { this.model = model; if (Helpers.isEmpty(model)) { this.model = new Date(); } else if (!isNaN(model)) { this.model = new Date(model); } this.datePickerValue = this.model; this.timePickerValue = this.model; if (Helpers.isDate(this.model)) { this.setDateLabels(this.model); this.setTimeLabels(this.model); } } registerOnChange(fn: Function): void { this.onModelChange = fn; } registerOnTouched(fn: Function): void { this.onModelTouched = fn; } }