angularx-flatpickr
Version:
An angular 17.0+ wrapper for flatpickr
599 lines (592 loc) • 24.3 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, forwardRef, EventEmitter, PLATFORM_ID, Directive, Inject, Input, Output, HostListener, InjectionToken, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import flatpickr from 'flatpickr';
import { isPlatformBrowser } from '@angular/common';
class FlatpickrDefaults {
constructor() {
/**
* Exactly the same as date format, but for the altInput field.
*/
this.altFormat = 'F j, Y';
/**
* Show the user a readable date (as per altFormat), but return something totally different to the server.
*/
this.altInput = false;
/**
* This class will be added to the input element created by the altInput option.
* Note that `altInput` already inherits classes from the original input.
*/
this.altInputClass = '';
/**
* Allows the user to enter a date directly input the input field. By default, direct entry is disabled.
*/
this.allowInput = false;
/**
* Allows the preloading of an invalid date. When disabled, the field will be cleared if the provided date is invalid
*/
this.allowInvalidPreload = false;
/**
* Instead of `body`, appends the calendar to the specified node instead.
*/
this.appendTo = undefined;
/**
* Defines how the date will be formatted in the aria-label for calendar days, using the same tokens as dateFormat. If you change this, you should choose a value that will make sense if a screen reader reads it out loud.
*/
this.ariaDateFormat = 'F j, Y';
/**
* Whether clicking on the input should open the picker.
* You could disable this if you wish to open the calendar manually `with.open()`.
*/
this.clickOpens = true;
/**
* A string of characters which are used to define how the date will be displayed in the input box.
* The supported characters are defined in the table below.
*/
this.dateFormat = 'Y-m-d';
/**
* Initial value of the hour element.
*/
this.defaultHour = 12;
/**
* Initial value of the minute element.
*/
this.defaultMinute = 0;
/**
* Initial value of the seconds element.
*/
this.defaultSeconds = 0;
/**
* See <a href="https://chmln.github.io/flatpickr/examples/#disabling-specific-dates">disabling dates</a>.
*/
this.disable = [];
/**
* Set disableMobile to true to always use the non-native picker.
* By default, Flatpickr utilizes native datetime widgets unless certain options (e.g. disable) are used.
*/
this.disableMobile = false;
/**
* Enables time picker.
*/
this.enableTime = false;
/**
* Enables seconds in the time picker.
*/
this.enableSeconds = false;
/**
* Allows using a custom date formatting function instead of the built-in handling for date formats using dateFormat, altFormat, etc.
*/
this.formatDate = undefined;
/**
* Adjusts the step for the hour input (incl. scrolling).
*/
this.hourIncrement = 1;
/**
* Displays the calendar inline.
*/
this.inline = false;
/**
* The maximum date that a user can pick to (inclusive).
*/
this.maxDate = undefined;
/**
* The minimum date that a user can start picking from (inclusive).
*/
this.minDate = undefined;
/**
* The maximum time that a user can pick to (inclusive).
*/
this.maxTime = undefined;
/**
* The minimum time that a user can start picking from (inclusive).
*/
this.minTime = undefined;
/**
* Adjusts the step for the minute input (incl. scrolling).
*/
this.minuteIncrement = 5;
/**
* Select a single date, multiple dates or a date range.
*/
this.mode = 'single';
/**
* HTML for the arrow icon, used to switch months.
*/
this.nextArrow = '>';
/**
* Hides the day selection in calendar. Use it along with `enableTime` to create a time picker.
*/
this.noCalendar = false;
/**
* Default now to the current date
*/
this.now = new Date();
/**
* HTML for the left arrow icon.
*/
this.prevArrow = '<';
/**
* Show the month using the shorthand version (ie, Sep instead of September).
*/
this.shorthandCurrentMonth = false;
/**
* Position the calendar inside the wrapper and next to the input element. (Leave `false` unless you know what you're doing).
*/
this.static = false;
/**
* Displays time picker in 24 hour mode without AM/PM selection when enabled.
*/
this.time24hr = false;
/**
* When true, dates will parsed, formatted, and displayed in UTC.
* It's recommended that date strings contain the timezone, but not necessary.
*/
this.utc = false;
/**
* Enables display of week numbers in calendar.
*/
this.weekNumbers = false;
/**
* Custom elements and input groups.
*/
this.wrap = false;
/**
* Array of plugin instances to use.
*/
this.plugins = [];
/**
* The locale object or string to use for the locale.
*/
this.locale = 'default';
/**
* Auto convert the ngModel value from a string to a date / array of dates / from - to date object depending on the `mode`
*/
this.convertModelValue = false;
/**
* The number of months shown.
*/
this.showMonths = 1;
/**
* How the month should be displayed in the header of the calendar.
*/
this.monthSelectorType = 'static';
/**
* Array of HTML elements that should not close the picker on click.
*/
this.ignoredFocusElements = [];
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrDefaults, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrDefaults }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrDefaults, decorators: [{
type: Injectable
}] });
const FLATPICKR_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => FlatpickrDirective),
multi: true,
};
class FlatpickrDirective {
constructor(elm, defaults, renderer, platformId) {
this.elm = elm;
this.defaults = defaults;
this.renderer = renderer;
this.platformId = platformId;
/**
* Object-options that can be user for multiple instances of Flatpickr.
* Option from this object is applied only if specific option is not specified.
* Example:
* ```typescript
* options: FlatpickrDefaultsInterface = {
* altFormat: 'd/m/Y', // will be ignored since altFormat is provided via specific attribute
* altInput: true // will be used since specific attribute is not provided
* };
* ```
* ```html
* <input
* class="form-control"
* type="text"
* mwlFlatpickr
* [options]="options"
* altFormat="d/m/Y">
* ```
*/
this.options = {};
/**
* Array of HTML elements that should not close the picker on click.
*/
this.ignoredFocusElements = [];
/**
* Gets triggered once the calendar is in a ready state
*/
this.flatpickrReady = new EventEmitter();
/**
* Gets triggered when the user selects a date, or changes the time on a selected date.
*/
this.flatpickrChange = new EventEmitter();
/**
* Gets triggered when the input value is updated with a new date string.
*/
this.flatpickrValueUpdate = new EventEmitter();
/**
* Gets triggered when the calendar is opened.
*/
this.flatpickrOpen = new EventEmitter();
/**
* Gets triggered when the calendar is closed.
*/
this.flatpickrClose = new EventEmitter();
/**
* Gets triggered when the month is changed, either by the user or programmatically.
*/
this.flatpickrMonthChange = new EventEmitter();
/**
* Gets triggered when the year is changed, either by the user or programmatically.
*/
this.flatpickrYearChange = new EventEmitter();
/**
* Take full control of every date cell with this output
*/
this.flatpickrDayCreate = new EventEmitter();
this.isDisabled = false;
this.onChangeFn = () => { };
this.onTouchedFn = () => { };
}
ngAfterViewInit() {
const options = {
altFormat: this.altFormat,
altInput: this.altInput,
altInputClass: this.altInputClass,
allowInput: this.allowInput,
allowInvalidPreload: this.allowInvalidPreload,
appendTo: this.appendTo,
ariaDateFormat: this.ariaDateFormat,
clickOpens: this.clickOpens,
dateFormat: this.dateFormat,
defaultHour: this.defaultHour,
defaultMinute: this.defaultMinute,
defaultSeconds: this.defaultSeconds,
disable: this.disable,
disableMobile: this.disableMobile,
enable: this.enable,
enableTime: this.enableTime,
enableSeconds: this.enableSeconds,
formatDate: this.formatDate,
hourIncrement: this.hourIncrement,
defaultDate: this.initialValue,
inline: this.inline,
maxDate: this.maxDate,
minDate: this.minDate,
maxTime: this.maxTime,
minTime: this.minTime,
minuteIncrement: this.minuteIncrement,
mode: this.mode,
nextArrow: this.nextArrow,
noCalendar: this.noCalendar,
now: this.now,
parseDate: this.parseDate,
prevArrow: this.prevArrow,
shorthandCurrentMonth: this.shorthandCurrentMonth,
showMonths: this.showMonths,
monthSelectorType: this.monthSelectorType,
static: this.static,
time24hr: this.time24hr,
weekNumbers: this.weekNumbers,
getWeek: this.getWeek,
wrap: this.wrap,
plugins: this.plugins,
locale: this.locale,
ignoredFocusElements: this.ignoredFocusElements,
onChange: (selectedDates, dateString, instance) => {
this.flatpickrChange.emit({ selectedDates, dateString, instance });
},
onOpen: (selectedDates, dateString, instance) => {
this.flatpickrOpen.emit({ selectedDates, dateString, instance });
},
onClose: (selectedDates, dateString, instance) => {
this.flatpickrClose.emit({ selectedDates, dateString, instance });
},
onMonthChange: (selectedDates, dateString, instance) => {
this.flatpickrMonthChange.emit({ selectedDates, dateString, instance });
},
onYearChange: (selectedDates, dateString, instance) => {
this.flatpickrYearChange.emit({ selectedDates, dateString, instance });
},
onReady: (selectedDates, dateString, instance) => {
this.flatpickrReady.emit({ selectedDates, dateString, instance });
},
onValueUpdate: (selectedDates, dateString, instance) => {
this.flatpickrValueUpdate.emit({ selectedDates, dateString, instance });
},
onDayCreate: (selectedDates, dateString, instance, dayElement) => {
this.flatpickrDayCreate.emit({
selectedDates,
dateString,
instance,
dayElement,
});
},
};
Object.keys(options).forEach((key) => {
if (typeof options[key] === 'undefined') {
if (typeof this.options[key] !== 'undefined') {
options[key] = this.options[key];
}
else {
options[key] = this.defaults[key];
}
}
});
// @ts-ignore
options.time_24hr = options.time24hr;
// workaround bug in flatpickr 4.6 where it doesn't copy the classes across
// TODO - remove once fix in https://github.com/flatpickr/flatpickr/issues/1860 is released
options.altInputClass =
(options.altInputClass || '') + ' ' + this.elm.nativeElement.className;
if (!options.enable) {
delete options.enable;
}
if (isPlatformBrowser(this.platformId)) {
this.instance = flatpickr(this.elm.nativeElement, options);
this.setDisabledState(this.isDisabled);
}
}
ngOnChanges(changes) {
if (this.instance) {
Object.keys(changes).forEach((inputKey) => {
this.instance.set(inputKey, this[inputKey]);
});
}
}
ngOnDestroy() {
if (this.instance) {
this.instance.destroy();
}
}
writeValue(value) {
let convertedValue = value;
if (this.convertModelValue && this.mode === 'range' && value) {
convertedValue = [value.from, value.to];
}
if (this.instance) {
this.instance.setDate(convertedValue);
}
else {
// flatpickr hasn't been initialised yet, store the value for later use
this.initialValue = convertedValue;
}
}
registerOnChange(fn) {
this.onChangeFn = fn;
}
registerOnTouched(fn) {
this.onTouchedFn = fn;
}
setDisabledState(isDisabled) {
this.isDisabled = isDisabled;
if (this.instance) {
if (this.isDisabled) {
this.renderer.setProperty(this.instance._input, 'disabled', 'disabled');
}
else {
this.renderer.removeAttribute(this.instance._input, 'disabled');
}
}
}
inputChanged() {
const value = this.elm.nativeElement.value;
if (this.convertModelValue && typeof value === 'string') {
switch (this.mode) {
case 'multiple':
const dates = value
.split('; ')
.map((str) => this.instance.parseDate(str, this.instance.config.dateFormat, !this.instance.config.enableTime));
this.onChangeFn(dates);
break;
case 'range':
const [from, to] = value
.split(this.instance.l10n.rangeSeparator)
.map((str) => this.instance.parseDate(str, this.instance.config.dateFormat, !this.instance.config.enableTime));
this.onChangeFn({ from, to });
break;
case 'single':
default:
this.onChangeFn(this.instance.parseDate(value, this.instance.config.dateFormat, !this.instance.config.enableTime));
}
}
else {
this.onChangeFn(value);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrDirective, deps: [{ token: i0.ElementRef }, { token: FlatpickrDefaults }, { token: i0.Renderer2 }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: FlatpickrDirective, isStandalone: true, selector: "[mwlFlatpickr]", inputs: { options: "options", altFormat: "altFormat", altInput: "altInput", altInputClass: "altInputClass", allowInput: "allowInput", allowInvalidPreload: "allowInvalidPreload", appendTo: "appendTo", ariaDateFormat: "ariaDateFormat", clickOpens: "clickOpens", dateFormat: "dateFormat", defaultHour: "defaultHour", defaultMinute: "defaultMinute", defaultSeconds: "defaultSeconds", disable: "disable", disableMobile: "disableMobile", enable: "enable", enableTime: "enableTime", enableSeconds: "enableSeconds", formatDate: "formatDate", hourIncrement: "hourIncrement", inline: "inline", maxDate: "maxDate", minDate: "minDate", maxTime: "maxTime", minTime: "minTime", minuteIncrement: "minuteIncrement", mode: "mode", nextArrow: "nextArrow", noCalendar: "noCalendar", now: "now", parseDate: "parseDate", prevArrow: "prevArrow", shorthandCurrentMonth: "shorthandCurrentMonth", showMonths: "showMonths", static: "static", time24hr: "time24hr", weekNumbers: "weekNumbers", getWeek: "getWeek", wrap: "wrap", plugins: "plugins", locale: "locale", convertModelValue: "convertModelValue", monthSelectorType: "monthSelectorType", ignoredFocusElements: "ignoredFocusElements" }, outputs: { flatpickrReady: "flatpickrReady", flatpickrChange: "flatpickrChange", flatpickrValueUpdate: "flatpickrValueUpdate", flatpickrOpen: "flatpickrOpen", flatpickrClose: "flatpickrClose", flatpickrMonthChange: "flatpickrMonthChange", flatpickrYearChange: "flatpickrYearChange", flatpickrDayCreate: "flatpickrDayCreate" }, host: { listeners: { "blur": "onTouchedFn()", "input": "inputChanged()" } }, providers: [FLATPICKR_CONTROL_VALUE_ACCESSOR], exportAs: ["mwlFlatpickr"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrDirective, decorators: [{
type: Directive,
args: [{
selector: '[mwlFlatpickr]',
providers: [FLATPICKR_CONTROL_VALUE_ACCESSOR],
exportAs: 'mwlFlatpickr',
standalone: true,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: FlatpickrDefaults }, { type: i0.Renderer2 }, { type: Object, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }], propDecorators: { options: [{
type: Input
}], altFormat: [{
type: Input
}], altInput: [{
type: Input
}], altInputClass: [{
type: Input
}], allowInput: [{
type: Input
}], allowInvalidPreload: [{
type: Input
}], appendTo: [{
type: Input
}], ariaDateFormat: [{
type: Input
}], clickOpens: [{
type: Input
}], dateFormat: [{
type: Input
}], defaultHour: [{
type: Input
}], defaultMinute: [{
type: Input
}], defaultSeconds: [{
type: Input
}], disable: [{
type: Input
}], disableMobile: [{
type: Input
}], enable: [{
type: Input
}], enableTime: [{
type: Input
}], enableSeconds: [{
type: Input
}], formatDate: [{
type: Input
}], hourIncrement: [{
type: Input
}], inline: [{
type: Input
}], maxDate: [{
type: Input
}], minDate: [{
type: Input
}], maxTime: [{
type: Input
}], minTime: [{
type: Input
}], minuteIncrement: [{
type: Input
}], mode: [{
type: Input
}], nextArrow: [{
type: Input
}], noCalendar: [{
type: Input
}], now: [{
type: Input
}], parseDate: [{
type: Input
}], prevArrow: [{
type: Input
}], shorthandCurrentMonth: [{
type: Input
}], showMonths: [{
type: Input
}], static: [{
type: Input
}], time24hr: [{
type: Input
}], weekNumbers: [{
type: Input
}], getWeek: [{
type: Input
}], wrap: [{
type: Input
}], plugins: [{
type: Input
}], locale: [{
type: Input
}], convertModelValue: [{
type: Input
}], monthSelectorType: [{
type: Input
}], ignoredFocusElements: [{
type: Input
}], flatpickrReady: [{
type: Output
}], flatpickrChange: [{
type: Output
}], flatpickrValueUpdate: [{
type: Output
}], flatpickrOpen: [{
type: Output
}], flatpickrClose: [{
type: Output
}], flatpickrMonthChange: [{
type: Output
}], flatpickrYearChange: [{
type: Output
}], flatpickrDayCreate: [{
type: Output
}], onTouchedFn: [{
type: HostListener,
args: ['blur']
}], inputChanged: [{
type: HostListener,
args: ['input']
}] } });
const USER_DEFAULTS = new InjectionToken('flatpickr defaults');
function provideFlatpickrDefaults(userDefaults = {}) {
return [
{
provide: USER_DEFAULTS,
useValue: userDefaults,
},
{
provide: FlatpickrDefaults,
useFactory() {
const defaults = new FlatpickrDefaults();
Object.assign(defaults, userDefaults);
return defaults;
},
deps: [USER_DEFAULTS],
},
];
}
/**
* @deprecated Will be removed in the next major version. Please use the standalone `FlatpickrDirective` and `provideFlatpickrDefaults()` instead.
*/
class FlatpickrModule {
static forRoot(userDefaults = {}) {
return {
ngModule: FlatpickrModule,
providers: provideFlatpickrDefaults(userDefaults),
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrModule, imports: [FlatpickrDirective], exports: [FlatpickrDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FlatpickrModule, decorators: [{
type: NgModule,
args: [{
imports: [FlatpickrDirective],
exports: [FlatpickrDirective],
}]
}] });
/*
* Public API Surface of angularx-flatpickr
*/
/**
* Generated bundle index. Do not edit.
*/
export { FlatpickrDefaults, FlatpickrDirective, FlatpickrModule, USER_DEFAULTS, provideFlatpickrDefaults };
//# sourceMappingURL=angularx-flatpickr.mjs.map