diff --git a/frontend/src/utils/form/datepicker.js b/frontend/src/utils/form/datepicker.js index 21b09eb19..7a8abe3ad 100644 --- a/frontend/src/utils/form/datepicker.js +++ b/frontend/src/utils/form/datepicker.js @@ -2,6 +2,7 @@ import datetime from 'tail.datetime'; import './datepicker.css'; import { Utility } from '../../core/utility'; import moment from 'moment'; +import { EventManager, EventWrapper, EVENT_TYPE } from '../../lib/event-manager/event-manager'; import * as defer from 'lodash.defer'; @@ -82,6 +83,8 @@ export class Datepicker { initialValue; _locale; + _eventManager; + _unloadIsDueToSubmit = false; constructor(element) { @@ -102,6 +105,8 @@ export class Datepicker { this._element = element; + this._eventManager = new EventManager(); + // store the previously set type to select the input format this.elementType = this._element.getAttribute('type'); @@ -179,23 +184,22 @@ export class Datepicker { } // reregister change event to prevent event loop - this._element.addEventListener('change', setDatepickerDate, { once: true }); }; // change the selected date in the tail.datetime instance if the value of the input element is changed - this._element.addEventListener('change', setDatepickerDate, { once: true }); - + const changeSelectedDateEvent = new EventWrapper(EVENT_TYPE.CHANGE, setDatepickerDate.bind(this), this._element, { once: true }); + this._eventManager.registerNewListener(changeSelectedDateEvent); // create a mutation observer that observes the datepicker instance class and sets // the datepicker-open DOM attribute of the input element if the datepicker has been opened - const datepickerInstanceObserver = new MutationObserver((mutations) => { + let callback = (mutations) => { for (const mutation of mutations) { if (!mutation.oldValue.includes(DATEPICKER_OPEN_CLASS) && this.datepickerInstance.dt.getAttribute('class').includes(DATEPICKER_OPEN_CLASS)) { this._element.setAttribute(ATTR_DATEPICKER_OPEN, true); break; } } - }); - datepickerInstanceObserver.observe(this.datepickerInstance.dt, { + }; + this._eventManager.registerNewMutationObserver(callback.bind(this), this.datepickerInstance.dt, { attributes: true, attributeFilter: ['class'], attributeOldValue: true, @@ -203,38 +207,44 @@ export class Datepicker { // close the instance on focusout of any element if another input is focussed that is neither the timepicker nor _element - window.addEventListener('focusout', event => { + const focusOutEvent = new EventWrapper(EVENT_TYPE.FOCUS_OUT,(event => { const hasFocus = event.relatedTarget !== null; const focussedIsNotTimepicker = !this.datepickerInstance.dt.contains(event.relatedTarget); const focussedIsNotElement = event.relatedTarget !== this._element; const focussedIsInDocument = window.document.contains(event.relatedTarget); if (hasFocus && focussedIsNotTimepicker && focussedIsNotElement && focussedIsInDocument) this.closeDatepickerInstance(); - }); + }).bind(this), window ); + this._eventManager.registerNewListener(focusOutEvent); // close the instance on click on any element outside of the datepicker (except the input element itself) - window.addEventListener('click', event => { + const clickOutsideEvent = new EventWrapper(EVENT_TYPE.CLICK, (event => { const targetIsOutside = !this.datepickerInstance.dt.contains(event.target) && event.target !== this.datepickerInstance.dt; const targetIsInDocument = window.document.contains(event.target); const targetIsNotElement = event.target !== this._element; if (targetIsOutside && targetIsInDocument && targetIsNotElement) this.closeDatepickerInstance(); - }); + }).bind(this), window); + this._eventManager.registerNewListener(clickOutsideEvent); // close the instance on escape keydown events - this._element.addEventListener('keydown', event => { + const escapeCloseEvent = new EventWrapper(EVENT_TYPE.KEYDOWN, (event => { if (event.keyCode === KEYCODE_ESCAPE) { this.closeDatepickerInstance(); } - }); + }).bind(this), this._element); + this._eventManager.registerNewListener(escapeCloseEvent); // format the date value of the form input element of this datepicker before form submission - this._element.form.addEventListener('submit', this._submitHandler.bind(this)); + const submitEvent = new EventWrapper(EVENT_TYPE.SUBMIT, this._submitHandler.bind(this), this._element.form); + this._eventManager.registerNewListener(submitEvent); } destroy() { this.datepickerInstance.remove(); + this._eventManager.removeAllListenersFromUtil(); + this._element.classList.remove(DATEPICKER_INITIALIZED_CLASS); }