feat(datepicker): define instance collection singleton

This commit is contained in:
Sarah Vaupel 2019-08-13 16:47:01 +02:00
parent 939bbfa884
commit f5636b81d1
2 changed files with 51 additions and 12 deletions

View File

@ -4,6 +4,12 @@ import { Utility } from '../../core/utility';
const FORM_DATE_FORMAT = 'yyyy-mm-dd"T"HH:MM:ss';
/* TODO:
- DONE define a map of form id to instance lists
- DONE define a function that formats all dates of a form with a specified id
- WIP call this function where formdata appears in mass-input.js, async-form.js and async-table.js
*/
const DATEPICKER_UTIL_SELECTOR = 'input[type="date"], input[type="time"], input[type="datetime-local"]';
const DATEPICKER_INITIALIZED_CLASS = 'datepicker--initialized';
@ -30,10 +36,13 @@ const DATEPICKER_CONFIG = {
})
export class Datepicker {
// singleton Map that maps a formID to a Map of Datepicker objects
static datepickerCollections;
datepickerInstance;
_element;
constructor(element) {
if (!element) {
throw new Error('Datepicker utility needs to be passed an element!');
}
@ -42,17 +51,37 @@ export class Datepicker {
return false;
}
// initialize datepickerCollections singleton if not already done
if (!Datepicker.datepickerCollections) {
Datepicker.datepickerCollections = new Map();
}
this._element = element;
// get all relevant config options for this datepicker type
const datepickerGlobalConfig = DATEPICKER_CONFIG['global'];
const datepickerConfig = DATEPICKER_CONFIG[element.getAttribute('type')];
const datepickerConfig = DATEPICKER_CONFIG[this._element.getAttribute('type')];
if (!datepickerConfig) {
throw new Error('Datepicker utility called on unsupported element!');
}
this.datepickerInstance = datetime(element, { ...datepickerGlobalConfig, ...datepickerConfig });
// initialize tail.datetime (datepicker) instance
this.datepickerInstance = datetime(this._element, { ...datepickerGlobalConfig, ...datepickerConfig });
// mark initialized
element.classList.add(DATEPICKER_INITIALIZED_CLASS);
// register this datepicker instance with the formID of the given element in the datepicker collection
const formID = this._element.form.id;
const elemID = this._element.id;
if (!Datepicker.datepickerCollections.has(formID)) {
// insert a new key value pair if the formID key is not there already
Datepicker.datepickerCollections.set(formID, new Map([[elemID, this]]));
} else {
// otherwise, insert this instance into the Map
Datepicker.datepickerCollections.get(formID).set(elemID, this);
}
// mark the form input element as initialized
this._element.classList.add(DATEPICKER_INITIALIZED_CLASS);
// close the instance if something other than the instance was clicked (i.e. if the target is not within the datepicker instance and if any previously clicked calendar view was replaced (is not in the window anymore) because it was clicked). YES, I KNOW
window.addEventListener('click', event => {
@ -62,20 +91,25 @@ export class Datepicker {
});
// close the datepicker on escape keydown events
element.addEventListener('keydown', event => {
this._element.addEventListener('keydown', event => {
if (event.keyCode === 27) {
this.datepickerInstance.close();
}
});
// format the dates before submission
element.form.addEventListener('submit', () => {
if (!this.datepickerInstance.select && !element.value) return;
element.value = dateFormat(this.datepickerInstance.select, FORM_DATE_FORMAT);
});
// format the date value of the form input element of this datepicker before form submission
this._element.form.addEventListener('submit', () => this.formatElementValue());
}
destroy() {
this.datepickerInstance.destroy();
}
}
/**
* Formats the value of this input element from datepicker format (i.e. DATEPICKER_CONFIG.dateFormat + " " + datetime.defaults.timeFormat) to Uni2work internal date format (i.e. FORM_DATE_FORMAT) required for form submission
*/
formatElementValue() {
if (!this.datepickerInstance.select || !this._element.value) return;
this._element.value = dateFormat(this.datepickerInstance.select, FORM_DATE_FORMAT);
}
}

5
jsconfig.json Normal file
View File

@ -0,0 +1,5 @@
{
"compilerOptions": {
"experimentalDecorators": true
},
}