UNPKG

ng-daterangepicker-ext

Version:
183 lines (165 loc) 6.1 kB
import { DateObj, NgDateRangePickerHelper } from './shared/ng-daterangerpicker.helper'; import { NgDateRangeCalendarComponent } from './ng-daterange-calendar/ng-daterange-calendar.component'; import { ApplicationRef, Component, ComponentFactory, ComponentFactoryResolver, ComponentRef, ElementRef, forwardRef, HostListener, Injector, Input, OnChanges, OnInit, Renderer, SimpleChange, Type, ViewChild, ViewContainerRef } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; import { NgDateRangePickerOptions } from './shared/ng-daterangepicker-options'; import * as dateFns from 'date-fns'; export let DATERANGEPICKER_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgDateRangePickerComponent), multi: true }; @Component({ selector: 'ng-daterangepicker', templateUrl: 'ng-daterangepicker.component.html', styleUrls: ['ng-daterangepicker.sass'], providers: [ DATERANGEPICKER_VALUE_ACCESSOR ] }) export class NgDateRangePickerComponent implements ControlValueAccessor, OnInit { @Input() options: NgDateRangePickerOptions; @Input() container: string; @ViewChild('defaultContainer') public defaultContainer: ElementRef; created: boolean; calendarComponentRef: ComponentRef<NgDateRangeCalendarComponent>; modelValue: string; date: Date; _opened: false | 'from' | 'to' = false; get opened(): false | 'from' | 'to' { return this._opened; }; set opened(value: false | 'from' | 'to') { this._opened = value; if (this.calendarComponentRef && this.calendarComponentRef.instance) { this.calendarComponentRef.instance.opened = this.opened; } }; dateFrom: Date; dateTo: Date; defaultOptions: NgDateRangePickerOptions = { theme: 'default', range: 'tm', dayNames: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], presetNames: ['This Month', 'Last Month', 'This Week', 'Last Week', 'This Year', 'Last Year', 'Start', 'End', 'Hours', 'Minutes', 'Seconds'], outputFormat: 'DD/MM/YYYY', startOfWeek: 0, showTime: false, timeFormat: 'HH:mm:ss', container: false }; private onTouchedCallback: () => void = () => { }; private onChangeCallback: (_: any) => void = () => { }; constructor(private elementRef: ElementRef, private renderer: Renderer, private injector: Injector, private viewContainerRef: ViewContainerRef, private applicationRef: ApplicationRef, private componentFactoryResolver: ComponentFactoryResolver, private helper: NgDateRangePickerHelper) { } get value(): string { return this.modelValue; } set value(value: string) { if (!value) { return; } this.modelValue = value; this.onChangeCallback(value); } writeValue(value: string) { if (!value) { return; } this.modelValue = value; } registerOnChange(fn: any) { this.onChangeCallback = fn; } registerOnTouched(fn: any) { this.onTouchedCallback = fn; } ngOnInit() { this.options = this.options || {}; Object.keys(this.defaultOptions).forEach((key) => { if (!this.options.hasOwnProperty(key)) { this.options[key] = this.defaultOptions[key]; } }); let dates: DateObj = this.helper.selectRange(this.options); this.dateFrom = dates.dateFrom; this.dateTo = dates.dateTo; } toggleCalendar(e: MouseEvent, selection: 'from' | 'to'): void { if (!this.created) { this.createCalendar(); this.created = true; } if (this.opened && this.opened !== selection) { this.opened = selection; this.calendarComponentRef.instance.opened = this.opened; } else { this.opened = this.opened ? false : selection; this.calendarComponentRef.instance.opened = this.opened; } } createCalendar(): void { this.calendarComponentRef = this.componentFactoryResolver.resolveComponentFactory(NgDateRangeCalendarComponent).create(this.injector); this.initCalendar(); this.applicationRef.attachView(this.calendarComponentRef.hostView); let container: HTMLElement = this.options.container ? document.querySelector(this.options.container) : this.defaultContainer.nativeElement; container.appendChild(this.calendarComponentRef.location.nativeElement); } initCalendar(): void { this.calendarComponentRef.instance.options = this.options; this.calendarComponentRef.instance.dateFrom = this.dateFrom; this.calendarComponentRef.instance.dateTo = this.dateTo; this.calendarComponentRef.instance.onDateFrom.subscribe((val: Date) => { this.dateFrom = val; }); this.calendarComponentRef.instance.onDateTo.subscribe((val: Date) => { this.dateTo = val; }); this.calendarComponentRef.instance.opened = this.opened; this.calendarComponentRef.instance.onValueChange.subscribe((val: string) => { this.value = val; }); this.calendarComponentRef.instance.target = this.options.container ? this.defaultContainer.nativeElement : false; } formatDate(value: Date) { return dateFns.format(value, this.options.outputFormat); } getCSSClasses(): string { return `ng-daterangepicker theme-${this.options.theme}${!!this.opened ? ' is-active' : ''}`; } @HostListener('document:click', ['$event']) handleBlurClick(e: MouseEvent) { let target = e.srcElement || e.target; if (!this.elementRef.nativeElement.contains(e.target) && (this.calendarComponentRef && !this.calendarComponentRef.instance.element.nativeElement.contains(e.target)) && !(<Element>target).classList.contains('day-num') && !(<Element>target).classList.contains('time-link') && !(<Element>target).classList.contains('time-svg')) { this.opened = false; } } }