ngx-month-picker-range
Version:
Esta libreria fue generada con [Angular CLI](https://github.com/angular/angular-cli) version 8.2.9.
1,141 lines (1,110 loc) • 41.9 kB
JavaScript
import { ɵɵdefineInjectable, Injectable, EventEmitter, Component, forwardRef, Renderer2, ChangeDetectorRef, ElementRef, Input, ViewChild, Output, HostBinding, HostListener, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
import { CommonModule } from '@angular/common';
class NgxMonthPickerService {
constructor() { }
}
NgxMonthPickerService.ɵprov = ɵɵdefineInjectable({ factory: function NgxMonthPickerService_Factory() { return new NgxMonthPickerService(); }, token: NgxMonthPickerService, providedIn: "root" });
NgxMonthPickerService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
NgxMonthPickerService.ctorParameters = () => [];
/**
* @dynamic is for runtime initializing DomHandler.browser
*
* If delete below comment, we can see this error message:
* Metadata collected contains an error that will be reported at runtime:
* Only initialized variables and constants can be referenced
* because the value of this variable is needed by the template compiler.
*/
// @dynamic
class DomHandler {
static addClass(element, className) {
if (element.classList)
element.classList.add(className);
else
element.className += ' ' + className;
}
static addMultipleClasses(element, className) {
if (element.classList) {
let styles = className.split(' ');
for (let i = 0; i < styles.length; i++) {
element.classList.add(styles[i]);
}
}
else {
let styles = className.split(' ');
for (let i = 0; i < styles.length; i++) {
element.className += ' ' + styles[i];
}
}
}
static removeClass(element, className) {
if (element.classList)
element.classList.remove(className);
else
element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
static hasClass(element, className) {
if (element.classList)
return element.classList.contains(className);
else
return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className);
}
static siblings(element) {
return Array.prototype.filter.call(element.parentNode.children, function (child) {
return child !== element;
});
}
static find(element, selector) {
return Array.from(element.querySelectorAll(selector));
}
static findSingle(element, selector) {
if (element) {
return element.querySelector(selector);
}
return null;
}
static index(element) {
let children = element.parentNode.childNodes;
let num = 0;
for (var i = 0; i < children.length; i++) {
if (children[i] == element)
return num;
if (children[i].nodeType == 1)
num++;
}
return -1;
}
static indexWithinGroup(element, attributeName) {
let children = element.parentNode ? element.parentNode.childNodes : [];
let num = 0;
for (var i = 0; i < children.length; i++) {
if (children[i] == element)
return num;
if (children[i].attributes && children[i].attributes[attributeName] && children[i].nodeType == 1)
num++;
}
return -1;
}
static relativePosition(element, target) {
let elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
const targetHeight = target.offsetHeight;
const targetOffset = target.getBoundingClientRect();
const viewport = this.getViewport();
let top, left;
if ((targetOffset.top + targetHeight + elementDimensions.height) > viewport.height) {
top = -1 * (elementDimensions.height);
element.style.transformOrigin = 'bottom';
if (targetOffset.top + top < 0) {
top = -1 * targetOffset.top;
}
}
else {
top = targetHeight;
element.style.transformOrigin = 'top';
}
if (elementDimensions.width > viewport.width) {
// element wider then viewport and cannot fit on screen (align at left side of viewport)
left = targetOffset.left * -1;
}
else if ((targetOffset.left + elementDimensions.width) > viewport.width) {
// element wider then viewport but can be fit on screen (align at right side of viewport)
left = (targetOffset.left + elementDimensions.width - viewport.width) * -1;
}
else {
// element fits on screen (align with target)
left = 0;
}
element.style.top = top + 'px';
element.style.left = left + 'px';
}
static absolutePosition(element, target) {
let elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
let elementOuterHeight = elementDimensions.height;
let elementOuterWidth = elementDimensions.width;
let targetOuterHeight = target.offsetHeight;
let targetOuterWidth = target.offsetWidth;
let targetOffset = target.getBoundingClientRect();
let windowScrollTop = this.getWindowScrollTop();
let windowScrollLeft = this.getWindowScrollLeft();
let windowScrollRight = this.getWindowScrollRght();
let viewport = this.getViewport();
let top, left;
if (targetOffset.top + targetOuterHeight + elementOuterHeight > viewport.height) {
top = targetOffset.top + windowScrollTop - elementOuterHeight;
element.style.transformOrigin = 'bottom';
if (top < 0) {
top = windowScrollTop;
}
}
else {
top = targetOuterHeight + targetOffset.top + windowScrollTop;
element.style.transformOrigin = 'top';
}
if (targetOffset.left + elementOuterWidth > viewport.width)
left = Math.max(0, targetOffset.left + windowScrollLeft + targetOuterWidth - elementOuterWidth);
else
left = targetOffset.left + windowScrollLeft;
element.style.top = top + 'px';
element.style.left = left + 'px';
element.style.position = 'absolute';
}
static getHiddenElementOuterHeight(element) {
element.style.visibility = 'hidden';
element.style.display = 'block';
let elementHeight = element.offsetHeight;
element.style.display = 'none';
element.style.visibility = 'visible';
return elementHeight;
}
static getHiddenElementOuterWidth(element) {
element.style.visibility = 'hidden';
element.style.display = 'block';
let elementWidth = element.offsetWidth;
element.style.display = 'none';
element.style.visibility = 'visible';
return elementWidth;
}
static getHiddenElementDimensions(element) {
let dimensions = {};
element.style.visibility = 'hidden';
element.style.display = 'block';
dimensions.width = element.offsetWidth;
dimensions.height = element.offsetHeight;
element.style.display = 'none';
element.style.visibility = 'visible';
return dimensions;
}
static scrollInView(container, item) {
let borderTopValue = getComputedStyle(container).getPropertyValue('borderTopWidth');
let borderTop = borderTopValue ? parseFloat(borderTopValue) : 0;
let paddingTopValue = getComputedStyle(container).getPropertyValue('paddingTop');
let paddingTop = paddingTopValue ? parseFloat(paddingTopValue) : 0;
let containerRect = container.getBoundingClientRect();
let itemRect = item.getBoundingClientRect();
let offset = (itemRect.top + document.body.scrollTop) - (containerRect.top + document.body.scrollTop) - borderTop - paddingTop;
let scroll = container.scrollTop;
let elementHeight = container.clientHeight;
let itemHeight = this.getOuterHeight(item);
if (offset < 0) {
container.scrollTop = scroll + offset;
}
else if ((offset + itemHeight) > elementHeight) {
container.scrollTop = scroll + offset - elementHeight + itemHeight;
}
}
static fadeIn(element, duration) {
element.style.opacity = 0;
let last = +new Date();
let opacity = 0;
let tick = function () {
opacity = +element.style.opacity.replace(",", ".") + (new Date().getTime() - last) / duration;
element.style.opacity = opacity;
last = +new Date();
if (+opacity < 1) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
}
};
tick();
}
static fadeOut(element, ms) {
var opacity = 1, interval = 50, duration = ms, gap = interval / duration;
let fading = setInterval(() => {
opacity = opacity - gap;
if (opacity <= 0) {
opacity = 0;
clearInterval(fading);
}
element.style.opacity = opacity;
}, interval);
}
static getWindowScrollTop() {
let doc = document.documentElement;
return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
}
static getWindowScrollLeft() {
let doc = document.documentElement;
return (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
}
static getWindowScrollRght() {
let doc = document.documentElement;
return (window.pageXOffset || doc.scrollWidth) - (doc.scrollWidth || 0);
}
static matches(element, selector) {
var p = Element.prototype;
var f = p['matches'] || p.webkitMatchesSelector || p['mozMatchesSelector'] || p['msMatchesSelector'] || function (s) {
return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
};
return f.call(element, selector);
}
static getOuterWidth(el, margin) {
let width = el.offsetWidth;
if (margin) {
let style = getComputedStyle(el);
width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
}
return width;
}
static getHorizontalPadding(el) {
let style = getComputedStyle(el);
return parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
}
static getHorizontalMargin(el) {
let style = getComputedStyle(el);
return parseFloat(style.marginLeft) + parseFloat(style.marginRight);
}
static innerWidth(el) {
let width = el.offsetWidth;
let style = getComputedStyle(el);
width += parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
return width;
}
static width(el) {
let width = el.offsetWidth;
let style = getComputedStyle(el);
width -= parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
return width;
}
static getInnerHeight(el) {
let height = el.offsetHeight;
let style = getComputedStyle(el);
height += parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
return height;
}
static getOuterHeight(el, margin) {
let height = el.offsetHeight;
if (margin) {
let style = getComputedStyle(el);
height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
}
return height;
}
static getHeight(el) {
let height = el.offsetHeight;
let style = getComputedStyle(el);
height -= parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
return height;
}
static getWidth(el) {
let width = el.offsetWidth;
let style = getComputedStyle(el);
width -= parseFloat(style.paddingLeft) + parseFloat(style.paddingRight) + parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
return width;
}
static getViewport() {
let win = window, d = document, e = d.documentElement, g = d.getElementsByTagName('body')[0], w = win.innerWidth || e.clientWidth || g.clientWidth, h = win.innerHeight || e.clientHeight || g.clientHeight;
return { width: w, height: h };
}
static getOffset(el) {
var rect = el.getBoundingClientRect();
return {
top: rect.top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),
left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0),
};
}
static replaceElementWith(element, replacementElement) {
let parentNode = element.parentNode;
if (!parentNode)
throw `Can't replace element`;
return parentNode.replaceChild(replacementElement, element);
}
static getUserAgent() {
return navigator.userAgent;
}
static isIE() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return true;
}
var trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
var rv = ua.indexOf('rv:');
return true;
}
var edge = ua.indexOf('Edge/');
if (edge > 0) {
// Edge (IE 12+) => return version number
return true;
}
// other browser
return false;
}
static isIOS() {
return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window['MSStream'];
}
static isAndroid() {
return /(android)/i.test(navigator.userAgent);
}
static appendChild(element, target) {
if (this.isElement(target))
target.appendChild(element);
else if (target.el && target.el.nativeElement)
target.el.nativeElement.appendChild(element);
else
throw 'Cannot append ' + target + ' to ' + element;
}
static removeChild(element, target) {
if (this.isElement(target))
target.removeChild(element);
else if (target.el && target.el.nativeElement)
target.el.nativeElement.removeChild(element);
else
throw 'Cannot remove ' + element + ' from ' + target;
}
static isElement(obj) {
return (typeof HTMLElement === "object" ? obj instanceof HTMLElement :
obj && typeof obj === "object" && obj !== null && obj.nodeType === 1 && typeof obj.nodeName === "string");
}
static calculateScrollbarWidth(el) {
if (el) {
let style = getComputedStyle(el);
return (el.offsetWidth - el.clientWidth - parseFloat(style.borderLeftWidth) - parseFloat(style.borderRightWidth));
}
else {
if (this.calculatedScrollbarWidth !== null)
return this.calculatedScrollbarWidth;
let scrollDiv = document.createElement("div");
scrollDiv.className = "p-scrollbar-measure";
document.body.appendChild(scrollDiv);
let scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
this.calculatedScrollbarWidth = scrollbarWidth;
return scrollbarWidth;
}
}
static calculateScrollbarHeight() {
if (this.calculatedScrollbarHeight !== null)
return this.calculatedScrollbarHeight;
let scrollDiv = document.createElement("div");
scrollDiv.className = "p-scrollbar-measure";
document.body.appendChild(scrollDiv);
let scrollbarHeight = scrollDiv.offsetHeight - scrollDiv.clientHeight;
document.body.removeChild(scrollDiv);
this.calculatedScrollbarWidth = scrollbarHeight;
return scrollbarHeight;
}
static invokeElementMethod(element, methodName, args) {
element[methodName].apply(element, args);
}
static clearSelection() {
if (window.getSelection) {
if (window.getSelection().empty) {
window.getSelection().empty();
}
else if (window.getSelection().removeAllRanges && window.getSelection().rangeCount > 0 && window.getSelection().getRangeAt(0).getClientRects().length > 0) {
window.getSelection().removeAllRanges();
}
}
else if (document['selection'] && document['selection'].empty) {
try {
document['selection'].empty();
}
catch (error) {
//ignore IE bug
}
}
}
static getBrowser() {
if (!this.browser) {
let matched = this.resolveUserAgent();
this.browser = {};
if (matched.browser) {
this.browser[matched.browser] = true;
this.browser['version'] = matched.version;
}
if (this.browser['chrome']) {
this.browser['webkit'] = true;
}
else if (this.browser['webkit']) {
this.browser['safari'] = true;
}
}
return this.browser;
}
static resolveUserAgent() {
let ua = navigator.userAgent.toLowerCase();
let match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[1] || "",
version: match[2] || "0"
};
}
static isInteger(value) {
if (Number.isInteger) {
return Number.isInteger(value);
}
else {
return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
}
}
static isHidden(element) {
return element.offsetParent === null;
}
static getFocusableElements(element) {
let focusableElements = DomHandler.find(element, `button:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
[href][clientHeight][clientWidth]:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
input:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]), select:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
textarea:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]), [tabIndex]:not([tabIndex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
[contenteditable]:not([tabIndex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden])`);
let visibleFocusableElements = [];
for (let focusableElement of focusableElements) {
if (getComputedStyle(focusableElement).display != "none" && getComputedStyle(focusableElement).visibility != "hidden")
visibleFocusableElements.push(focusableElement);
}
return visibleFocusableElements;
}
}
DomHandler.zindex = 1000;
DomHandler.calculatedScrollbarWidth = null;
DomHandler.calculatedScrollbarHeight = null;
class NgxMonthPickerComponent {
constructor(renderer, cd, elem) {
this.renderer = renderer;
this.cd = cd;
this.elem = elem;
this.mode = 'single' || 'range';
this.inputContainerClass = "calendar-input-container";
this.inputValueClass = "calendar-input-value";
this.calendarContainerClass = "calendar-ui";
this.monthItemClass = "monthItem";
this.edgeClass = "isEdge";
this.notYearClass = "notCurrentYear";
this.inRangeClass = "inRange";
this.lowerEdgeClass = "isLowerEdge";
this.upperEdgeClass = "upperEdgeClass";
this.cleanBtnClass = "clean-btn";
this.acceptBtnClass = "accept-btn";
this.locale = "es-MX";
//@Input('appendTo')
this.appendTo = "body";
this.monthRangeSelected = new EventEmitter();
this.tabindex = 0;
this.onChange = (_) => { };
this.onTouched = () => { };
this.onModelTouched = () => { };
if (!this.placeholder)
this.placeholder = 'Seleccionar...';
}
blurHandler() {
this.focused = false;
this.itemFocused = -1;
this.onTouched();
}
focusHandler() {
this.focused = true;
}
set value(val) {
this._Value = val;
}
get value() {
return this._Value;
}
set itemFocused(val) {
this._itemFocused = val;
}
get itemFocused() {
return this._itemFocused;
}
ngOnInit() {
this.initCalendar();
this.cd.detectChanges();
}
initCalendar() {
this.initYearLabels();
this.initMonthLabels();
this.initViewSlices();
this.initMonthsData();
this.initRangeIndexes();
if (this.value) {
if (!this.value['start']) {
this.currentYearIndex = this.years.findIndex(year => year === this.value.getFullYear());
}
else {
this.currentYearIndex = this.years.findIndex(year => year === this.value['start'].getFullYear());
}
}
else {
this.currentYearIndex = this.years.findIndex(year => year === (new Date()).getFullYear());
}
this.sliceDataIntoView();
}
ngOnChanges(simpleChange) {
if (simpleChange.value) {
this.value = simpleChange.value.currentValue;
}
if (simpleChange.mode) {
this.mode = simpleChange.mode.currentValue;
}
if (simpleChange.placeholder) {
this.placeholder = simpleChange.placeholder.currentValue;
}
if (simpleChange.acceptBtnClass)
this.acceptBtnClass = simpleChange.acceptBtnClass.currentValue;
}
ngAfterContentInit() {
this.renderer.listen(this.elem.nativeElement, "keydown", ($event) => onKeydown($event, this));
}
ngOnDestroy() {
if (this.isOpen) {
this.onShowCalendar();
}
this.renderer.listen(this.elem.nativeElement, "keydown", null);
}
onShowCalendar(event) {
if (this.disabled)
return;
if (event) {
event.stopPropagation();
}
if (!this.isOpen) {
this.show(event);
}
else {
this.hide(event);
}
}
show(event) {
if (event) {
event.stopPropagation();
}
this.initCalendar();
this.isOpen = true;
const selectedStyles = document.querySelectorAll('.calendar-input-container');
selectedStyles.forEach(element => {
if (element.getAttribute('class').includes('active')) {
this.renderer.removeClass(element, 'active');
}
});
const selectedOptions = document.querySelectorAll('.calendar-ui');
selectedOptions.forEach(element => {
this.renderer.setStyle(element, 'display', 'none');
});
this.renderer.addClass(this.calendarInputContainer.nativeElement, 'active');
this.appendOverlay();
this.alignOverlay();
this.renderer.setStyle(this.calendarUI.nativeElement, 'display', 'block');
}
hide(event) {
if (event) {
event.stopPropagation();
}
this.isOpen = false;
this.renderer.removeClass(this.calendarInputContainer.nativeElement, 'active');
this.renderer.setStyle(this.calendarUI.nativeElement, 'display', 'none');
this.restoreOverlayAppend();
}
appendOverlay() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.calendarUI.nativeElement);
else
DomHandler.appendChild(this.calendarUI, this.appendTo);
}
//this.calendarUI.nativeElement.style.width = DomHandler.getWidth(this.containerViewChild.nativeElement) + 'px';
}
restoreOverlayAppend() {
if (this.calendarUI) {
if (this.appendTo) {
this.elem.nativeElement.appendChild(this.calendarUI.nativeElement);
}
}
}
alignOverlay() {
if (this.calendarUI) {
if (this.appendTo)
DomHandler.absolutePosition(this.calendarUI.nativeElement, this.containerViewChild.nativeElement);
else
DomHandler.relativePosition(this.calendarUI.nativeElement, this.containerViewChild.nativeElement);
}
}
onClick(indexClicked) {
if (this.mode === 'single') {
this.rangeIndexes[0] = this.globalIndexOffset + indexClicked;
let fromMonthYear = this.monthsData[this.rangeIndexes[0]];
let initDate = new Date(fromMonthYear.monthYear, fromMonthYear.month, 1);
this.value = initDate;
return;
}
if (this.rangeIndexes[0] !== null && this.rangeIndexes[1] !== null) {
this.clearData();
}
if (this.rangeIndexes[0] === null) {
this.rangeIndexes[0] = this.globalIndexOffset + indexClicked;
}
else if (this.rangeIndexes[1] === null) {
this.rangeIndexes[1] = this.globalIndexOffset + indexClicked;
this.paintRange();
let fromMonthYear = this.monthsData[this.rangeIndexes[0]];
let toMonthYear = this.monthsData[this.rangeIndexes[1]];
let initDate = new Date(fromMonthYear.monthYear, fromMonthYear.month, 1);
let endDate = new Date(toMonthYear.monthYear, toMonthYear.month + 1, 0);
this.value = { start: initDate, end: endDate };
}
else {
this.initRangeIndexes();
this.initMonthsData();
this.onClick(indexClicked);
this.sliceDataIntoView();
}
;
}
;
paintRange() {
this.rangeIndexes.sort((a, b) => a - b);
this.monthsData.forEach((month, index) => {
if ((this.rangeIndexes[0] <= index) && (index <= this.rangeIndexes[1])) {
month.isInRange = true;
}
;
if (this.rangeIndexes[0] === index) {
month.isLowerEdge = true;
}
;
if (this.rangeIndexes[1] === index) {
month.isUpperEdge = true;
}
;
});
}
emitData() {
this.isClosing = true;
this.updateChanges();
this.onTouched();
this.monthRangeSelected.emit(this.value);
this.hide();
}
;
sliceDataIntoView() {
this.globalIndexOffset = this.monthViewSlicesIndexes[this.currentYearIndex];
this.monthDataSlice = this.monthsData.slice(this.globalIndexOffset, this.globalIndexOffset + 24);
}
;
incrementYear() {
if (this.currentYearIndex !== this.years.length - 1) {
this.currentYearIndex++;
this.sliceDataIntoView();
}
;
}
;
decrementYear() {
if (this.currentYearIndex !== 0) {
this.currentYearIndex--;
this.sliceDataIntoView();
}
;
}
;
initRangeIndexes() {
if (this.value) {
this.rangeIndexes = [];
if (this.value['start']) {
this.rangeIndexes.push(this.monthsData.findIndex((v, i) => (v.month === this.value['start'].getMonth() && v.monthYear === this.value['start'].getFullYear())));
if (this.value['end'])
this.rangeIndexes.push(this.monthsData.findIndex((v, i) => (v.month === this.value['end'].getMonth() && v.monthYear === this.value['end'].getFullYear())));
this.paintRange();
}
else {
this.rangeIndexes.push(this.monthsData.findIndex((v, i) => (v.month === this.value.getMonth() && v.monthYear === this.value.getFullYear())));
}
}
else
this.rangeIndexes = [null, null];
}
;
initMonthsData() {
this.monthsData = new Array();
this.years.forEach(year => {
this.months.forEach((month, i) => {
this.monthsData.push({
monthName: month,
month: i,
monthYear: year,
isInRange: false,
isLowerEdge: false,
isUpperEdge: false
});
});
});
}
;
initYearLabels() {
const currentYear = (new Date()).getFullYear();
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + (i * step));
this.years = range(this.firstYear ? this.firstYear : (currentYear - 5), this.lastYear ? this.lastYear : (currentYear + 5), 1);
}
;
initMonthLabels() {
this.months = new Array(12).fill(0).map((_, i) => {
//console.log(new Date(`${i + 1}/1/1`).toLocaleDateString(this.locale, { month: 'short' }));
return new Date(`${i + 1}/1/1`).toLocaleDateString(this.locale, { month: 'short' });
});
}
;
initViewSlices() {
this.monthViewSlicesIndexes = [];
this.years.forEach((year, index) => {
if (index === 0) {
this.monthViewSlicesIndexes.push(0);
}
else if (index === 1) {
this.monthViewSlicesIndexes.push(6);
}
else
this.monthViewSlicesIndexes.push(this.monthViewSlicesIndexes[index - 1] + 12);
});
}
get valueText() {
let text = "";
let fromMonthYear = this.monthsData[this.rangeIndexes[0]];
let toMonthYear = this.monthsData[this.rangeIndexes[1]];
if (this.mode === 'single') {
if (fromMonthYear) {
text += `${fromMonthYear.monthName}, ${fromMonthYear.monthYear}`;
}
}
else if (fromMonthYear && toMonthYear) {
if (fromMonthYear.monthYear === toMonthYear.monthYear) {
if (fromMonthYear.monthName !== toMonthYear.monthName) {
text += `${fromMonthYear.monthName} - ${toMonthYear.monthName}, ${fromMonthYear.monthYear}`;
}
else {
text += `${fromMonthYear.monthName}, ${fromMonthYear.monthYear}`;
}
}
else {
text += `${fromMonthYear.monthName}, ${fromMonthYear.monthYear} - ${toMonthYear.monthName}, ${toMonthYear.monthYear}`;
}
}
if (text === '') {
text = this.placeholder ? this.placeholder : "Seleccionar...";
}
return text;
}
clearData() {
this.value = undefined;
this.updateChanges();
this.ngOnInit();
}
validate({ value }) {
const isNotValid = this.isRequired && this.value == undefined;
return isNotValid && {
invalid: true
};
}
updateChanges() {
this.onChange(this.value);
}
writeValue(value) {
this.value = value;
this.updateChanges();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
setDisabledState(val) {
this.disabled = val;
}
setReadOnlyState(val) {
this.isReadOnly = val;
}
}
NgxMonthPickerComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-month-picker',
template: `
<div class="calendar-widget" #select>
<div [ngClass]="inputContainerClass" (click)="onShowCalendar($event)" role="listbox" #calendarInputContainer [title]="valueText">
<span [ngClass]="inputValueClass">{{valueText}}</span>
</div>
<div [ngClass]="calendarContainerClass" #calendarUI style="display: none;">
<div class="outerCard">
<div class="topPanel">
<button class="prevYearButton" (click)="decrementYear()">
<i class="arrow arrow-left"></i>
</button>
<span class="yearLabel">{{ years[currentYearIndex] }}</span>
<button class="nextYearButton" (click)="incrementYear()">
<i class="arrow arrow-right"></i>
</button>
</div>
<div class="contentPanel" #calendarContent>
<div (click)="onClick(i)" *ngFor="let month of monthDataSlice; let i = index" [ngClass]="[monthItemClass,
(rangeIndexes[0]===globalIndexOffset+i || rangeIndexes[1]===globalIndexOffset+i) ? edgeClass: '',
(currentYearIndex===0? i > 11:(i < 6 || i > 17)) ? notYearClass : '']">
<div [id]="i" class="monthItemHighlight" [ngClass]="[ month.isInRange ? inRangeClass : '',
month.isLowerEdge ? lowerEdgeClass : '', month.isUpperEdge ? upperEdgeClass : '' ]">
{{ month.monthName }}
</div>
</div>
</div>
<div class="footerPanel">
<a id="cleanBtn" href="javascript:void(0)" [ngClass]="cleanBtnClass" (click)="clearData()">
Limpiar
</a>
<a id="acceptBtn" href="javascript:void(0)" [ngClass]="acceptBtnClass" (click)="emitData()">
Aceptar
</a>
</div>
</div>
</div>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgxMonthPickerComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: NgxMonthPickerComponent,
multi: true
}
],
styles: [`
.calendar-ui {
z-index: 1003;
width: 350px;
background-color: white;
}
.calendar-input-container {
background: #F5F5F6 !important;
border: solid 1px #C2D1D9 !important;
color: #A8B0BA !important;
font-family: "open_sansitalic", sans-serif !important;
line-height: 17px;
min-height: 48px;
display: flex;
align-items: center;
border-radius: 3px;
width: 100%;
font-size: 16px;
letter-spacing: 0;
}
.calendar-input-value {
padding-left: 10px;
padding-right: 10px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.outerCard {
touch-action: none;
overflow: hidden;
width: inherit;
/*height: 350px;*/
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
}
.topPanel {
width: inherit;
height: 44px;
text-align: center;
line-height: 64px;
}
.prevYearButton {
float: left;
}
.nextYearButton {
float: right;
}
button {
width: 64px;
height: 64px;
background: none;
border: none;
margin: 0;
padding: 0;
cursor: pointer;
}
button:focus {
outline: 0;
}
i {
border: solid black;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 6px;
}
.arrow-right {
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.arrow-left {
transform: rotate(135deg);
-webkit-transform: rotate(135deg);
}
.topPanel.yearLabel {
display: inline-block;
margin: 0 auto;
}
.contentPanel {
padding: 32px 6px;
}
.footerPanel {
display: flex;
}
.monthItem {
display: inline-block;
height: 54px;
width: 54px;
cursor: pointer;
text-align: center;
line-height: 54px;
margin-top: 1px;
margin-bottom: 1px;
}
.monthItem:hover {
border-radius: 100%;
background-color: #F5F5F6;
color: #A8B0BA;
}
.isEdge {
border-radius: 100%;
background-color: #1474a4;
color: white;
}
.inRange {
background-color: #1474a4;
opacity: 0.5;
color: white;
}
.isLowerEdge {
background-color: none;
background: linear-gradient(to right, transparent 50%, #1474a4 50%);
}
.isUpperEdge {
background-color: none;
background: linear-gradient(to right, #1474a4 50%, transparent 50%);
}
.notCurrentYear {
color: #c4cbd6;
}
.clean-btn {
text-decoration: none;
width: 50%;
display: inline-block;
font-weight: 400;
color: #A8B0BA;
background-color: #F5F5F6;
text-align: center;
vertical-align: middle;
user-select: none;
border: 1px solid transparent;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
}
.accept-btn {
text-decoration: none;
width: 50%;
display: inline-block;
font-weight: 400;
text-align: center;
vertical-align: middle;
user-select: none;
border: 1px solid transparent;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
color: white;
background-color: #1474a4;
}
`]
},] }
];
NgxMonthPickerComponent.ctorParameters = () => [
{ type: Renderer2 },
{ type: ChangeDetectorRef },
{ type: ElementRef }
];
NgxMonthPickerComponent.propDecorators = {
placeholder: [{ type: Input, args: ['placeholder',] }],
isRequired: [{ type: Input, args: ['required',] }],
disabled: [{ type: Input, args: ['disabled',] }],
isReadOnly: [{ type: Input, args: ['readonly',] }],
mode: [{ type: Input, args: ['mode',] }],
firstYear: [{ type: Input, args: ['firstYear',] }],
lastYear: [{ type: Input, args: ['lastYear',] }],
inputContainerClass: [{ type: Input, args: ['inputContainerClass',] }],
inputValueClass: [{ type: Input, args: ['inputValueClass',] }],
calendarContainerClass: [{ type: Input, args: ['inputValueClass',] }],
monthItemClass: [{ type: Input, args: ['monthItemClass',] }],
edgeClass: [{ type: Input, args: ['edgeClass',] }],
notYearClass: [{ type: Input, args: ['notYearClass',] }],
inRangeClass: [{ type: Input, args: ['inRangeClass',] }],
lowerEdgeClass: [{ type: Input, args: ['lowerEdgeClass',] }],
upperEdgeClass: [{ type: Input, args: ['upperEdgeClass',] }],
cleanBtnClass: [{ type: Input, args: ['cleanBtnClass',] }],
acceptBtnClass: [{ type: Input, args: ['acceptBtnClass',] }],
locale: [{ type: Input, args: ['locale',] }],
calendarInputContainer: [{ type: ViewChild, args: ["calendarInputContainer", { static: false },] }],
calendarUI: [{ type: ViewChild, args: ["calendarUI", { static: false },] }],
calendarContent: [{ type: ViewChild, args: ["calendarContent", { static: false },] }],
containerViewChild: [{ type: ViewChild, args: ["select", { static: false },] }],
monthRangeSelected: [{ type: Output }],
tabindex: [{ type: HostBinding, args: ['tabindex',] }],
blurHandler: [{ type: HostListener, args: ['blur',] }],
focusHandler: [{ type: HostListener, args: ['focus',] }]
};
function onKeydown(event, component) {
switch (event.which) {
//down
case 40:
if (!component.isOpen && event.altKey) {
component.onShowCalendar();
component.itemFocused = -1;
}
event.preventDefault();
break;
case 13:
component.onShowCalendar();
component.itemFocused = -1;
event.preventDefault();
break;
case 27:
component.hide();
component.itemFocused = -1;
event.preventDefault();
break;
case 8:
component.clearData();
component.itemFocused = -1;
event.preventDefault();
break;
}
}
class NgxMonthPickerModule {
}
NgxMonthPickerModule.decorators = [
{ type: NgModule, args: [{
declarations: [NgxMonthPickerComponent],
imports: [
CommonModule
],
exports: [NgxMonthPickerComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
},] }
];
/*
* Public API Surface of ngx-month-picker
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgxMonthPickerComponent, NgxMonthPickerModule, NgxMonthPickerService };
//# sourceMappingURL=ngx-month-picker-range.js.map