import { IMyDate, IMyDateRange, IMySelectorPosition, IMyOptions } from '../interfaces/public-api'; import { PX, EMPTY_STR } from '../constants/constants'; import { Year } from '../enums/year.enum'; import { UtilService } from './farris-datepicker.util.service'; import { ComponentRef } from '@angular/core'; export class DatePickerService { opts; utilService; private _mouseWheelHandle = null; private _mouseScrollHandle = null; constructor(opts) { this.opts = opts; this.utilService = new UtilService(); } static parseOptions(opts: IMyOptions, defaultOpts): IMyOptions { if (defaultOpts !== undefined) { Object.keys(defaultOpts).forEach(k => { if (defaultOpts[k] !== undefined && defaultOpts[k] !== '') { (opts as IMyOptions)[k] = defaultOpts[k]; } }); } if (opts.minYear < Year.min) { opts.minYear = Year.min; } if (opts.maxYear > Year.max) { opts.maxYear = Year.max; } return opts; } validate(value: string) { const { dateRange } = this.opts; let valid = false; if (!dateRange) { const date: IMyDate = this.utilService.isDateValid(value, this.opts); valid = this.utilService.isInitializedDate(date); } else { const _dateRange: IMyDateRange = this.utilService.isDateValidDateRange(value, this.opts); const { begin, end } = _dateRange; valid = this.utilService.isInitializedDate(begin) && this.utilService.isInitializedDate(end); } return valid; } registerScrollEvent(fn) { this._mouseScrollHandle = fn; document.addEventListener('scroll', this._mouseScrollHandle); } removeMouseEvent() { const container = document.querySelector('.date-overlay-container'); if (container) { container.removeEventListener('mousewheel', this._mouseWheelHandle); } document.removeEventListener('scroll', this._mouseScrollHandle); } appendSelector(elem: any): void { let container = document.querySelector('.date-overlay-container'); if (container) { if (container.hasChildNodes()) { container.childNodes.forEach(el => { if (el !== elem) { container.removeChild(el); } }); } } else { container = document.createElement('div'); container.classList.add('date-overlay-container'); container.classList.add('overlay-container'); document.body.appendChild(container); } container.addEventListener('mousewheel', this._mouseWheelHandle = (e: MouseEvent) => { const target = e.target as any; if (!target.closest('.calendar-time-picker-select')) { e.preventDefault(); } return; }); container.appendChild(elem); } getSelectorPosition(elem: any, calendarRef: ComponentRef = null): IMySelectorPosition { let top = 0; let left = 0; let _selectorHeight = 0; let _selectorWidth = 0; const { selectorHeight, selectorWidth, showTime, dateRange, showType } = this.opts; const b: any = document.body.getBoundingClientRect(); const e: any = elem.getBoundingClientRect(); top = e.top - b.top; left = e.left - b.left; let position = 'bottom'; if (dateRange && showType !== 4) { _selectorWidth = this.getSelectorDimension(selectorWidth) * 2; } else { _selectorWidth = this.getSelectorDimension(selectorWidth); } if (showTime) { _selectorHeight = this.getSelectorDimension(selectorHeight) + 36; } else { _selectorHeight = this.getSelectorDimension(selectorHeight); } if (top + elem.offsetHeight + _selectorHeight > window.innerHeight && top - _selectorHeight - 2 > 0) { top = top - _selectorHeight - 2 - (showTime ? 6 : 0); position = 'top'; } else { top = top + elem.offsetHeight + 2; } if (window.innerHeight - top < _selectorHeight) { top = top - (_selectorHeight - (window.innerHeight - e.top - e.height - 15)); if (calendarRef) { const calendarElem = calendarRef.location.nativeElement; const arrow = calendarElem.querySelector('.arrow'); if (arrow) { arrow.style.display = 'none'; } } } if (left + _selectorWidth > b.width) { left = b.width - _selectorWidth - 15; } left = left > 0 ? left : 0; const scrollTop = document.body.scrollTop || document.documentElement.scrollTop; top -= scrollTop; return { top, left, position }; } private getSelectorDimension(value: string): number { return Number(value.replace(PX, EMPTY_STR)); } }