$$plugins.define('modal_handling', [], function (element, options) { /** Modal Handling * (impementation of Builder design pattern) * ------------------------------------------------------------------------- * * Modal_handling requires a '#lazymodal' modal to be attached into dom */ const modal_html = ``; const submodal_html = ``; /** setup a subdiv * * @param {string} message : message html * @param {string} btn : button label */ const subdiv = (message, btn) => { let modal_div = [ ``, (btn == '' ? '' : `
`) ].join('\n'); } // TODO: // atach modal & submodal divs as html-nodes into document var _Modals_ = { /** variables and constants * --------------------------------------------------------------------- */ loaded : [], // list of loaded modals; acts as caching mechanism too classes : [ // all posible modal classes (various designs) "modal--l", "modal--noSpaces", "modal--full", "open" ], current : '', // current modal (label) status : -1, // modal status (-1:idle, 0:initializing, 1:ready) // NOTE: property reserved for future development // TODO: track modal status /** methods * --------------------------------------------------------------------- */ /** attach * -- --- -- -- - - - * @param modal (string) : label, modal friendly name * @param director (object) : the director for the modal Builder */ attach : (modal, director) => { if (typeof window._Modals_.loaded[modal] == 'undefined') { window._Modals_.loaded[modal] = director; } }, /** exist * check if modal is loaded * --- -- -- - - - * @param modal (string) : label * @returns true|false */ exist : (modal) => { return (typeof window._Modals_.loaded[modal] == 'undefined') ? false : true; }, /** use * * @param modal : modal label * @param luggage : passed data (any type; default: null) * * NOTE: * luggage will be passed to the init function */ use : (modal, luggage = null) => { const this_ = window._Modals_; // this_.status = 0; if (!this_.exist(modal)) { require(modal, function() { this_.open(modal, luggage); }); } else { this_.open(modal, luggage); } }, /** use_modal * --- -- -- - - - * 1. load modal object (if not loaded already) * 2. setup modal * 3. constuct html content * 4, initiaize status of modal's elements * 5. prepare event listeners of modal * * @param modal (string) : modal label */ open : (modal, luggage) => { const this_ = window._Modals_; // if (this_.status !== 0) { return false; } const modalDiv = document.querySelector('#lazymodal'); const modalContentDiv = document.querySelector('#lazymodal .modal__content'); if (typeof this_.loaded[modal] == 'undefined') { return false; } // remove previous modal handlers if (this_.current != modal) { this_.destroy_modal_events(this_.current); } // set display classes; +open this_.set_modal_classes(this_.loaded[modal]['classes']); modalDiv.classList.add("open"); // constuct html if (this_.current != modal) { modalContentDiv.innerHTML = (this_.loaded[modal]['html'] instanceof Function) ? this_.loaded[modal]['html']() : this_.loaded[modal]['html']; } // init (ex. load values on forms) if (this_.loaded[modal]['init']) { this_.loaded[modal]['init'](luggage); } // prepare events (if not the same modal) if (this_.current != modal) { this_.prepare_modal_events(modal); } // set current model if (this_.current != modal) { this_.current = modal; } // this_.status = 1; // return true; }, /** set classes to modal * --------------------------------------------------------------------- * @param classes (array) */ set_modal_classes : (classes) => { const this_ = window._Modals_; const modalDiv = document.querySelector('#lazymodal'); // remove old classes if existed this_.classes.forEach( c => { modalDiv.classList.remove(c); }); // add new classes classes.forEach( c => { modalDiv.classList.add(c); }); }, /** prepare (create) event listenerts for the specified modal * --------------------------------------------------------------------- */ prepare_modal_events : ( modal ) => { if (!window._Modals_.loaded[modal]) { return false; } if (!window._Modals_.loaded[modal]['events']) { return false; } if (!window._Modals_.loaded[modal]['events']) { return false; } let evTree = window._Modals_.loaded[modal]['events']; for (selector in evTree) { let collection = document.querySelectorAll(selector); for (ev in evTree[selector]) { // add event listener for eadh item of collection collection.forEach( el => { el.addEventListener( ev, evTree[selector][ev] ); }); } } }, // destroy (remove) event listeners for the specified modal // --------------------------------------------------------------------- destroy_modal_events : (modal) => { if (!window._Modals_.loaded[modal]) { return false; } if (!window._Modals_.loaded[modal]['events']) { return false; } let evTree = window._Modals_.loaded[modal]['events']; for (selector in evTree) { let collection = document.querySelectorAll(selector); for (ev in evTree[selector]) { // remove event listener for eadh item of collection collection.forEach( el => { el.removeEventListener( ev, evTree[selector][ev] ); }); } } return true; }, // sub-modals //////////////////////////////////////////////////////////////////////// /** show mini * * @param {obj} director * * director structure: { * message : html * button : ... * } */ show_mini : (director) => { console.log(director); }, /** close_mini * * closes the opened mini-modal * * @param (void) */ close_mini: () => { console.log('message modal closed'); } } // attach/install _Modals_ object onto window window._Modals_ = _Modals_; });