ngx-datetime-range-picker-ng13
Version:
> Ngx Date time range picker with daily, weekly, monthly, quarterly & yearly levels
1,302 lines (1,296 loc) • 485 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Pipe, EventEmitter, Component, ViewEncapsulation, Input, Output, ViewChild, NgModule, Optional, SkipSelf } from '@angular/core';
import * as i2 from '@angular/material/form-field';
import { MatFormFieldModule } from '@angular/material/form-field';
import * as i3 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import * as i4 from '@angular/material/select';
import { MatSelectModule } from '@angular/material/select';
import * as i5 from '@angular/material/core';
import * as i6 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i7 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i8 from '@angular/material/input';
import { MatInputModule } from '@angular/material/input';
import * as i9 from '@angular/forms';
import { FormsModule } from '@angular/forms';
const moment$2 = require("moment");
const USA_MST_TZ_CODE = "MST";
const USA_TZ_CODE$1 = "PST";
const EU_TZ_CODE = "CET";
function getLocalTimezone() {
const tz = /\((.*)\)/.exec(new Date().toString())[1];
if (tz === "Central Europe Standard Time") {
return EU_TZ_CODE;
}
else {
return USA_MST_TZ_CODE;
}
}
const DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
const NgxDatetimeRangePickerConstants = {
DEFAULT: {
OPTIONS: {
dateArray: [],
startDate: moment$2().format("YYYY-MM-DD"),
endDate: moment$2().format("YYYY-MM-DD"),
minDate: moment$2()
.subtract(2, "year")
.startOf("year")
.format("YYYY-MM-DD"),
maxDate: moment$2().format("YYYY-MM-DD"),
startTime: "00:00",
endTime: "23:59"
},
SETTINGS: {
type: "daily",
modelKeys: ["daily", "weekly", "monthly", "quarterly", "yearly"],
showTimezoneSelect: false,
useLocalTimezone: false,
timePicker: false,
inputClass: "m1drp",
inputDateFormat: null,
viewDateFormat: DEFAULT_DATE_FORMAT,
outputDateFormat: DEFAULT_DATE_FORMAT,
singleDatePicker: false,
componentDisabled: false,
placeholder: "Select Date",
showRowNumber: false,
availableRanges: {},
showRanges: true,
disableWeekends: false,
disableWeekdays: false,
retailCalendar: false,
displayBeginDate: false,
displayEndDate: false,
ariaLabels: {
inputField: "Date Range Input Field"
}
},
STATE: {
activeEndDate: null,
activeItem: {
left: {},
right: {}
},
activeRange: null,
activeStartDate: null,
calendarAvailable: {
left: false,
right: false
},
customRange: false,
dates: {
left: {},
right: {}
},
dateTitleText: {
left: "",
right: ""
},
frequencyColumnHeader: null,
isCalendarVisible: false,
isValidFilter: false,
isUserModelChange: true,
localTimezone: getLocalTimezone(),
selectedDateText: "",
selectedHour: {
left: "",
right: ""
},
selectedMeridian: {
left: "",
right: ""
},
selectedMinute: {
left: "",
right: ""
},
selectedMonth: {
left: "",
right: ""
},
selectedTimezone: undefined,
selectedYear: {
left: "",
right: ""
},
sides: [],
timeItems: ["hour", "minute"],
times: {
left: "",
right: ""
},
timeZones: [USA_TZ_CODE$1, EU_TZ_CODE],
todayTime: "",
weekDayOptions: ["su", "mo", "tu", "we", "th", "fr", "sa"]
},
TIME_FORMAT: "HH:mm",
RANGES: {
daily: [
{ label: "Last 7 Days", count: 6 },
{ label: "Last 30 Days", count: 29 },
{ label: "Last 90 Days", count: 89 }
],
weekly: [
{ label: "Last 4 Weeks", count: 3 },
{ label: "Last 13 Weeks", count: 12 },
{ label: "Last 26 Weeks", count: 25 }
],
monthly: [
{ label: "Last 3 Months", count: 2 },
{ label: "Last 6 Months", count: 5 },
{ label: "Last 9 Months", count: 8 }
],
quarterly: [
{ label: "Last 2 Quarters", count: 1 },
{ label: "Last 4 Quarters", count: 3 }
],
yearly: [{ label: "Last Year", count: 1 }]
}
},
CONSTANT: {
MONTHS_AVAILABLE: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
TIMES_AVAILABLE: ["hour", "minute"],
MOMENT_CONVERSION_MAP: {
daily: "day",
weekly: "week",
monthly: "month",
quarterly: "quarter",
yearly: "year"
},
USA_MST_TZ_CODE,
USA_TZ_CODE: USA_TZ_CODE$1,
EU_TZ_CODE,
OFFSETS: {
[USA_TZ_CODE$1]: {
SO: -7,
WO: -8
},
[EU_TZ_CODE]: {
SO: 1,
WO: 0
}
},
TZ_NAMES: {
[USA_MST_TZ_CODE]: "America/Phoenix",
[USA_TZ_CODE$1]: "America/Los_Angeles",
[EU_TZ_CODE]: "Europe/Berlin"
}
}
};
const getNotAvailableText = () => {
return "N/A";
};
/**
*
* @param value the value to be cloned
* @note will not work for objects containing functions
*/
const cloneDeep = (value) => {
if (value) {
return JSON.parse(JSON.stringify(value));
}
};
const isEmpty = (value) => {
if (value) {
return Object.keys(value).length <= 0;
}
};
const mergeDeep = (...objects) => {
const isObject = (obj) => obj && typeof obj === "object";
return objects.reduce((prev, obj) => {
Object.keys(obj).forEach((key) => {
const pVal = prev[key];
const oVal = obj[key];
if (Array.isArray(pVal) && Array.isArray(oVal)) {
prev[key] = pVal.concat(...oVal);
}
else if (isObject(pVal) && isObject(oVal)) {
prev[key] = mergeDeep(pVal, oVal);
}
else {
prev[key] = oVal;
}
});
return prev;
}, {});
};
const isNil = (value) => {
return value == null || value === undefined;
};
const tuple = (...args) => args;
const CalendarTypes = tuple("daily", "weekly", "monthly", "quarterly", "yearly");
const moment$1 = require("moment");
const DEFAULT_TIME_FORMAT$1 = NgxDatetimeRangePickerConstants.DEFAULT.TIME_FORMAT;
const MONTHS_AVAILABLE = NgxDatetimeRangePickerConstants.CONSTANT.MONTHS_AVAILABLE;
const TZ_NAMES = NgxDatetimeRangePickerConstants.CONSTANT.TZ_NAMES;
const DEFAULT_RANGES = NgxDatetimeRangePickerConstants.DEFAULT.RANGES;
const MOMENT_CONVERSION_MAP = NgxDatetimeRangePickerConstants.CONSTANT.MOMENT_CONVERSION_MAP;
class NgxDatetimeRangePickerService {
getDefaultOptions() {
return cloneDeep(NgxDatetimeRangePickerConstants.DEFAULT.OPTIONS);
}
getDefaultSettings() {
return cloneDeep(NgxDatetimeRangePickerConstants.DEFAULT.SETTINGS);
}
getDefaultState() {
return cloneDeep(NgxDatetimeRangePickerConstants.DEFAULT.STATE);
}
checkSettingsValidity(settings) {
if (settings.type && !CalendarTypes.includes(settings.type)) {
const errMsg = `${settings.type} is an invalid calendar type. It should one of ${[...CalendarTypes]}`;
throw new Error(errMsg);
}
}
formatDateToDefaultFormat(date, format) {
let formattedDate = null;
if (!date) {
return;
}
if (!isNaN(Number(date))) {
formattedDate = moment$1(date).format(DEFAULT_DATE_FORMAT);
}
else {
formattedDate = moment$1(date, format).format(DEFAULT_DATE_FORMAT);
}
return formattedDate;
}
formatTimeToDefaultFormat(time) {
let formattedTime = null;
if (!time) {
return;
}
if (time.indexOf(":") > -1) {
if (time.indexOf("AM") > -1 || time.indexOf("PM") > -1) {
formattedTime = moment$1(time, "h:mm A").format(DEFAULT_TIME_FORMAT$1);
}
else {
formattedTime = time;
}
}
else {
console.warn(`WARN_NGX_DATETIME_RANGE_PICKER:
The provided time is not in correct format.
Format: HH:mm or hh:mm A
`);
}
return formattedTime;
}
getCalendarRowNumberText(type, number) {
return (() => {
switch (type) {
case "daily":
return `W${number}`;
case "weekly":
return "";
case "monthly":
return `Q${number}`;
case "quarterly":
return `${number}`;
case "yearly":
return "";
}
})();
}
createDefaultRanges(config) {
const ranges = {};
const type = config.type;
const maxDate = cloneDeep(config.maxDate);
DEFAULT_RANGES[type].forEach((rangeInfo) => {
ranges[rangeInfo.label] = {
startDate: moment$1(maxDate, DEFAULT_DATE_FORMAT)
.subtract(rangeInfo.count, MOMENT_CONVERSION_MAP[type])
.format(DEFAULT_DATE_FORMAT),
endDate: maxDate
};
});
ranges["Custom Range"] = { startDate: null, endDate: null };
return ranges;
}
getSanitizedDateArray(config) {
const sanitizedDateArray = [];
const type = config.type;
const dateArray = config.dateArray;
const inputDateFormat = config.inputDateFormat;
// dateArray can have nulls
dateArray.forEach((date) => {
if (!date) {
return;
}
let format = null;
if (isNaN(Number(date))) {
if (inputDateFormat) {
format = inputDateFormat;
}
else {
format = moment$1(date)._f; // moment does not support this
}
}
if (inputDateFormat !== moment$1(date)._f) {
console.warn(`ERR_NGX_DATETIME_RANGE_PICKER:
inputDateFormat !== dateFormat in dateArray.
Converted dates might not be as expected
`);
}
const value = format ? moment$1(date, format) : moment$1(date);
if (value) {
const formattedDate = value.endOf(MOMENT_CONVERSION_MAP[type]).format(DEFAULT_DATE_FORMAT);
sanitizedDateArray.push(formattedDate);
}
else {
console.warn(`ERR_NGX_DATETIME_RANGE_PICKER:
dateArray values are in unknown format.
Pass the format or pass the dates in known format
`);
}
});
return [...new Set(sanitizedDateArray)];
}
getNumberOfWeeks(date) {
if (!date) {
return;
}
const monthStart = moment$1(date, DEFAULT_DATE_FORMAT)
.startOf("month")
.day();
const monthEnd = Number(moment$1(date, DEFAULT_DATE_FORMAT)
.endOf("month")
.format("D"));
return Math.ceil((monthStart + monthEnd) / 7);
}
getYearlyWeekCount(year) {
if (!year) {
return;
}
const yearStartDate = moment$1(year, "YYYY")
.startOf("year")
.format(DEFAULT_DATE_FORMAT);
const yearEndDate = moment$1(year, "YYYY")
.endOf("year")
.format(DEFAULT_DATE_FORMAT);
const yearEndWeekEndDate = moment$1(yearEndDate, DEFAULT_DATE_FORMAT)
.startOf("week")
.format(DEFAULT_DATE_FORMAT);
const yearStartWeekEndDate = moment$1(yearStartDate, DEFAULT_DATE_FORMAT)
.endOf("week")
.format(DEFAULT_DATE_FORMAT);
const yearStartWeekNumber = this.getWeekNumber(yearStartWeekEndDate);
const yearEndWeekNumber = this.getWeekNumber(yearEndWeekEndDate);
return yearEndWeekNumber - yearStartWeekNumber + 1;
}
getMonthsAvailable(minDate, maxDate, selectedYear) {
const months = [];
if (!minDate || !maxDate || !selectedYear) {
return;
}
minDate = moment$1(minDate, DEFAULT_DATE_FORMAT).startOf("month");
maxDate = moment$1(maxDate, DEFAULT_DATE_FORMAT).startOf("month");
let minDatems = moment$1(minDate, DEFAULT_DATE_FORMAT).valueOf();
let maxDatems = moment$1(maxDate, DEFAULT_DATE_FORMAT).valueOf();
const yearStartms = moment$1()
.year(selectedYear)
.startOf("year")
.valueOf();
const yearEndms = moment$1()
.year(selectedYear)
.endOf("year")
.valueOf();
if (minDatems < yearStartms) {
minDatems = yearStartms;
}
if (maxDatems > yearEndms) {
maxDatems = yearEndms;
}
let minDateMonthNumber = moment$1(minDatems).month();
const diff = moment$1(maxDatems).diff(moment$1(minDatems), "months");
const maxMonths = diff < MONTHS_AVAILABLE.length ? diff : MONTHS_AVAILABLE.length;
for (let i = 0; i <= maxMonths; i++) {
if (minDateMonthNumber >= MONTHS_AVAILABLE.length) {
months.push(MONTHS_AVAILABLE[minDateMonthNumber - MONTHS_AVAILABLE.length]);
}
else {
months.push(MONTHS_AVAILABLE[minDateMonthNumber]);
}
minDateMonthNumber++;
}
return months;
}
getYearsAvailable(config) {
const minDate = config ? config.minDate : "";
const maxDate = config ? config.maxDate : "";
const years = [];
if (minDate && maxDate) {
const minYear = Number(this.getSelectedYear(minDate));
const maxYear = Number(this.getSelectedYear(maxDate));
const diff = maxYear - minYear;
for (let i = 0; i <= diff; i++) {
years.push(`${minYear + i}`);
}
}
return years.reverse();
}
isDateAvailable(date, minDate, maxDate, startDate, endDate, monthStartDate, monthEndDate, config) {
let available = false;
const type = config.type;
const disableWeekends = config.disableWeekends;
const disableWeekdays = config.disableWeekdays;
if (type === "daily") {
minDate = minDate > monthStartDate ? minDate : monthStartDate;
maxDate = maxDate < monthEndDate ? maxDate : monthEndDate;
}
if (date >= minDate && date <= maxDate) {
available = true;
if (available) {
if (disableWeekends) {
available = !this.isWeekend(date);
}
if (disableWeekdays) {
available = !this.isWeekday(date);
}
if (config.dateArray.length) {
available = this.isInDateArray(date, config.dateArray, DEFAULT_DATE_FORMAT);
}
}
}
return available;
}
isDateInRange(date, minDate, maxDate, startDate, endDate, monthStartDate, monthEndDate, available, config) {
let inRange = false;
const type = config.type;
const singleDatePicker = config.singleDatePicker;
if (!singleDatePicker) {
if (type === "daily") {
minDate = monthStartDate;
maxDate = monthEndDate;
}
if (date >= startDate && date <= endDate && date >= minDate && date <= maxDate) {
if (available) {
inRange = true;
}
}
}
return inRange;
}
isDateActive(date, startDate, endDate, side) {
return (date === startDate && side === "left") || (date === endDate && side === "right");
}
isDateToday(dateMs, config) {
const todayDate = moment$1().format(DEFAULT_DATE_FORMAT);
const type = config.type;
const { firstDay, lastDay } = this.getFirstLastDay(todayDate, type);
const firstDayMs = moment$1(firstDay, DEFAULT_DATE_FORMAT).valueOf();
const lastDayMs = moment$1(lastDay, DEFAULT_DATE_FORMAT).valueOf();
return dateMs >= firstDayMs && dateMs <= lastDayMs;
}
isWeekday(date, format) {
return !this.isWeekend(date, format);
}
isWeekend(date, format) {
if (!format) {
format = null;
}
const day = moment$1(date, format).day();
return day === 0 || day === 6;
}
isInDateArray(date, dateArray, format) {
if (!format) {
format = null;
}
return dateArray.find((d) => moment$1(d, format).valueOf() === date) !== undefined;
}
getCalendarRowVariables(options) {
const variables = {
rowNumber: "",
columns: 0
};
const type = options.type;
const monthStartWeekNumber = options.monthStartWeekNumber;
const dateRows = options.dateRows;
const year = `${options.year}`;
if (type === "daily") {
variables.rowNumber = `${monthStartWeekNumber + dateRows}`;
variables.columns = 6;
}
else if (type === "weekly") {
variables.rowNumber = ``;
variables.columns = 6;
}
else if (type === "monthly") {
variables.rowNumber = `${dateRows + 1}`;
variables.columns = 2;
}
else if (type === "quarterly") {
variables.rowNumber = year.charAt(dateRows);
variables.columns = 0;
}
else if (type === "yearly") {
variables.rowNumber = "";
variables.columns = 0;
}
return variables;
}
getCalendarRowItemVariables(options) {
const { type, monthStartWeekNumber, yearStartDate, year, rowItem, dateRows, columns } = options;
const itemCount = rowItem + dateRows * columns + dateRows;
let currentItemDate = "";
let rowItemText = "";
if (type === "daily") {
if (!isNil(monthStartWeekNumber) && !isNil(dateRows) && !isNil(year)) {
const yearStartDateDaily = moment$1()
.year(year)
.startOf("year")
.format(DEFAULT_DATE_FORMAT);
currentItemDate = moment$1(yearStartDateDaily, DEFAULT_DATE_FORMAT)
.add(monthStartWeekNumber + dateRows - 1, "week")
.startOf("week")
.add(rowItem, "day")
.format(DEFAULT_DATE_FORMAT);
rowItemText = moment$1(currentItemDate, DEFAULT_DATE_FORMAT).format("D");
}
}
else if (type === "weekly") {
if (!isNil(yearStartDate) && !isNil(itemCount)) {
currentItemDate = moment$1(yearStartDate, DEFAULT_DATE_FORMAT)
.add(itemCount, "week")
.endOf("week")
.format(DEFAULT_DATE_FORMAT);
const weekNumber = itemCount + 1;
rowItemText = `W${weekNumber}`;
}
}
else if (type === "monthly") {
if (!isNil(itemCount) && !isNil(year)) {
currentItemDate = moment$1()
.year(year)
.month(itemCount)
.endOf("month")
.format(DEFAULT_DATE_FORMAT);
rowItemText = moment$1(currentItemDate, DEFAULT_DATE_FORMAT).format("MMM");
}
}
else if (type === "quarterly") {
if (!isNil(itemCount) && !isNil(year)) {
currentItemDate = moment$1()
.year(year)
.quarter(itemCount + 1)
.endOf("quarter")
.format(DEFAULT_DATE_FORMAT);
rowItemText = `Quarter ${itemCount + 1}`;
}
}
const { firstDay, lastDay } = this.getFirstLastDay(currentItemDate, type);
return {
itemCount,
currentItemDate,
rowItemText,
firstDay,
lastDay
};
}
isRowIemValid(options) {
let valid = false;
const type = options.type;
const year = options.year;
const itemCount = options.itemCount;
const validWeekCount = this.getYearlyWeekCount(year);
if (type === "daily") {
valid = true;
}
else if (type === "weekly") {
if (itemCount < validWeekCount) {
valid = true;
}
}
else if (type === "monthly") {
valid = true;
}
else if (type === "quarterly") {
valid = true;
}
return valid;
}
formatStartDate(config, returnFormat) {
const startDate = config ? config.startDate : null;
const type = config ? config.type : "";
let formattedStartDate = null;
if (startDate) {
formattedStartDate = moment$1(startDate, DEFAULT_DATE_FORMAT)
.startOf(MOMENT_CONVERSION_MAP[type])
.format(returnFormat);
}
return formattedStartDate;
}
getSelectedYear(date) {
return moment$1(date, DEFAULT_DATE_FORMAT).format("YYYY");
}
getFirstLastDay(date, type) {
let firstDay = "";
let lastDay = "";
if (type === "daily") {
firstDay = lastDay = date;
}
else if (type === "weekly") {
firstDay = moment$1(date, DEFAULT_DATE_FORMAT)
.startOf("week")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment$1(date, DEFAULT_DATE_FORMAT)
.endOf("week")
.format(DEFAULT_DATE_FORMAT);
}
else if (type === "monthly") {
firstDay = moment$1(date, DEFAULT_DATE_FORMAT)
.startOf("month")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment$1(date, DEFAULT_DATE_FORMAT)
.endOf("month")
.format(DEFAULT_DATE_FORMAT);
}
else if (type === "quarterly") {
firstDay = moment$1(date, DEFAULT_DATE_FORMAT)
.startOf("quarter")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment$1(date, DEFAULT_DATE_FORMAT)
.endOf("quarter")
.format(DEFAULT_DATE_FORMAT);
}
else if (type === "yearly") {
firstDay = moment$1(date, DEFAULT_DATE_FORMAT)
.startOf("year")
.format(DEFAULT_DATE_FORMAT);
lastDay = moment$1(date, DEFAULT_DATE_FORMAT)
.endOf("year")
.format(DEFAULT_DATE_FORMAT);
}
return { firstDay, lastDay };
}
getZoneDate(tz, format, date) {
let _date = moment$1().valueOf();
if (date) {
_date = moment$1(date, format)
.startOf("day")
.valueOf();
}
const today = new Date(_date).toLocaleString("en-US", {
timeZone: TZ_NAMES[tz]
});
return moment$1(today, "MM/DD/YYYY, hh:mm:ss A");
}
getZoneToday(tz, viewDateFormat) {
const today = this.getZoneDate(tz, viewDateFormat);
return moment$1(today).format(`${viewDateFormat} hh:mm A`);
}
formatToZoneDate(tz, format, date) {
const formattedDate = this.getZoneDate(tz, format, date);
return moment$1(formattedDate).format(`${format}`);
}
convertToViewTimeItem(item) {
let stringified_item = item + "";
if (stringified_item.length === 1) {
stringified_item = `0${stringified_item}`;
}
return stringified_item;
}
getWeekNumber(date) {
if (date) {
const year = moment$1(date, "YYYY-MM-DD").year();
const month = moment$1(date, "YYYY-MM-DD").month();
const day = Number(moment$1(date, "YYYY-MM-DD").format("D"));
const yearStartms = new Date(year, 0, 1);
const datems = new Date(year, month, day);
return Math.ceil(((datems.getTime() - yearStartms.getTime()) / 86400000 + yearStartms.getDay() + 1) / 7);
}
else {
console.warn(`
WARN_NGX_DATETIME_RANGE_PICKER | getWeekNumber:
Invalid date
`);
return getNotAvailableText();
}
}
iterateOverDateObj(dates, func) {
for (const side in dates) {
if (side) {
const sideDates = dates[side];
sideDates.itemRows.forEach((rows) => {
rows.items.forEach((rowItem) => {
func(rowItem);
});
});
}
}
}
getCalendarColspan(type) {
if (type === "daily") {
return 6;
}
else if (type === "weekly") {
return 8;
}
else if (type === "monthly") {
return 3;
}
else if (type === "quarterly") {
return 1;
}
else if (type === "yearly") {
return 1;
}
}
getCalendarRowItemColspan(type) {
if (type === "monthly") {
return 3;
}
else if (type === "quarterly") {
return 6;
}
else if (type === "yearly") {
return 6;
}
}
getDateCharacteristics(config, state, date, month, side) {
const currentDate = moment$1(date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
let _date = this.formatDateToDefaultFormat(config.minDate, DEFAULT_DATE_FORMAT);
const minDate = moment$1(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
_date = this.formatDateToDefaultFormat(config.maxDate, DEFAULT_DATE_FORMAT);
const maxDate = moment$1(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
_date = this.formatDateToDefaultFormat(config.startDate, DEFAULT_DATE_FORMAT);
const startDate = moment$1(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
_date = this.formatDateToDefaultFormat(config.endDate, DEFAULT_DATE_FORMAT);
const endDate = moment$1(_date, DEFAULT_DATE_FORMAT)
.startOf("day")
.valueOf();
const currentMonthStartDate = moment$1(month, "MMM YYYY")
.startOf("month")
.startOf("day")
.valueOf();
const currentMonthEndDate = moment$1(month, "MMM YYYY")
.endOf("month")
.startOf("day")
.valueOf();
const available = this.isDateAvailable(currentDate, minDate, maxDate, startDate, endDate, currentMonthStartDate, currentMonthEndDate, config);
const inRange = this.isDateInRange(currentDate, minDate, maxDate, startDate, endDate, currentMonthStartDate, currentMonthEndDate, available, config);
const active = this.isDateActive(currentDate, startDate, endDate, side);
const today = this.isDateToday(currentDate, config);
// Active
if (currentDate === startDate && side === "left") {
state.activeStartDate = date;
}
else if (currentDate === endDate && side === "right") {
state.activeEndDate = date;
}
return { available, inRange, active, today };
}
getLabelProps(state, calendarType, side) {
let label, labelFormat, type;
if (calendarType === "daily") {
label = `${state.selectedMonth[side]} ${state.selectedYear[side]}`;
labelFormat = "MMM YYYY";
type = "month";
}
else {
label = `${state.selectedYear[side]}`;
labelFormat = "YYYY";
type = "year";
}
return { label, labelFormat, type };
}
}
NgxDatetimeRangePickerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NgxDatetimeRangePickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
NgxDatetimeRangePickerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NgxDatetimeRangePickerService, providedIn: "root" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NgxDatetimeRangePickerService, decorators: [{
type: Injectable,
args: [{
providedIn: "root"
}]
}] });
/**
* Iterate over {key: value}
* Returns the keys of the object
* Usage:
* let objKey of obj | ObjNgFor
* Example:
* let obj = {a: 1, b: 2};
* *ngFor="let key of obj | ObjNgFor"
* {{keys}}: {{obj[key]}}
*/
class ObjNgFor {
transform(value, args = null) {
return Object.keys(value); // .map(key => value[key]);
}
}
ObjNgFor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: ObjNgFor, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
ObjNgFor.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: ObjNgFor, name: "ObjNgFor", pure: false });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: ObjNgFor, decorators: [{
type: Pipe,
args: [{ name: "ObjNgFor", pure: false }]
}] });
const moment = require("moment");
var InputFocusBlur;
(function (InputFocusBlur) {
InputFocusBlur[InputFocusBlur["focus"] = 1] = "focus";
InputFocusBlur[InputFocusBlur["blur"] = 2] = "blur";
})(InputFocusBlur || (InputFocusBlur = {}));
const DEFAULT_TIME_FORMAT = NgxDatetimeRangePickerConstants.DEFAULT.TIME_FORMAT;
const USA_TZ_CODE = NgxDatetimeRangePickerConstants.CONSTANT.USA_TZ_CODE;
class NgxDatetimeRangePickerComponent {
constructor(element, renderer, service) {
this.element = element;
this.renderer = renderer;
this.service = service;
this.canBeEmpty = false;
this.dateRangeModelChange = new EventEmitter();
this.dateRangeChanged = new EventEmitter();
this.inputFocusBlur = new EventEmitter();
this.selectedDate = new EventEmitter();
this.state = this.service.getDefaultState();
this.options = this.service.getDefaultOptions();
this.settings = this.service.getDefaultSettings();
this.config = Object.assign(this.options, this.settings);
this.state.todayTime = this.service.getZoneToday(this.state.selectedTimezone, this.config.viewDateFormat);
this.renderer.listen("document", "click", (event) => {
if (this.state.isCalendarVisible &&
event.target &&
!event.target.parentElement.getElementsByClassName("ngx-datetime-range-picker-select-panel")
.length &&
event.target.className !== "mat-option-text" &&
this.element.nativeElement !== event.target &&
!this.element.nativeElement.contains(event.target)) {
this.onCalendarClose(event);
}
});
}
ngOnChanges(changes) {
const { canBeEmpty, settings, dateRangeModel, optionService, options } = changes;
if (canBeEmpty) {
this.canBeEmpty = canBeEmpty.currentValue;
}
if (settings) {
this.service.checkSettingsValidity(settings.currentValue);
this.settings = mergeDeep(this.settings, settings.currentValue);
}
if (dateRangeModel) {
this.dateRangeModel = dateRangeModel.currentValue;
}
if (dateRangeModel && !dateRangeModel.firstChange) {
const previousValue = dateRangeModel.previousValue[this.config.type];
const currentValue = dateRangeModel.currentValue[this.config.type];
if (previousValue &&
currentValue &&
previousValue.startDate === currentValue.startDate &&
previousValue.endDate === currentValue.endDate) {
return;
}
}
if (optionService && optionService.currentValue) {
optionService.currentValue.subscribe((dateOptions) => {
if (typeof dateOptions === "object" && !Array.isArray(dateOptions)) {
this.options = dateOptions.plain ? dateOptions.plain() : dateOptions;
}
}, (err) => {
console.error(`ERR_NGX_DATETIME_RANGE_PICKER:
Filter Call Failure:
${err}
`);
}, () => {
this.init();
});
}
if (options) {
this.options = options ? options.currentValue : this.options;
}
if (!optionService) {
this.init();
}
}
// Events
onDateRangeInputChange(value) {
this.dateRangeSelected();
}
setDisabledState(disabled) {
this.config.componentDisabled = disabled;
}
onComponentClick() {
this.state.isCalendarVisible = !this.state.isCalendarVisible;
}
onFocusInput(event) {
this.inputFocusBlur.emit({
reason: InputFocusBlur.focus,
value: event.target.value
});
}
onBlurInput(event) {
const value = event.target.value;
this.state.selectedDateText = value;
this.inputFocusBlur.emit({
reason: InputFocusBlur.blur,
value
});
}
onCalendarClose(event) {
if (this.config.startDate && this.config.endDate) {
if (this.filterInputBox) {
this.filterInputBox.nativeElement.classList.remove("empty-filter");
}
this.state.isCalendarVisible = false;
}
else {
// this.filterInputBox.nativeElement.classList.add('empty-filter');
}
}
isPrevAvailable(side) {
const { label, labelFormat, type } = this.service.getLabelProps(this.state, this.config.type, side);
return (moment(label, labelFormat)
.startOf(type)
.valueOf() >
moment(this.config.minDate, DEFAULT_DATE_FORMAT)
.startOf(type)
.valueOf());
}
isNextAvailable(side) {
const { label, labelFormat, type } = this.service.getLabelProps(this.state, this.config.type, side);
return (moment(label, labelFormat)
.endOf(type)
.valueOf() <
moment(this.config.maxDate, DEFAULT_DATE_FORMAT)
.endOf(type)
.valueOf());
}
getCalendarColspan() {
return this.service.getCalendarColspan(this.config.type);
}
getCalendarRowItemColspan() {
return this.service.getCalendarRowItemColspan(this.config.type);
}
onClickPrevious(side) {
const { label, labelFormat, type } = this.service.getLabelProps(this.state, this.config.type, side);
const startDate = moment(label, labelFormat)
.subtract(1, type)
.startOf(type)
.format(DEFAULT_DATE_FORMAT);
this.state.dates[side] = this.generateCalendar(startDate, side);
}
onClickNext(side) {
const { label, labelFormat, type } = this.service.getLabelProps(this.state, this.config.type, side);
const endDate = moment(label, labelFormat)
.add(1, type)
.endOf(type)
.format(DEFAULT_DATE_FORMAT);
this.state.dates[side] = this.generateCalendar(endDate, side);
}
onCellClick(item, itemCell, side) {
const date = moment(item.date, DEFAULT_DATE_FORMAT).valueOf();
const startDate = moment(this.config.startDate, DEFAULT_DATE_FORMAT).valueOf();
const endDate = moment(this.config.endDate, DEFAULT_DATE_FORMAT).valueOf();
const minDate = moment(this.config.minDate, DEFAULT_DATE_FORMAT).valueOf();
const maxDate = moment(this.config.maxDate, DEFAULT_DATE_FORMAT).valueOf();
if (!item.available) {
if (date < minDate || date > maxDate) {
return;
}
this.state.dates[side] = this.generateCalendar(item.date, side);
}
if (endDate || date < startDate) {
this.config.endDate = null;
this.config.startDate = item.date;
this.state.activeItem.left = item;
}
else if (!endDate && date < startDate) {
this.config.endDate = cloneDeep(this.config.startDate);
this.state.activeItem.right = item;
}
else {
this.config.endDate = item.date;
this.state.activeItem.right = item;
}
if (this.config.singleDatePicker) {
this.config.endDate = cloneDeep(this.config.startDate);
this.state.activeItem.right = this.state.activeItem.left = item;
}
this.doApply();
}
onCellMouseEnter(item, itemCell) {
if (!item.available) {
return;
}
const date = moment(item.date, DEFAULT_DATE_FORMAT).valueOf();
const startDate = moment(this.config.startDate, DEFAULT_DATE_FORMAT).valueOf();
const endDate = moment(this.config.endDate, DEFAULT_DATE_FORMAT).valueOf();
const hoverItemText = itemCell ? itemCell.innerText : "";
let hoverItemFirstDate = itemCell ? itemCell.getAttribute("firstDay") : "";
let hoverItemLastDate = itemCell ? itemCell.getAttribute("lastDay") : "";
hoverItemFirstDate = moment(hoverItemFirstDate, DEFAULT_DATE_FORMAT).format(this.config.viewDateFormat);
hoverItemLastDate = moment(hoverItemLastDate, DEFAULT_DATE_FORMAT).format(this.config.viewDateFormat);
let activeItemInputFieldText = `${hoverItemText} (${hoverItemFirstDate} - ${hoverItemLastDate})`;
if (this.config.type === "daily") {
activeItemInputFieldText = `${hoverItemLastDate}`;
}
if (!endDate) {
const func = (rowItem) => {
if (rowItem.available) {
const hoverItemDate = rowItem.date ? moment(rowItem.date, DEFAULT_DATE_FORMAT).valueOf() : rowItem.date;
if ((hoverItemDate > startDate && hoverItemDate < date) || date === hoverItemDate) {
rowItem.inRange = true;
this.state.dateTitleText.right = activeItemInputFieldText;
}
}
};
this.service.iterateOverDateObj(this.state.dates, func.bind(this));
}
else {
if (this.config.singleDatePicker) {
this.state.dateTitleText.right = activeItemInputFieldText;
}
else {
this.state.dateTitleText.left = activeItemInputFieldText;
}
}
}
onCellMouseLeave() {
if (!this.config.endDate) {
const func = (rowItem) => {
rowItem.inRange = false;
};
this.service.iterateOverDateObj(this.state.dates, func.bind(this));
}
else {
this.updateActiveItemInputField();
}
}
onRangeClick(rangeLabel, dateRangeModel) {
this.state.activeRange = rangeLabel;
if (rangeLabel === "Custom Range") {
this.state.customRange = true;
}
else {
this.state.customRange = false;
this.config.startDate = dateRangeModel.startDate;
this.config.endDate = dateRangeModel.endDate;
if (this.config.timePicker) {
this.state.times = {};
}
this.setActiveItemOnRangeClick();
}
}
updateCalendar() {
this.state.sides.length = 0;
this.state.dates = {};
// takes 223 milliSeconds
// Order is important left - right
if (!this.config.singleDatePicker) {
this.state.sides.push("left");
this.state.dates.left = this.generateCalendar(this.config.startDate, "left");
if (this.config.timePicker) {
this.state.times.left = this.generateTimePicker(this.config.startTime, "left");
}
}
this.state.sides.push("right");
this.state.dates.right = this.generateCalendar(this.config.endDate, "right");
if (this.config.timePicker) {
this.state.times.right = this.generateTimePicker(this.config.endTime, "right");
}
}
onCalendarLabelChange(label, side, type) {
this.state.isCalendarVisible = true;
if (type === "month") {
this.state.selectedMonth[side] = label;
}
else if (type === "year") {
this.state.selectedYear[side] = label;
}
if (this.config.type !== "daily") {
this.state.selectedMonth[side] = "Jun";
}
if (this.config.type !== "yearly") {
const selectedMonth = `${this.state.selectedMonth[side]} ${this.state.selectedYear[side]}`;
const date = moment(selectedMonth, "MMM YYYY")
.startOf("month")
.format(DEFAULT_DATE_FORMAT);
this.state.dates[side] = this.generateCalendar(date, side);
}
else {
if (this.state.selectedYear.left <= this.state.selectedYear.right && side === "right") {
this.config.startDate = moment(this.state.selectedYear.left, "YYYY")
.startOf("year")
.format(DEFAULT_DATE_FORMAT);
this.config.endDate = moment(this.state.selectedYear.right, "YYYY")
.endOf("year")
.format(DEFAULT_DATE_FORMAT);
this.doApply();
}
const config = {
startDate: moment(this.state.selectedYear.left, "YYYY")
.startOf("year")
.format(DEFAULT_DATE_FORMAT),
type: "yearly"
};
const startDate = this.service.formatStartDate(config, this.config.viewDateFormat);
const endDate = this.config.endDate
? moment(this.config.endDate, DEFAULT_DATE_FORMAT).format(this.config.viewDateFormat)
: "";
this.state.dateTitleText.left = `${startDate}`;
this.state.dateTitleText.right = `${endDate}`;
}
}
onTimeLabelChange(item, side, timeItem) {
let time = null;
if (side === "left") {
time = this.config.startTime.split(":");
if (timeItem === "hour") {
this.config.startTime = `${item}:${time[1]}`;
}
else {
this.config.startTime = `${time[0]}:${item}`;
}
const startDateEpoch = moment(this.config.startDate, DEFAULT_DATE_FORMAT).valueOf();
const endDateEpoch = moment(this.config.endDate, DEFAULT_DATE_FORMAT).valueOf();
if (startDateEpoch === endDateEpoch) {
this.state.times.right = this.generateTimePicker(this.config.startTime, "right");
}
}
else {
time = this.config.endTime.split(":");
if (timeItem === "hour") {
this.config.endTime = `${item}:${time[1]}`;
}
else {
this.config.endTime = `${time[0]}:${item}`;
}
}
if (timeItem === "hour") {
this.state.selectedHour[side] = this.service.convertToViewTimeItem(item);
}
else {
this.state.selectedMinute[side] = this.service.convertToViewTimeItem(item);
}
}
onTimeApply() {
this.dateRangeSelected();
this.updateInputField();
}
// Helpers
init() {
this.state.isValidFilter = false;
if (!this.config) {
this.config = Object.assign(this.service.getDefaultOptions(), this.service.getDefaultSettings());
}
this.initialize();
this.parseOptions();
this.updateInputField();
}
initialize() {
this.state = this.service.getDefaultState();
}
parseOptions() {
if (this.options !== undefined) {
Object.keys(this.options).forEach((k) => {
if (!isNil(this.options[k])) {
this.config[k] = this.options[k];
}
else {
console.warn(`WARN_NGX_DATETIME_RANGE_PICKER:
'options.${k}' is undefined or null. Setting default value.
`);
}
});
}
if (this.settings !== undefined) {
Object.keys(this.settings).forEach((k) => {
if (!isNil(this.settings[k])) {
this.config[k] = this.settings[k];
}
else {
console.warn(`WARN_NGX_DATETIME_RANGE_PICKER:
'settings.${k}' is undefined or null. Setting default value.
`);
}
});
}
// check if inputDateFormat is provided
if (!this.config.inputDateFormat) {
console.warn(`WARN_NGX_DATETIME_RANGE_PICKER:
'inputDateFormat' is required to convert dates.
'inputDateFormat' not provided. Setting it to YYYY-MM-DD.
`);
this.config.inputDateFormat = DEFAULT_DATE_FORMAT;
}
if (this.config.type === "weekly" || this.config.type === "yearly") {
this.config.showRowNumber = false;
}
if (this.config.singleDatePicker) {
this.config.startDate = cloneDeep(this.config.endDate);
}
this.selectTimeZone();
this.parseOptionsToDefaultDateFormat();
this.processDateRangeModel();
this.sanitizeDates();
this.processRanges();
this.doDateRangeModelChange();
this.updateCalendar();
}
selectTimeZone() {
if (this.config.timezoneSupport) {
if (!this.config.defaultTimezone) {
this.config.defaultTimezone = USA_TZ_CODE;
}
this.state.selectedTimezone = this.config.defaultTimezone;
}
if (this.config.useLocalTimezone) {
this.state.selectedTimezone = this.state.localTimezone;
}
this.onTimezoneChange(this.state.selectedTimezone);
}
parseOptionsToDefaultDateFormat() {
this.config.minDate = this.service.formatDateToDefaultFormat(this.config.minDate, this.config.inputDateFormat);
this.config.maxDate = this.service.formatDateToDefaultFormat(this.config.maxDate, this.config.inputDateFormat);
this.config.startDate = this.service.formatDateToDefaultFormat(this.config.startDate, this.config.inputDateFormat);
this.config.endDate = this.service.formatDateToDefaultFormat(this.config.endDate, this.config.inputDateFormat);
if (this.config.timePicker) {
this.config.minTime = this.service.formatTimeToDefaultFormat(this.config.minTime);
this.config.maxTime = this.service.formatTimeToDefaultFormat(this.config.maxTime);
this.config.startTime = this.service.formatTimeToDefaultFormat(this.config.startTime);
this.config.endTime = this.service.formatTimeToDefaultFormat(this.config.endTime);
}
}
/**
* @desc sets startDate, endDate
*/
processDateRangeModel() {
if (undefined === this.dateRangeModel || isEmpty(this.dateRangeModel)) {
return;
}
if (!this.dateRangeModel[this.config.type]) {
const _optionsKeys = Object.keys(this.service.getDefaultOptions());
const _model = {};
Object.keys(this.dateRangeModel).forEach((key) => {
if (_optionsKeys.includes(key)) {
_model[key] = this.dateRangeModel[key];
delete this.dateRangeModel[key];
}
});
this.dateRangeModel[this.config.type] = _model;
if (!this.dateRangeModel[this.config.type]) {
return;
}
}
this.config.dateArray = this.dateRangeModel[this.config.type].dateArray || this.config.dateArray;
this.handleDateArray();
if (this.config.dateArray.length) {
if (!this.dateRangeModel[this.config.type].minDate) {
this.dateRangeModel[this.config.type].minDate = this.config.dateArray[0] || this.config.minDate;
}
if (!this.dateRangeModel[this.config.type].maxDate) {
this.dateRangeModel[this.config.type].maxDate =
this.config.dateArray[this.config.dateArray.length - 1] || this.config.maxDate;
}
if (!this.dateRangeModel[this.config.type].startDate) {
this.dateRangeModel[this.config.type].startDate = this.config.dateArray[0] || this.config.startDat