summaryrefslogtreecommitdiff
path: root/html/assets/js/modals/modal_handling.js
blob: 0009be6b63fa3908212f124c8aae780a70bc79b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
$$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 = `<div id="lazymodal" class="modal" data-plugin-modal="">
        <div class="modal__bg modal__close"></div>
        <div class="modal__wrap">
            <button class="modal__close modal__closeButton iconButton iconButton--s iconButton--black icon-close"></button>
            <div class="modal__content">
            </div>
        </div>
    </div>`;

    const submodal_html = `<div class="modal modal--l message-modal" data-plugin-modal="">
        <div class="modal__bg modal__close"></div>
        <div class="modal__wrap">
            <button class="modal__close modal__closeButton iconButton iconButton--s iconButton--black icon-close"></button>
        </div>
    </div>`;

        
    /** setup a subdiv
     * 
     * @param {string} message : message html
     * @param {string} btn : button label
     */
    const subdiv = (message, btn) => {
        let modal_div = [
            `<h2 class="modal__title">${message}</h2>`,
            (btn == '' ? '' : `<div class="btnWrap btnWrap--hCenter"><button class="button modal__close">${btn}</button></div>`)
        ].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_;


});