$$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 = [
`${message} `,
(btn == '' ? '' : `${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_;
});