webcimes-modal 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +15 -0
- package/LICENSE.md +21 -0
- package/README.md +247 -0
- package/demo.html +102 -0
- package/demo_test.html +0 -0
- package/images/times.svg +1 -0
- package/package.json +28 -0
- package/tsconfig.json +13 -0
- package/webcimes-modal.css +415 -0
- package/webcimes-modal.js +353 -0
- package/webcimes-modal.js.map +1 -0
- package/webcimes-modal.ts +502 -0
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2023 WebCimes - RICHARD Florian (https://webcimes.com)
|
|
3
|
+
* MIT License - https://choosealicense.com/licenses/mit/
|
|
4
|
+
* Date: 2023-03-25
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Options
|
|
11
|
+
*/
|
|
12
|
+
interface Options {
|
|
13
|
+
/** set a specific id on the modal. default "null" */
|
|
14
|
+
setId: string | null;
|
|
15
|
+
/** set a specific class on the modal, default "null" */
|
|
16
|
+
setClass: string | null;
|
|
17
|
+
/** width (specify unit), default "auto" */
|
|
18
|
+
width: string;
|
|
19
|
+
/** height (specify unit), default "auto" */
|
|
20
|
+
height: string;
|
|
21
|
+
/** html for title, default "null" */
|
|
22
|
+
titleHtml: string | null;
|
|
23
|
+
/** html for body, default "null" */
|
|
24
|
+
bodyHtml: string | null;
|
|
25
|
+
/** html for cancel button, default "null" */
|
|
26
|
+
buttonCancelHtml: string | null;
|
|
27
|
+
/** html for confirm button, default "null" */
|
|
28
|
+
buttonConfirmHtml: string | null;
|
|
29
|
+
/** close modal after trigger cancel button, default "true" */
|
|
30
|
+
closeOnCancelButton: boolean;
|
|
31
|
+
/** close modal after trigger confirm button, default "true" */
|
|
32
|
+
closeOnConfirmButton: boolean;
|
|
33
|
+
/** show close button, default "true" */
|
|
34
|
+
showCloseButton: boolean;
|
|
35
|
+
/** allow the modal to close when clicked outside, default "true" */
|
|
36
|
+
allowCloseOutside: boolean;
|
|
37
|
+
/** ability to move modal, default "true" */
|
|
38
|
+
allowMovement: boolean;
|
|
39
|
+
/** if allowMovement is set to "true", ability to move modal from header, default "true" */
|
|
40
|
+
moveFromHeader: boolean;
|
|
41
|
+
/** if allowMovement is set to "true", ability to move modal from body, default "false" */
|
|
42
|
+
moveFromBody: boolean;
|
|
43
|
+
/** if allowMovement is set to "true", ability to move modal from footer, default "true" */
|
|
44
|
+
moveFromFooter: boolean;
|
|
45
|
+
/** keep header sticky (visible) when scrolling, default "true" */
|
|
46
|
+
stickyHeader: boolean;
|
|
47
|
+
/** keep footer sticky (visible) when scrolling, default "true" */
|
|
48
|
+
stickyFooter: boolean;
|
|
49
|
+
/** add extra css style to modal, default null */
|
|
50
|
+
style: string | null;
|
|
51
|
+
/** "animDropDown" or "animFadeIn" for show animation, default "animDropDown" */
|
|
52
|
+
animationOnShow: "animDropDown" | "animFadeIn";
|
|
53
|
+
/** "animDropUp" or "animFadeOut" for destroy animation, default "animDropUp" */
|
|
54
|
+
animationOnDestroy: "animDropUp" | "animFadeOut";
|
|
55
|
+
/** animation duration in ms, default "500" */
|
|
56
|
+
animationDuration: number;
|
|
57
|
+
/** callback before show modal */
|
|
58
|
+
beforeShow: () => void;
|
|
59
|
+
/** callback after show modal */
|
|
60
|
+
afterShow: () => void;
|
|
61
|
+
/** callback before destroy modal */
|
|
62
|
+
beforeDestroy: () => void;
|
|
63
|
+
/** callback after destroy modal */
|
|
64
|
+
afterDestroy: () => void;
|
|
65
|
+
/** callback after triggering cancel button */
|
|
66
|
+
onCancelButton: () => void;
|
|
67
|
+
/** callback after triggering confirm button */
|
|
68
|
+
onConfirmButton: () => void;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Class WebcimesModal
|
|
73
|
+
*/
|
|
74
|
+
export class WebcimesModal
|
|
75
|
+
{
|
|
76
|
+
private webcimesModals: HTMLElement;
|
|
77
|
+
private modal: HTMLElement;
|
|
78
|
+
private options: Options;
|
|
79
|
+
private eventCancelButton: () => void = () => {
|
|
80
|
+
// Callback on cancel button
|
|
81
|
+
if(typeof this.options.onCancelButton === 'function')
|
|
82
|
+
{
|
|
83
|
+
this.options.onCancelButton();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
private eventConfirmButton: () => void = () => {
|
|
87
|
+
// Callback on confirm button
|
|
88
|
+
if(typeof this.options.onConfirmButton === 'function')
|
|
89
|
+
{
|
|
90
|
+
this.options.onConfirmButton();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
private eventClickOutside: (e: Event) => void = (e) => {
|
|
94
|
+
if(e.target == this.webcimesModals)
|
|
95
|
+
{
|
|
96
|
+
if(this.options.allowCloseOutside)
|
|
97
|
+
{
|
|
98
|
+
// Destroy modal
|
|
99
|
+
this.destroy();
|
|
100
|
+
}
|
|
101
|
+
else
|
|
102
|
+
{
|
|
103
|
+
// Add animation for show modal who can't be close
|
|
104
|
+
this.modal.classList.add("animGrowShrink");
|
|
105
|
+
|
|
106
|
+
// Delete animation after the animation delay
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
this.modal.classList.remove("animGrowShrink");
|
|
109
|
+
}, this.options.animationDuration);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
private eventClickCloseButton: () => void = () => {
|
|
114
|
+
// Destroy modal
|
|
115
|
+
this.destroy();
|
|
116
|
+
};
|
|
117
|
+
private eventDragModalOnTop: (e: Event) => void = (e) => {
|
|
118
|
+
// Only if target is not close button (for bug in chrome)
|
|
119
|
+
if(!(<HTMLElement>e.target).closest(".close"))
|
|
120
|
+
{
|
|
121
|
+
// If multiple modal, and modal not already on top (no next sibling), we place the current modal on the top
|
|
122
|
+
if(document.querySelectorAll(".modal").length > 1 && this.modal.nextElementSibling !== null)
|
|
123
|
+
{
|
|
124
|
+
let oldScrollTop = this.modal.scrollTop;
|
|
125
|
+
this.webcimesModals.insertAdjacentElement("beforeend", this.modal);
|
|
126
|
+
this.modal.scrollTop = oldScrollTop;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
private position: {x: number, y: number};
|
|
131
|
+
private offset: {x: number, y: number};
|
|
132
|
+
private isDragging: boolean = false;
|
|
133
|
+
private moveFromElements: HTMLElement[] = [];
|
|
134
|
+
private eventDragStart: (e: Event) => void = (e) => {
|
|
135
|
+
// Start drag only if it's not a button
|
|
136
|
+
if(!(<HTMLElement>e.target).closest("button"))
|
|
137
|
+
{
|
|
138
|
+
this.isDragging = true;
|
|
139
|
+
|
|
140
|
+
// Mouse
|
|
141
|
+
if((<MouseEvent>e).clientX)
|
|
142
|
+
{
|
|
143
|
+
this.offset = {
|
|
144
|
+
x: this.modal.offsetLeft - (<MouseEvent>e).clientX,
|
|
145
|
+
y: this.modal.offsetTop - (<MouseEvent>e).clientY
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Touch device (use the first touch only)
|
|
149
|
+
else if((<TouchEvent>e).touches)
|
|
150
|
+
{
|
|
151
|
+
this.offset = {
|
|
152
|
+
x: this.modal.offsetLeft - (<TouchEvent>e).touches[0].clientX,
|
|
153
|
+
y: this.modal.offsetTop - (<TouchEvent>e).touches[0].clientY
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
private eventMove: (e: Event) => void = (e) => {
|
|
159
|
+
if(this.isDragging)
|
|
160
|
+
{
|
|
161
|
+
// Mouse
|
|
162
|
+
if((<MouseEvent>e).clientX)
|
|
163
|
+
{
|
|
164
|
+
this.position = {
|
|
165
|
+
x: (<MouseEvent>e).clientX,
|
|
166
|
+
y: (<MouseEvent>e).clientY
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// Touch device (use the first touch only)
|
|
170
|
+
else if((<TouchEvent>e).touches)
|
|
171
|
+
{
|
|
172
|
+
this.position = {
|
|
173
|
+
x: (<TouchEvent>e).touches[0].clientX,
|
|
174
|
+
y: (<TouchEvent>e).touches[0].clientY
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
this.modal.style.left = (this.position.x + this.offset.x)+'px';
|
|
178
|
+
this.modal.style.top = (this.position.y + this.offset.y)+'px';
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
private eventDragStop: () => void = () => {
|
|
182
|
+
this.isDragging = false;
|
|
183
|
+
};
|
|
184
|
+
private eventPreventSelectText: (e: Event) => void = (e) => {
|
|
185
|
+
if(this.isDragging)
|
|
186
|
+
{
|
|
187
|
+
e.preventDefault();
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Create modal
|
|
193
|
+
* @param {Object} options
|
|
194
|
+
* @param {string | null} options.setId - set a specific id on the modal. default "null"
|
|
195
|
+
* @param {string | null} options.setClass - set a specific class on the modal, default "null"
|
|
196
|
+
* @param {string} options.width - width (specify unit), default "auto"
|
|
197
|
+
* @param {string} options.height - height (specify unit), default "auto"
|
|
198
|
+
* @param {string | null} options.titleHtml - html for title, default "null"
|
|
199
|
+
* @param {string | null} options.bodyHtml - html for body, default "null"
|
|
200
|
+
* @param {string | null} options.buttonCancelHtml - html for cancel button, default "null"
|
|
201
|
+
* @param {string | null} options.buttonConfirmHtml - html for confirm button, default "null"
|
|
202
|
+
* @param {boolean} options.closeOnCancelButton - close modal after trigger cancel button, default "true"
|
|
203
|
+
* @param {boolean} options.closeOnConfirmButton - close modal after trigger confirm button, default "true"
|
|
204
|
+
* @param {boolean} options.showCloseButton - show close button, default "true"
|
|
205
|
+
* @param {boolean} options.allowCloseOutside - allow the modal to close when clicked outside, default "true"
|
|
206
|
+
* @param {boolean} options.allowMovement - ability to move modal, default "true"
|
|
207
|
+
* @param {boolean} options.moveFromHeader - if allowMovement is set to "true", ability to move modal from header, default "true"
|
|
208
|
+
* @param {boolean} options.moveFromBody - if allowMovement is set to "true", ability to move modal from body, default "false"
|
|
209
|
+
* @param {boolean} options.moveFromFooter - if allowMovement is set to "true", ability to move modal from footer, default "true"
|
|
210
|
+
* @param {boolean} options.stickyHeader - keep header sticky (visible) when scrolling, default "true"
|
|
211
|
+
* @param {boolean} options.stickyFooter - keep footer sticky (visible) when scrolling, default "true"
|
|
212
|
+
* @param {string | null} options.style - add extra css style to modal, default null
|
|
213
|
+
* @param {"animDropDown" | "animFadeIn"} options.animationOnShow - "animDropDown" or "animFadeIn" for show animation, default "animDropDown"
|
|
214
|
+
* @param {"animDropUp" | "animFadeOut"} options.animationOnDestroy - "animDropUp" or "animFadeOut" for destroy animation, default "animDropUp"
|
|
215
|
+
* @param {number} options.animationDuration - animation duration in ms, default "500"
|
|
216
|
+
* @param {() => void} options.beforeShow - callback before show modal
|
|
217
|
+
* @param {() => void} options.afterShow - callback after show modal
|
|
218
|
+
* @param {() => void} options.beforeDestroy - callback before destroy modal
|
|
219
|
+
* @param {() => void} options.afterDestroy - callback after destroy modal
|
|
220
|
+
* @param {() => void} options.onCancelButton - callback after triggering cancel button
|
|
221
|
+
* @param {() => void} options.onConfirmButton - callback after triggering confirm button
|
|
222
|
+
*/
|
|
223
|
+
constructor(options: Options)
|
|
224
|
+
{
|
|
225
|
+
// Defaults
|
|
226
|
+
const defaults: Options = {
|
|
227
|
+
setId: null,
|
|
228
|
+
setClass: null,
|
|
229
|
+
width: 'auto',
|
|
230
|
+
height: 'auto',
|
|
231
|
+
titleHtml: null,
|
|
232
|
+
bodyHtml: null,
|
|
233
|
+
buttonCancelHtml: null,
|
|
234
|
+
buttonConfirmHtml: null,
|
|
235
|
+
closeOnCancelButton: true,
|
|
236
|
+
closeOnConfirmButton: true,
|
|
237
|
+
showCloseButton: true,
|
|
238
|
+
allowCloseOutside: true,
|
|
239
|
+
allowMovement: true,
|
|
240
|
+
moveFromHeader: true,
|
|
241
|
+
moveFromBody: false,
|
|
242
|
+
moveFromFooter: true,
|
|
243
|
+
stickyHeader: true,
|
|
244
|
+
stickyFooter: true,
|
|
245
|
+
style: null,
|
|
246
|
+
animationOnShow: 'animDropDown',
|
|
247
|
+
animationOnDestroy: 'animDropUp',
|
|
248
|
+
animationDuration: 500,
|
|
249
|
+
beforeShow: () => {},
|
|
250
|
+
afterShow: () => {},
|
|
251
|
+
beforeDestroy: () => {},
|
|
252
|
+
afterDestroy: () => {},
|
|
253
|
+
onCancelButton: () => {},
|
|
254
|
+
onConfirmButton: () => {},
|
|
255
|
+
}
|
|
256
|
+
this.options = {...defaults, ...options};
|
|
257
|
+
|
|
258
|
+
// Call init method
|
|
259
|
+
this.init();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Init modal
|
|
264
|
+
*/
|
|
265
|
+
init()
|
|
266
|
+
{
|
|
267
|
+
// Create webcimesModals
|
|
268
|
+
if(!document.querySelector(".webcimesModals"))
|
|
269
|
+
{
|
|
270
|
+
// Create webcimesModals
|
|
271
|
+
document.body.insertAdjacentHTML("beforeend", '<div class="webcimesModals animFadeIn"></div>');
|
|
272
|
+
this.webcimesModals = <HTMLElement>document.querySelector(".webcimesModals");
|
|
273
|
+
|
|
274
|
+
// Set animation duration for webcimesModals
|
|
275
|
+
this.webcimesModals.style.setProperty("animation-duration", this.options.animationDuration+"ms");
|
|
276
|
+
|
|
277
|
+
// Delete enter animation after animation delay
|
|
278
|
+
setTimeout(() => {
|
|
279
|
+
this.webcimesModals.classList.remove("animFadeIn");
|
|
280
|
+
}, this.options.animationDuration);
|
|
281
|
+
}
|
|
282
|
+
else
|
|
283
|
+
{
|
|
284
|
+
this.webcimesModals = <HTMLElement>document.querySelector(".webcimesModals");
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Callback before show modal
|
|
288
|
+
if(typeof this.options.beforeShow === 'function')
|
|
289
|
+
{
|
|
290
|
+
this.options.beforeShow();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Create modal
|
|
294
|
+
this.webcimesModals.insertAdjacentHTML("beforeend",
|
|
295
|
+
`<div class="modal `+(this.options.setClass?this.options.setClass:'')+` `+this.options.animationOnShow+`" `+(this.options.setClass?'id="'+this.options.setId+'"':'')+`>
|
|
296
|
+
`+(this.options.titleHtml||this.options.showCloseButton?
|
|
297
|
+
`<div class="modalHeader `+(this.options.stickyHeader?'sticky':'')+` `+(this.options.moveFromHeader?'movable':'')+`">
|
|
298
|
+
`+(this.options.titleHtml?'<div class="title">'+this.options.titleHtml+'</div>':'')+`
|
|
299
|
+
`+(this.options.showCloseButton?'<button class="close"></button>':'')+`
|
|
300
|
+
</div>`
|
|
301
|
+
:'')+`
|
|
302
|
+
`+(this.options.bodyHtml?
|
|
303
|
+
`<div class="modalBody `+(this.options.moveFromBody?'movable':'')+`">
|
|
304
|
+
`+this.options.bodyHtml+`
|
|
305
|
+
</div>`
|
|
306
|
+
:'')+`
|
|
307
|
+
`+(this.options.buttonCancelHtml||this.options.buttonConfirmHtml?
|
|
308
|
+
`<div class="modalFooter `+(this.options.stickyFooter?'sticky':'')+` `+(this.options.moveFromFooter?'movable':'')+`">
|
|
309
|
+
`+(this.options.buttonCancelHtml?'<button class="cancel '+(this.options.closeOnCancelButton?'close':'')+'">'+this.options.buttonCancelHtml+'</button>':'')+`
|
|
310
|
+
`+(this.options.buttonConfirmHtml?'<button class="confirm '+(this.options.closeOnConfirmButton?'close':'')+'">'+this.options.buttonConfirmHtml+'</button>':'')+`
|
|
311
|
+
</div>`
|
|
312
|
+
:'')+`
|
|
313
|
+
</div>`
|
|
314
|
+
);
|
|
315
|
+
this.modal = <HTMLElement>this.webcimesModals.lastElementChild;
|
|
316
|
+
|
|
317
|
+
// Set animation duration for modal
|
|
318
|
+
this.modal.style.setProperty("animation-duration", this.options.animationDuration+"ms");
|
|
319
|
+
|
|
320
|
+
// Delete animation of enter after the animation delay
|
|
321
|
+
setTimeout(() => {
|
|
322
|
+
this.modal.classList.remove(this.options.animationOnShow);
|
|
323
|
+
|
|
324
|
+
// Callback after show modal
|
|
325
|
+
if(typeof this.options.afterShow === 'function')
|
|
326
|
+
{
|
|
327
|
+
this.options.afterShow();
|
|
328
|
+
}
|
|
329
|
+
}, this.options.animationDuration);
|
|
330
|
+
|
|
331
|
+
// Width of modal
|
|
332
|
+
this.modal.style.setProperty("max-width", "90%");
|
|
333
|
+
if(this.options.width != "auto" && this.options.width)
|
|
334
|
+
{
|
|
335
|
+
this.modal.style.setProperty("width", this.options.width);
|
|
336
|
+
}
|
|
337
|
+
else
|
|
338
|
+
{
|
|
339
|
+
// "max-content" is for keep size in "auto" and for maximum to max-width
|
|
340
|
+
this.modal.style.setProperty("width", "max-content");
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Height of modal
|
|
344
|
+
this.modal.style.setProperty("max-height", "90%");
|
|
345
|
+
if(this.options.height != "auto" && this.options.height)
|
|
346
|
+
{
|
|
347
|
+
this.modal.style.setProperty("height", this.options.height);
|
|
348
|
+
}
|
|
349
|
+
else
|
|
350
|
+
{
|
|
351
|
+
// "max-content" is for keep size in "auto" and for maximum to max-height
|
|
352
|
+
this.modal.style.setProperty("height", "max-content");
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Style
|
|
356
|
+
if(this.options.style)
|
|
357
|
+
{
|
|
358
|
+
let oldStyle = this.modal.getAttribute("style");
|
|
359
|
+
this.modal.setAttribute("style", oldStyle+this.options.style);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Event on cancel button
|
|
363
|
+
if(this.options.buttonCancelHtml)
|
|
364
|
+
{
|
|
365
|
+
this.modal.querySelector(".cancel")?.addEventListener("click", this.eventCancelButton);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Event on confirm button
|
|
369
|
+
if(this.options.buttonConfirmHtml)
|
|
370
|
+
{
|
|
371
|
+
this.modal.querySelector(".confirm")?.addEventListener("click", this.eventConfirmButton);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Event click outside (on webcimesModals)
|
|
375
|
+
this.webcimesModals.addEventListener("click", this.eventClickOutside);
|
|
376
|
+
|
|
377
|
+
// Event close modal when click on close button
|
|
378
|
+
this.modal.querySelectorAll(".close").forEach((el) => {
|
|
379
|
+
el.addEventListener("click", this.eventClickCloseButton);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// Place selected modal on top
|
|
383
|
+
['mousedown', 'touchstart'].forEach((typeEvent) => {
|
|
384
|
+
this.modal.addEventListener(typeEvent, this.eventDragModalOnTop);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Move modal
|
|
388
|
+
if(this.options.allowMovement && (this.options.moveFromHeader || this.options.moveFromBody || this.options.moveFromFooter))
|
|
389
|
+
{
|
|
390
|
+
if(this.options.moveFromHeader && this.modal.querySelector(".modalHeader"))
|
|
391
|
+
{
|
|
392
|
+
this.moveFromElements.push(<HTMLElement>this.modal.querySelector(".modalHeader"));
|
|
393
|
+
}
|
|
394
|
+
if(this.options.moveFromBody && this.modal.querySelector(".modalBody"))
|
|
395
|
+
{
|
|
396
|
+
this.moveFromElements.push(<HTMLElement>this.modal.querySelector(".modalBody"));
|
|
397
|
+
}
|
|
398
|
+
if(this.options.moveFromFooter && this.modal.querySelector(".modalFooter"))
|
|
399
|
+
{
|
|
400
|
+
this.moveFromElements.push(<HTMLElement>this.modal.querySelector(".modalFooter"));
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
['mousedown', 'touchstart'].forEach((typeEvent) => {
|
|
404
|
+
this.moveFromElements.forEach((el) => {
|
|
405
|
+
el.addEventListener(typeEvent, this.eventDragStart);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
['mousemove', 'touchmove'].forEach((typeEvent) => {
|
|
410
|
+
document.addEventListener(typeEvent, this.eventMove);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
['mouseup', 'touchend'].forEach((typeEvent) => {
|
|
414
|
+
document.addEventListener(typeEvent, this.eventDragStop);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
document.addEventListener("selectstart", this.eventPreventSelectText);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Destroy modal
|
|
423
|
+
*/
|
|
424
|
+
destroy()
|
|
425
|
+
{
|
|
426
|
+
// If modal is not already destroying
|
|
427
|
+
if(!this.modal.getAttribute("data-destroying"))
|
|
428
|
+
{
|
|
429
|
+
// Callback before destroy modal
|
|
430
|
+
if(typeof this.options.beforeDestroy === 'function')
|
|
431
|
+
{
|
|
432
|
+
this.options.beforeDestroy();
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Close webcimesModals (according the number of modal not already destroying)
|
|
436
|
+
if(document.querySelectorAll(".modal:not([data-destroying])").length == 1)
|
|
437
|
+
{
|
|
438
|
+
this.webcimesModals.classList.add("animFadeOut");
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Close modal
|
|
442
|
+
this.modal.setAttribute("data-destroying", "1");
|
|
443
|
+
this.modal.classList.add(this.options.animationOnDestroy);
|
|
444
|
+
|
|
445
|
+
// Destroy all events from modal and remove webcimesModals or modal after animation duration
|
|
446
|
+
setTimeout(() => {
|
|
447
|
+
if(typeof this.modal !== 'undefined')
|
|
448
|
+
{
|
|
449
|
+
// Destroy all events from modal
|
|
450
|
+
|
|
451
|
+
if(this.options.buttonCancelHtml)
|
|
452
|
+
{
|
|
453
|
+
this.modal.querySelector(".cancel")?.removeEventListener("click", this.eventCancelButton);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if(this.options.buttonConfirmHtml)
|
|
457
|
+
{
|
|
458
|
+
this.modal.querySelector(".confirm")?.removeEventListener("click", this.eventConfirmButton);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
this.webcimesModals.removeEventListener("click", this.eventClickOutside);
|
|
462
|
+
|
|
463
|
+
this.modal.querySelectorAll(".close").forEach((el) => {
|
|
464
|
+
el.removeEventListener("click", this.eventClickCloseButton);
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
['mousedown', 'touchstart'].forEach((typeEvent) => {
|
|
468
|
+
this.modal.removeEventListener(typeEvent, this.eventDragModalOnTop);
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
if(this.options.allowMovement && (this.options.moveFromHeader || this.options.moveFromBody || this.options.moveFromFooter))
|
|
472
|
+
{
|
|
473
|
+
['mousedown', 'touchstart'].forEach((typeEvent) => {
|
|
474
|
+
this.moveFromElements.forEach((el) => {
|
|
475
|
+
el.removeEventListener(typeEvent, this.eventDragStart);
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
['mousemove', 'touchmove'].forEach((typeEvent) => {
|
|
480
|
+
document.removeEventListener(typeEvent, this.eventMove);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
['mouseup', 'touchend'].forEach((typeEvent) => {
|
|
484
|
+
document.removeEventListener(typeEvent, this.eventDragStop);
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
document.removeEventListener("selectstart", this.eventPreventSelectText);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Remove webcimesModals or modal according the number of modal
|
|
491
|
+
(document.querySelectorAll(".modal").length>1?this.modal:this.webcimesModals).remove();
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Callback after destroy modal
|
|
495
|
+
if(typeof this.options.afterDestroy === 'function')
|
|
496
|
+
{
|
|
497
|
+
this.options.afterDestroy();
|
|
498
|
+
}
|
|
499
|
+
}, this.options.animationDuration);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|