PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 3.5.2
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v3.5.2
3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / assets / js / jquery-confirm / jquery-confirm.js
everest-forms / assets / js / jquery-confirm Last commit date
jquery-confirm.js 8 years ago jquery-confirm.min.js 1 year ago
jquery-confirm.js
1342 lines
1 /*!
2 * jquery-confirm v3.3.0 (http://craftpip.github.io/jquery-confirm/)
3 * Author: Boniface Pereira
4 * Website: www.craftpip.com
5 * Contact: hey@craftpip.com
6 *
7 * Copyright 2013-2017 jquery-confirm
8 * Licensed under MIT (https://github.com/craftpip/jquery-confirm/blob/master/LICENSE)
9 */
10
11 if (typeof jQuery === 'undefined') {
12 throw new Error('jquery-confirm requires jQuery');
13 }
14
15 var jconfirm, Jconfirm;
16 (function ($, window) {
17 "use strict";
18
19 $.fn.confirm = function (options, option2) {
20 if (typeof options === 'undefined') options = {};
21 if (typeof options === 'string') {
22 options = {
23 content: options,
24 title: (option2) ? option2 : false
25 };
26 }
27 /*
28 * Alias of $.confirm to emulate native confirm()
29 */
30 $(this).each(function () {
31 var $this = $(this);
32 if ($this.attr('jc-attached')) {
33 console.warn('jConfirm has already been attached to this element ', $this[0]);
34 return;
35 }
36
37 $this.on('click', function (e) {
38 e.preventDefault();
39 var jcOption = $.extend({}, options);
40 if ($this.attr('data-title'))
41 jcOption['title'] = $this.attr('data-title');
42 if ($this.attr('data-content'))
43 jcOption['content'] = $this.attr('data-content');
44 if (typeof jcOption['buttons'] == 'undefined')
45 jcOption['buttons'] = {};
46
47 jcOption['$target'] = $this;
48 if ($this.attr('href') && Object.keys(jcOption['buttons']).length == 0) {
49 var buttons = $.extend(true, {}, jconfirm.pluginDefaults.defaultButtons, (jconfirm.defaults || {}).defaultButtons || {});
50 var firstBtn = Object.keys(buttons)[0];
51 jcOption['buttons'] = buttons;
52 jcOption.buttons[firstBtn].action = function () {
53 location.href = $this.attr('href');
54 };
55 }
56 jcOption['closeIcon'] = false;
57 var instance = $.confirm(jcOption);
58 });
59
60 $this.attr('jc-attached', true);
61 });
62 return $(this);
63 };
64 $.confirm = function (options, option2) {
65 if (typeof options === 'undefined') options = {};
66 if (typeof options === 'string') {
67 options = {
68 content: options,
69 title: (option2) ? option2 : false
70 };
71 }
72
73 if (typeof options['buttons'] != 'object')
74 options['buttons'] = {};
75
76 if (Object.keys(options['buttons']).length == 0) {
77 var buttons = $.extend(true, {}, jconfirm.pluginDefaults.defaultButtons, (jconfirm.defaults || {}).defaultButtons || {});
78 options['buttons'] = buttons;
79 }
80
81 /*
82 * Alias of jconfirm
83 */
84 return jconfirm(options);
85 };
86 $.alert = function (options, option2) {
87 if (typeof options === 'undefined') options = {};
88 if (typeof options === 'string') {
89 options = {
90 content: options,
91 title: (option2) ? option2 : false
92 };
93 }
94
95 if (typeof options.buttons != 'object')
96 options.buttons = {};
97
98 if (Object.keys(options['buttons']).length == 0) {
99 var buttons = $.extend(true, {}, jconfirm.pluginDefaults.defaultButtons, (jconfirm.defaults || {}).defaultButtons || {});
100 var firstBtn = Object.keys(buttons)[0];
101 options['buttons'][firstBtn] = buttons[firstBtn];
102 }
103 /*
104 * Alias of jconfirm
105 */
106 return jconfirm(options);
107 };
108 $.dialog = function (options, option2) {
109 if (typeof options === 'undefined') options = {};
110 if (typeof options === 'string') {
111 options = {
112 content: options,
113 title: (option2) ? option2 : false,
114 closeIcon: function () {
115 // Just close the modal
116 }
117 };
118 }
119
120 options['buttons'] = {}; // purge buttons
121
122 if (typeof options['closeIcon'] == 'undefined') {
123 // Dialog must have a closeIcon.
124 options['closeIcon'] = function () {
125 }
126 }
127 /*
128 * Alias of jconfirm
129 */
130 options.confirmKeys = [13];
131 return jconfirm(options);
132 };
133
134 jconfirm = function (options) {
135 if (typeof options === 'undefined') options = {};
136 /*
137 * initial function for calling.
138 */
139 var pluginOptions = $.extend(true, {}, jconfirm.pluginDefaults);
140 if (jconfirm.defaults) {
141 pluginOptions = $.extend(true, pluginOptions, jconfirm.defaults);
142 }
143
144 /*
145 * merge options with plugin defaults.
146 */
147 pluginOptions = $.extend(true, {}, pluginOptions, options);
148 var instance = new Jconfirm(pluginOptions);
149 jconfirm.instances.push(instance);
150 return instance;
151 };
152 Jconfirm = function (options) {
153 /*
154 * constructor function Jconfirm,
155 * options = user options.
156 */
157 $.extend(this, options);
158 this._init();
159 };
160 Jconfirm.prototype = {
161 _init: function () {
162 var that = this;
163
164 if (!jconfirm.instances.length)
165 jconfirm.lastFocused = $('body').find(':focus');
166
167 this._id = Math.round(Math.random() * 99999);
168 /**
169 * contentParsed maintains the contents for $content, before it is put in DOM
170 */
171 this.contentParsed = $(document.createElement('div'));
172
173 if (!this.lazyOpen) {
174 setTimeout(function () {
175 that.open();
176 }, 0);
177 }
178 },
179 _buildHTML: function () {
180 var that = this;
181
182 // prefix the animation string and store in animationParsed
183 this._parseAnimation(this.animation, 'o');
184 this._parseAnimation(this.closeAnimation, 'c');
185 this._parseBgDismissAnimation(this.backgroundDismissAnimation);
186 this._parseColumnClass(this.columnClass);
187 this._parseTheme(this.theme);
188 this._parseType(this.type);
189
190 /*
191 * Append html.
192 */
193 var template = $(this.template);
194 template.find('.jconfirm-box').addClass(this.animationParsed).addClass(this.backgroundDismissAnimationParsed).addClass(this.typeParsed);
195
196 if (this.typeAnimated)
197 template.find('.jconfirm-box').addClass('jconfirm-type-animated');
198
199 if (this.useBootstrap) {
200 template.find('.jc-bs3-row').addClass(this.bootstrapClasses.row);
201 template.find('.jc-bs3-row').addClass('justify-content-md-center justify-content-sm-center justify-content-xs-center justify-content-lg-center');
202
203 template.find('.jconfirm-box-container').addClass(this.columnClassParsed);
204
205 if (this.containerFluid)
206 template.find('.jc-bs3-container').addClass(this.bootstrapClasses.containerFluid);
207 else
208 template.find('.jc-bs3-container').addClass(this.bootstrapClasses.container);
209 } else {
210 template.find('.jconfirm-box').css('width', this.boxWidth);
211 }
212
213 if (this.titleClass)
214 template.find('.jconfirm-title-c').addClass(this.titleClass);
215
216 template.addClass(this.themeParsed);
217 var ariaLabel = 'jconfirm-box' + this._id;
218 template.find('.jconfirm-box').attr('aria-labelledby', ariaLabel).attr('tabindex', -1);
219 template.find('.jconfirm-content').attr('id', ariaLabel);
220 if (this.bgOpacity !== null)
221 template.find('.jconfirm-bg').css('opacity', this.bgOpacity);
222 if (this.rtl)
223 template.addClass('jconfirm-rtl');
224
225 this.$el = template.appendTo(this.container);
226 this.$jconfirmBoxContainer = this.$el.find('.jconfirm-box-container');
227 this.$jconfirmBox = this.$body = this.$el.find('.jconfirm-box');
228 this.$jconfirmBg = this.$el.find('.jconfirm-bg');
229 this.$title = this.$el.find('.jconfirm-title');
230 this.$titleContainer = this.$el.find('.jconfirm-title-c');
231 this.$content = this.$el.find('div.jconfirm-content');
232 this.$contentPane = this.$el.find('.jconfirm-content-pane');
233 this.$icon = this.$el.find('.jconfirm-icon-c');
234 this.$closeIcon = this.$el.find('.jconfirm-closeIcon');
235 this.$holder = this.$el.find('.jconfirm-holder');
236 // this.$content.css(this._getCSS(this.animationSpeed, this.animationBounce));
237 this.$btnc = this.$el.find('.jconfirm-buttons');
238 this.$scrollPane = this.$el.find('.jconfirm-scrollpane');
239
240 that.setStartingPoint();
241
242 // for loading content via URL
243 this._contentReady = $.Deferred();
244 this._modalReady = $.Deferred();
245 this.$holder.css({
246 'padding-top': this.offsetTop,
247 'padding-bottom': this.offsetBottom,
248 });
249
250 this.setTitle();
251 this.setIcon();
252 this._setButtons();
253 this._parseContent();
254 this.initDraggable();
255
256 if (this.isAjax)
257 this.showLoading(false);
258
259 $.when(this._contentReady, this._modalReady).then(function () {
260 if (that.isAjaxLoading)
261 setTimeout(function () {
262 that.isAjaxLoading = false;
263 that.setContent();
264 that.setTitle();
265 that.setIcon();
266 setTimeout(function () {
267 that.hideLoading(false);
268 that._updateContentMaxHeight();
269 }, 100);
270 if (typeof that.onContentReady === 'function')
271 that.onContentReady();
272 }, 50);
273 else {
274 // that.setContent();
275 that._updateContentMaxHeight();
276 that.setTitle();
277 that.setIcon();
278 if (typeof that.onContentReady === 'function')
279 that.onContentReady();
280 }
281
282 // start countdown after content has loaded.
283 if (that.autoClose)
284 that._startCountDown();
285 });
286
287 this._watchContent();
288
289 if (this.animation === 'none') {
290 this.animationSpeed = 1;
291 this.animationBounce = 1;
292 }
293
294 this.$body.css(this._getCSS(this.animationSpeed, this.animationBounce));
295 this.$contentPane.css(this._getCSS(this.animationSpeed, 1));
296 this.$jconfirmBg.css(this._getCSS(this.animationSpeed, 1));
297 this.$jconfirmBoxContainer.css(this._getCSS(this.animationSpeed, 1));
298 },
299 _typePrefix: 'jconfirm-type-',
300 typeParsed: '',
301 _parseType: function (type) {
302 this.typeParsed = this._typePrefix + type;
303 },
304 setType: function (type) {
305 var oldClass = this.typeParsed;
306 this._parseType(type);
307 this.$jconfirmBox.removeClass(oldClass).addClass(this.typeParsed);
308 },
309 themeParsed: '',
310 _themePrefix: 'jconfirm-',
311 setTheme: function (theme) {
312 var previous = this.theme;
313 this.theme = theme || this.theme;
314 this._parseTheme(this.theme);
315 if (previous)
316 this.$el.removeClass(previous);
317 this.$el.addClass(this.themeParsed);
318 this.theme = theme;
319 },
320 _parseTheme: function (theme) {
321 var that = this;
322 theme = theme.split(',');
323 $.each(theme, function (k, a) {
324 if (a.indexOf(that._themePrefix) === -1)
325 theme[k] = that._themePrefix + $.trim(a);
326 });
327 this.themeParsed = theme.join(' ').toLowerCase();
328 },
329 backgroundDismissAnimationParsed: '',
330 _bgDismissPrefix: 'jconfirm-hilight-',
331 _parseBgDismissAnimation: function (bgDismissAnimation) {
332 var animation = bgDismissAnimation.split(',');
333 var that = this;
334 $.each(animation, function (k, a) {
335 if (a.indexOf(that._bgDismissPrefix) === -1)
336 animation[k] = that._bgDismissPrefix + $.trim(a);
337 });
338 this.backgroundDismissAnimationParsed = animation.join(' ').toLowerCase();
339 },
340 animationParsed: '',
341 closeAnimationParsed: '',
342 _animationPrefix: 'jconfirm-animation-',
343 setAnimation: function (animation) {
344 this.animation = animation || this.animation;
345 this._parseAnimation(this.animation, 'o');
346 },
347 _parseAnimation: function (animation, which) {
348 which = which || 'o'; // parse what animation and store where. open or close?
349 var animations = animation.split(',');
350 var that = this;
351 $.each(animations, function (k, a) {
352 if (a.indexOf(that._animationPrefix) === -1)
353 animations[k] = that._animationPrefix + $.trim(a);
354 });
355 var a_string = animations.join(' ').toLowerCase();
356 if (which === 'o')
357 this.animationParsed = a_string;
358 else
359 this.closeAnimationParsed = a_string;
360
361 return a_string;
362 },
363 setCloseAnimation: function (closeAnimation) {
364 this.closeAnimation = closeAnimation || this.closeAnimation;
365 this._parseAnimation(this.closeAnimation, 'c');
366 },
367 setAnimationSpeed: function (speed) {
368 this.animationSpeed = speed || this.animationSpeed;
369 // this.$body.css(this._getCSS(this.animationSpeed, this.animationBounce));
370 },
371 columnClassParsed: '',
372 setColumnClass: function (colClass) {
373 if (!this.useBootstrap) {
374 console.warn("cannot set columnClass, useBootstrap is set to false");
375 return;
376 }
377 this.columnClass = colClass || this.columnClass;
378 this._parseColumnClass(this.columnClass);
379 this.$jconfirmBoxContainer.addClass(this.columnClassParsed);
380 },
381 _updateContentMaxHeight: function () {
382 var height = $(window).height() - (this.$jconfirmBox.outerHeight() - this.$contentPane.outerHeight()) - (this.offsetTop + this.offsetBottom);
383 this.$contentPane.css({
384 'max-height': height + 'px'
385 });
386 },
387 setBoxWidth: function (width) {
388 if (this.useBootstrap) {
389 console.warn("cannot set boxWidth, useBootstrap is set to true");
390 return;
391 }
392 this.boxWidth = width;
393 this.$jconfirmBox.css('width', width);
394 },
395 _parseColumnClass: function (colClass) {
396 colClass = colClass.toLowerCase();
397 var p;
398 switch (colClass) {
399 case 'xl':
400 case 'xlarge':
401 p = 'col-md-12';
402 break;
403 case 'l':
404 case 'large':
405 p = 'col-md-8 col-md-offset-2';
406 break;
407 case 'm':
408 case 'medium':
409 p = 'col-md-6 col-md-offset-3';
410 break;
411 case 's':
412 case 'small':
413 p = 'col-md-4 col-md-offset-4';
414 break;
415 case 'xs':
416 case 'xsmall':
417 p = 'col-md-2 col-md-offset-5';
418 break;
419 default:
420 p = colClass;
421 }
422 this.columnClassParsed = p;
423 },
424 initDraggable: function () {
425 var that = this;
426 var $t = this.$titleContainer;
427
428 this.resetDrag();
429 if (this.draggable) {
430 $t.on('mousedown', function (e) {
431 $t.addClass('jconfirm-hand');
432 that.mouseX = e.clientX;
433 that.mouseY = e.clientY;
434 that.isDrag = true;
435 });
436 $(window).on('mousemove.' + this._id, function (e) {
437 if (that.isDrag) {
438 that.movingX = e.clientX - that.mouseX + that.initialX;
439 that.movingY = e.clientY - that.mouseY + that.initialY;
440 that.setDrag();
441 }
442 });
443
444 $(window).on('mouseup.' + this._id, function () {
445 $t.removeClass('jconfirm-hand');
446 if (that.isDrag) {
447 that.isDrag = false;
448 that.initialX = that.movingX;
449 that.initialY = that.movingY;
450 }
451 })
452 }
453 },
454 resetDrag: function () {
455 this.isDrag = false;
456 this.initialX = 0;
457 this.initialY = 0;
458 this.movingX = 0;
459 this.movingY = 0;
460 this.mouseX = 0;
461 this.mouseY = 0;
462 this.$jconfirmBoxContainer.css('transform', 'translate(' + 0 + 'px, ' + 0 + 'px)');
463 },
464 setDrag: function () {
465 if (!this.draggable)
466 return;
467
468 this.alignMiddle = false;
469 var boxWidth = this.$jconfirmBox.outerWidth();
470 var boxHeight = this.$jconfirmBox.outerHeight();
471 var windowWidth = $(window).width();
472 var windowHeight = $(window).height();
473 var that = this;
474 var dragUpdate = 1;
475 if (that.movingX % dragUpdate === 0 || that.movingY % dragUpdate === 0) {
476 if (that.dragWindowBorder) {
477 var leftDistance = (windowWidth / 2) - boxWidth / 2;
478 var topDistance = (windowHeight / 2) - boxHeight / 2;
479 topDistance -= that.dragWindowGap;
480 leftDistance -= that.dragWindowGap;
481
482 if (leftDistance + that.movingX < 0) {
483 that.movingX = -leftDistance;
484 } else if (leftDistance - that.movingX < 0) {
485 that.movingX = leftDistance;
486 }
487
488 if (topDistance + that.movingY < 0) {
489 that.movingY = -topDistance;
490 } else if (topDistance - that.movingY < 0) {
491 that.movingY = topDistance;
492 }
493 }
494
495 that.$jconfirmBoxContainer.css('transform', 'translate(' + that.movingX + 'px, ' + that.movingY + 'px)');
496 }
497 },
498 _scrollTop: function () {
499 if (typeof pageYOffset !== 'undefined') {
500 //most browsers except IE before #9
501 return pageYOffset;
502 }
503 else {
504 var B = document.body; //IE 'quirks'
505 var D = document.documentElement; //IE with doctype
506 D = (D.clientHeight) ? D : B;
507 return D.scrollTop;
508 }
509 },
510 _watchContent: function () {
511 var that = this;
512 if (this._timer) clearInterval(this._timer);
513
514 var prevContentHeight = 0;
515 this._timer = setInterval(function () {
516 if (that.smoothContent) {
517 var contentHeight = that.$content.outerHeight() || 0;
518 if (contentHeight !== prevContentHeight) {
519 that.$contentPane.css({
520 'height': contentHeight
521 }).scrollTop(0);
522 prevContentHeight = contentHeight;
523 }
524 var wh = $(window).height();
525 var total = that.offsetTop + that.offsetBottom + that.$jconfirmBox.height() - that.$contentPane.height() + that.$content.height();
526 if (total < wh) {
527 that.$contentPane.addClass('no-scroll');
528 } else {
529 that.$contentPane.removeClass('no-scroll');
530 }
531 }
532 }, this.watchInterval);
533 },
534 _overflowClass: 'jconfirm-overflow',
535 _hilightAnimating: false,
536 highlight: function () {
537 this.hiLightModal();
538 },
539 hiLightModal: function () {
540 var that = this;
541 if (this._hilightAnimating)
542 return;
543
544 that.$body.addClass('hilight');
545 var duration = parseFloat(that.$body.css('animation-duration')) || 2;
546 this._hilightAnimating = true;
547 setTimeout(function () {
548 that._hilightAnimating = false;
549 that.$body.removeClass('hilight');
550 }, duration * 1000);
551 },
552 _bindEvents: function () {
553 var that = this;
554 this.boxClicked = false;
555
556 this.$scrollPane.click(function (e) { // Ignore propagated clicks
557 if (!that.boxClicked) { // Background clicked
558 /*
559 If backgroundDismiss is a function and its return value is truthy
560 proceed to close the modal.
561 */
562 var buttonName = false;
563 var shouldClose = false;
564 var str;
565
566 if (typeof that.backgroundDismiss == 'function')
567 str = that.backgroundDismiss();
568 else
569 str = that.backgroundDismiss;
570
571 if (typeof str == 'string' && typeof that.buttons[str] != 'undefined') {
572 buttonName = str;
573 shouldClose = false;
574 } else if (typeof str == 'undefined' || !!(str) == true) {
575 shouldClose = true;
576 } else {
577 shouldClose = false;
578 }
579
580 if (buttonName) {
581 var btnResponse = that.buttons[buttonName].action.apply(that);
582 shouldClose = (typeof btnResponse == 'undefined') || !!(btnResponse);
583 }
584
585 if (shouldClose)
586 that.close();
587 else
588 that.hiLightModal();
589 }
590 that.boxClicked = false;
591 });
592
593 this.$jconfirmBox.click(function (e) {
594 that.boxClicked = true;
595 });
596
597 var isKeyDown = false;
598 $(window).on('jcKeyDown.' + that._id, function (e) {
599 if (!isKeyDown) {
600 isKeyDown = true;
601 }
602 });
603 $(window).on('keyup.' + that._id, function (e) {
604 if (isKeyDown) {
605 that.reactOnKey(e);
606 isKeyDown = false;
607 }
608 });
609
610 $(window).on('resize.' + this._id, function () {
611 that._updateContentMaxHeight();
612 setTimeout(function () {
613 that.resetDrag();
614 }, 100);
615 });
616 },
617 _cubic_bezier: '0.36, 0.55, 0.19',
618 _getCSS: function (speed, bounce) {
619 return {
620 '-webkit-transition-duration': speed / 1000 + 's',
621 'transition-duration': speed / 1000 + 's',
622 '-webkit-transition-timing-function': 'cubic-bezier(' + this._cubic_bezier + ', ' + bounce + ')',
623 'transition-timing-function': 'cubic-bezier(' + this._cubic_bezier + ', ' + bounce + ')'
624 };
625 },
626 _setButtons: function () {
627 var that = this;
628 /*
629 * Settings up buttons
630 */
631
632 var total_buttons = 0;
633 if (typeof this.buttons !== 'object')
634 this.buttons = {};
635
636 $.each(this.buttons, function (key, button) {
637 total_buttons += 1;
638 if (typeof button === 'function') {
639 that.buttons[key] = button = {
640 action: button
641 };
642 }
643
644 that.buttons[key].text = button.text || key;
645 that.buttons[key].btnClass = button.btnClass || 'btn-default';
646 that.buttons[key].action = button.action || function () {
647 };
648 that.buttons[key].keys = button.keys || [];
649 that.buttons[key].isHidden = button.isHidden || false;
650 that.buttons[key].isDisabled = button.isDisabled || false;
651
652 $.each(that.buttons[key].keys, function (i, a) {
653 that.buttons[key].keys[i] = a.toLowerCase();
654 });
655
656 var button_element = $('<button type="button" class="btn"></button>')
657 .html(that.buttons[key].text)
658 .addClass(that.buttons[key].btnClass)
659 .prop('disabled', that.buttons[key].isDisabled)
660 .css('display', that.buttons[key].isHidden ? 'none' : '')
661 .click(function (e) {
662 e.preventDefault();
663 var res = that.buttons[key].action.apply(that, [that.buttons[key]]);
664 that.onAction.apply(that, [key, that.buttons[key]]);
665 that._stopCountDown();
666 if (typeof res === 'undefined' || res)
667 that.close();
668 });
669
670 that.buttons[key].el = button_element;
671 that.buttons[key].setText = function (text) {
672 button_element.html(text);
673 };
674 that.buttons[key].addClass = function (className) {
675 button_element.addClass(className);
676 };
677 that.buttons[key].removeClass = function (className) {
678 button_element.removeClass(className);
679 };
680 that.buttons[key].disable = function () {
681 that.buttons[key].isDisabled = true;
682 button_element.prop('disabled', true);
683 };
684 that.buttons[key].enable = function () {
685 that.buttons[key].isDisabled = false;
686 button_element.prop('disabled', false);
687 };
688 that.buttons[key].show = function () {
689 that.buttons[key].isHidden = false;
690 button_element.css('display', '');
691 };
692 that.buttons[key].hide = function () {
693 that.buttons[key].isHidden = true;
694 button_element.css('display', 'none');
695 };
696 /*
697 Buttons are prefixed with $_ or $$ for quick access
698 */
699 that['$_' + key] = that['$$' + key] = button_element;
700 that.$btnc.append(button_element);
701 });
702
703 if (total_buttons === 0) this.$btnc.hide();
704 if (this.closeIcon === null && total_buttons === 0) {
705 /*
706 in case when no buttons are present & closeIcon is null, closeIcon is set to true,
707 set closeIcon to true to explicitly tell to hide the close icon
708 */
709 this.closeIcon = true;
710 }
711
712 if (this.closeIcon) {
713 if (this.closeIconClass) {
714 // user requires a custom class.
715 var closeHtml = '<i class="' + this.closeIconClass + '"></i>';
716 this.$closeIcon.html(closeHtml);
717 }
718
719 this.$closeIcon.click(function (e) {
720 e.preventDefault();
721
722 var buttonName = false;
723 var shouldClose = false;
724 var str;
725
726 if (typeof that.closeIcon == 'function') {
727 str = that.closeIcon();
728 } else {
729 str = that.closeIcon;
730 }
731
732 if (typeof str == 'string' && typeof that.buttons[str] != 'undefined') {
733 buttonName = str;
734 shouldClose = false;
735 } else if (typeof str == 'undefined' || !!(str) == true) {
736 shouldClose = true;
737 } else {
738 shouldClose = false;
739 }
740 if (buttonName) {
741 var btnResponse = that.buttons[buttonName].action.apply(that);
742 shouldClose = (typeof btnResponse == 'undefined') || !!(btnResponse);
743 }
744 if (shouldClose) {
745 that.close();
746 }
747 });
748 this.$closeIcon.show();
749 } else {
750 this.$closeIcon.hide();
751 }
752 },
753 setTitle: function (string, force) {
754 force = force || false;
755
756 if (typeof string !== 'undefined')
757 if (typeof string == 'string')
758 this.title = string;
759 else if (typeof string == 'function') {
760 if (typeof string.promise == 'function')
761 console.error('Promise was returned from title function, this is not supported.');
762
763 var response = string();
764 if (typeof response == 'string')
765 this.title = response;
766 else
767 this.title = false;
768 } else
769 this.title = false;
770
771 if (this.isAjaxLoading && !force)
772 return;
773
774 this.$title.html(this.title || '');
775 this.updateTitleContainer();
776 },
777 setIcon: function (iconClass, force) {
778 force = force || false;
779
780 if (typeof iconClass !== 'undefined')
781 if (typeof iconClass == 'string')
782 this.icon = iconClass;
783 else if (typeof iconClass === 'function') {
784 var response = iconClass();
785 if (typeof response == 'string')
786 this.icon = response;
787 else
788 this.icon = false;
789 }
790 else
791 this.icon = false;
792
793 if (this.isAjaxLoading && !force)
794 return;
795
796 this.$icon.html(this.icon ? '<i class="' + this.icon + '"></i>' : '');
797 this.updateTitleContainer();
798 },
799 updateTitleContainer: function () {
800 if (!this.title && !this.icon) {
801 this.$titleContainer.hide();
802 } else {
803 this.$titleContainer.show();
804 }
805 },
806 setContentPrepend: function (content, force) {
807 if (!content)
808 return;
809
810 this.contentParsed.prepend(content);
811 },
812 setContentAppend: function (content) {
813 if (!content)
814 return;
815
816 this.contentParsed.append(content);
817 },
818 setContent: function (content, force) {
819 force = !!force;
820 var that = this;
821 if (content)
822 this.contentParsed.html('').append(content);
823 if (this.isAjaxLoading && !force)
824 return;
825
826 this.$content.html('');
827 this.$content.append(this.contentParsed);
828 setTimeout(function () {
829 that.$body.find('input[autofocus]:visible:first').focus();
830 }, 100);
831 },
832 loadingSpinner: false,
833 showLoading: function (disableButtons) {
834 this.loadingSpinner = true;
835 this.$jconfirmBox.addClass('loading');
836 if (disableButtons)
837 this.$btnc.find('button').prop('disabled', true);
838
839 },
840 hideLoading: function (enableButtons) {
841 this.loadingSpinner = false;
842 this.$jconfirmBox.removeClass('loading');
843 if (enableButtons)
844 this.$btnc.find('button').prop('disabled', false);
845
846 },
847 ajaxResponse: false,
848 contentParsed: '',
849 isAjax: false,
850 isAjaxLoading: false,
851 _parseContent: function () {
852 var that = this;
853 var e = '&nbsp;';
854
855 if (typeof this.content == 'function') {
856 var res = this.content.apply(this);
857 if (typeof res == 'string') {
858 this.content = res;
859 }
860 else if (typeof res == 'object' && typeof res.always == 'function') {
861 // this is ajax loading via promise
862 this.isAjax = true;
863 this.isAjaxLoading = true;
864 res.always(function (data, status, xhr) {
865 that.ajaxResponse = {
866 data: data,
867 status: status,
868 xhr: xhr
869 };
870 that._contentReady.resolve(data, status, xhr);
871 if (typeof that.contentLoaded == 'function')
872 that.contentLoaded(data, status, xhr);
873 });
874 this.content = e;
875 } else {
876 this.content = e;
877 }
878 }
879
880 if (typeof this.content == 'string' && this.content.substr(0, 4).toLowerCase() === 'url:') {
881 this.isAjax = true;
882 this.isAjaxLoading = true;
883 var u = this.content.substring(4, this.content.length);
884 $.get(u).done(function (html) {
885 that.contentParsed.html(html);
886 }).always(function (data, status, xhr) {
887 that.ajaxResponse = {
888 data: data,
889 status: status,
890 xhr: xhr
891 };
892 that._contentReady.resolve(data, status, xhr);
893 if (typeof that.contentLoaded == 'function')
894 that.contentLoaded(data, status, xhr);
895 });
896 }
897
898 if (!this.content)
899 this.content = e;
900
901 if (!this.isAjax) {
902 this.contentParsed.html(this.content);
903 this.setContent();
904 that._contentReady.resolve();
905 }
906 },
907 _stopCountDown: function () {
908 clearInterval(this.autoCloseInterval);
909 if (this.$cd)
910 this.$cd.remove();
911 },
912 _startCountDown: function () {
913 var that = this;
914 var opt = this.autoClose.split('|');
915 if (opt.length !== 2) {
916 console.error('Invalid option for autoClose. example \'close|10000\'');
917 return false;
918 }
919
920 var button_key = opt[0];
921 var time = parseInt(opt[1]);
922 if (typeof this.buttons[button_key] === 'undefined') {
923 console.error('Invalid button key \'' + button_key + '\' for autoClose');
924 return false;
925 }
926
927 var seconds = Math.ceil(time / 1000);
928 this.$cd = $('<span class="countdown"> (' + seconds + ')</span>')
929 .appendTo(this['$_' + button_key]);
930
931 this.autoCloseInterval = setInterval(function () {
932 that.$cd.html(' (' + (seconds -= 1) + ') ');
933 if (seconds <= 0) {
934 that['$$' + button_key].trigger('click');
935 that._stopCountDown();
936 }
937 }, 1000);
938 },
939 _getKey: function (key) {
940 // very necessary keys.
941 switch (key) {
942 case 192:
943 return 'tilde';
944 case 13:
945 return 'enter';
946 case 16:
947 return 'shift';
948 case 9:
949 return 'tab';
950 case 20:
951 return 'capslock';
952 case 17:
953 return 'ctrl';
954 case 91:
955 return 'win';
956 case 18:
957 return 'alt';
958 case 27:
959 return 'esc';
960 case 32:
961 return 'space';
962 }
963
964 // only trust alphabets with this.
965 var initial = String.fromCharCode(key);
966 if (/^[A-z0-9]+$/.test(initial))
967 return initial.toLowerCase();
968 else
969 return false;
970 },
971 reactOnKey: function (e) {
972 var that = this;
973
974 /*
975 Prevent keyup event if the dialog is not last!
976 */
977 var a = $('.jconfirm');
978 if (a.eq(a.length - 1)[0] !== this.$el[0])
979 return false;
980
981 var key = e.which;
982 /*
983 Do not react if Enter or Space is pressed on input elements
984 */
985 if (this.$content.find(':input').is(':focus') && /13|32/.test(key))
986 return false;
987
988 var keyChar = this._getKey(key);
989
990 // If esc is pressed
991 if (keyChar === 'esc' && this.escapeKey) {
992 if (this.escapeKey === true) {
993 this.$scrollPane.trigger('click');
994 }
995 else if (typeof this.escapeKey === 'string' || typeof this.escapeKey === 'function') {
996 var buttonKey;
997 if (typeof this.escapeKey === 'function') {
998 buttonKey = this.escapeKey();
999 } else {
1000 buttonKey = this.escapeKey;
1001 }
1002
1003 if (buttonKey)
1004 if (typeof this.buttons[buttonKey] === 'undefined') {
1005 console.warn('Invalid escapeKey, no buttons found with key ' + buttonKey);
1006 } else {
1007 this['$_' + buttonKey].trigger('click');
1008 }
1009 }
1010 }
1011
1012 // check if any button is listening to this key.
1013 $.each(this.buttons, function (key, button) {
1014 if (button.keys.indexOf(keyChar) != -1) {
1015 that['$_' + key].trigger('click');
1016 }
1017 });
1018 },
1019 setDialogCenter: function () {
1020 console.info('setDialogCenter is deprecated, dialogs are centered with CSS3 tables');
1021 },
1022 _unwatchContent: function () {
1023 clearInterval(this._timer);
1024 },
1025 close: function () {
1026 var that = this;
1027
1028 if (typeof this.onClose === 'function')
1029 this.onClose();
1030
1031 this._unwatchContent();
1032
1033 /*
1034 unbind the window resize & keyup event.
1035 */
1036 $(window).unbind('resize.' + this._id);
1037 $(window).unbind('keyup.' + this._id);
1038 $(window).unbind('jcKeyDown.' + this._id);
1039
1040 if (this.draggable) {
1041 $(window).unbind('mousemove.' + this._id);
1042 $(window).unbind('mouseup.' + this._id);
1043 this.$titleContainer.unbind('mousedown');
1044 }
1045
1046 that.$el.removeClass(that.loadedClass);
1047 $('body').removeClass('jconfirm-no-scroll-' + that._id);
1048 that.$jconfirmBoxContainer.removeClass('jconfirm-no-transition');
1049
1050 setTimeout(function () {
1051 that.$body.addClass(that.closeAnimationParsed);
1052 that.$jconfirmBg.addClass('jconfirm-bg-h');
1053 var closeTimer = (that.closeAnimation === 'none') ? 1 : that.animationSpeed;
1054
1055 setTimeout(function () {
1056 that.$el.remove();
1057
1058 var l = jconfirm.instances;
1059 var i = jconfirm.instances.length - 1;
1060 for (i; i >= 0; i--) {
1061 if (jconfirm.instances[i]._id === that._id) {
1062 jconfirm.instances.splice(i, 1);
1063 }
1064 }
1065
1066 // Focusing a element, scrolls automatically to that element.
1067 // no instances should be open, lastFocused should be true, the lastFocused element must exists in DOM
1068 if (!jconfirm.instances.length) {
1069 if (that.scrollToPreviousElement && jconfirm.lastFocused && jconfirm.lastFocused.length && $.contains(document, jconfirm.lastFocused[0])) {
1070 var $lf = jconfirm.lastFocused;
1071 if (that.scrollToPreviousElementAnimate) {
1072 var st = $(window).scrollTop();
1073 var ot = jconfirm.lastFocused.offset().top;
1074 var wh = $(window).height();
1075 if (!(ot > st && ot < (st + wh))) {
1076 var scrollTo = (ot - Math.round((wh / 3)));
1077 $('html, body').animate({
1078 scrollTop: scrollTo
1079 }, that.animationSpeed, 'swing', function () {
1080 // gracefully scroll and then focus.
1081 $lf.focus();
1082 });
1083 } else {
1084 // the element to be focused is already in view.
1085 $lf.focus();
1086 }
1087 } else {
1088 $lf.focus();
1089 }
1090 jconfirm.lastFocused = false;
1091 }
1092 }
1093
1094 if (typeof that.onDestroy === 'function')
1095 that.onDestroy();
1096
1097 }, closeTimer * 0.40);
1098 }, 50);
1099
1100 return true;
1101 },
1102 open: function () {
1103 if (this.isOpen())
1104 return false;
1105
1106 // var that = this;
1107 this._buildHTML();
1108 this._bindEvents();
1109 this._open();
1110
1111 return true;
1112 },
1113 setStartingPoint: function () {
1114 var el = false;
1115
1116 if (this.animateFromElement !== true && this.animateFromElement) {
1117 el = this.animateFromElement;
1118 jconfirm.lastClicked = false;
1119 } else if (jconfirm.lastClicked && this.animateFromElement === true) {
1120 el = jconfirm.lastClicked;
1121 jconfirm.lastClicked = false;
1122 } else {
1123 return false;
1124 }
1125
1126 if (!el)
1127 return false;
1128
1129 var offset = el.offset();
1130
1131 var iTop = el.outerHeight() / 2;
1132 var iLeft = el.outerWidth() / 2;
1133
1134 // placing position of jconfirm modal in center of clicked element
1135 iTop -= this.$jconfirmBox.outerHeight() / 2;
1136 iLeft -= this.$jconfirmBox.outerWidth() / 2;
1137
1138 // absolute position on screen
1139 var sourceTop = offset.top + iTop;
1140 sourceTop = sourceTop - this._scrollTop();
1141 var sourceLeft = offset.left + iLeft;
1142
1143 // window halved
1144 var wh = $(window).height() / 2;
1145 var ww = $(window).width() / 2;
1146
1147 var targetH = wh - this.$jconfirmBox.outerHeight() / 2;
1148 var targetW = ww - this.$jconfirmBox.outerWidth() / 2;
1149
1150 sourceTop -= targetH;
1151 sourceLeft -= targetW;
1152
1153 // Check if the element is inside the viewable window.
1154 if (Math.abs(sourceTop) > wh || Math.abs(sourceLeft) > ww)
1155 return false;
1156
1157 this.$jconfirmBoxContainer.css('transform', 'translate(' + sourceLeft + 'px, ' + sourceTop + 'px)');
1158 },
1159 _open: function () {
1160 var that = this;
1161 if (typeof that.onOpenBefore === 'function')
1162 that.onOpenBefore();
1163
1164 this.$body.removeClass(this.animationParsed);
1165 this.$jconfirmBg.removeClass('jconfirm-bg-h');
1166 this.$body.focus();
1167
1168 that.$jconfirmBoxContainer.css('transform', 'translate(' + 0 + 'px, ' + 0 + 'px)');
1169
1170 setTimeout(function () {
1171 that.$body.css(that._getCSS(that.animationSpeed, 1));
1172 that.$body.css({
1173 'transition-property': that.$body.css('transition-property') + ', margin'
1174 });
1175 that.$jconfirmBoxContainer.addClass('jconfirm-no-transition');
1176 that._modalReady.resolve();
1177 if (typeof that.onOpen === 'function')
1178 that.onOpen();
1179
1180 that.$el.addClass(that.loadedClass);
1181 }, this.animationSpeed);
1182 },
1183 loadedClass: 'jconfirm-open',
1184 isClosed: function () {
1185 return !this.$el || this.$el.css('display') === '';
1186 },
1187 isOpen: function () {
1188 return !this.isClosed();
1189 },
1190 toggle: function () {
1191 if (!this.isOpen())
1192 this.open();
1193 else
1194 this.close();
1195 }
1196 };
1197
1198 jconfirm.instances = [];
1199 jconfirm.lastFocused = false;
1200 jconfirm.pluginDefaults = {
1201 template: '' +
1202 '<div class="jconfirm">' +
1203 '<div class="jconfirm-bg jconfirm-bg-h"></div>' +
1204 '<div class="jconfirm-scrollpane">' +
1205 '<div class="jconfirm-row">' +
1206 '<div class="jconfirm-cell">' +
1207 '<div class="jconfirm-holder">' +
1208 '<div class="jc-bs3-container">' +
1209 '<div class="jc-bs3-row">' +
1210 '<div class="jconfirm-box-container jconfirm-animated">' +
1211 '<div class="jconfirm-box" role="dialog" aria-labelledby="labelled" tabindex="-1">' +
1212 '<div class="jconfirm-closeIcon">&times;</div>' +
1213 '<div class="jconfirm-title-c">' +
1214 '<span class="jconfirm-icon-c"></span>' +
1215 '<span class="jconfirm-title"></span>' +
1216 '</div>' +
1217 '<div class="jconfirm-content-pane">' +
1218 '<div class="jconfirm-content"></div>' +
1219 '</div>' +
1220 '<div class="jconfirm-buttons">' +
1221 '</div>' +
1222 '<div class="jconfirm-clear">' +
1223 '</div>' +
1224 '</div>' +
1225 '</div>' +
1226 '</div>' +
1227 '</div>' +
1228 '</div>' +
1229 '</div>' +
1230 '</div>' +
1231 '</div></div>',
1232 title: 'Hello',
1233 titleClass: '',
1234 type: 'default',
1235 typeAnimated: true,
1236 draggable: true,
1237 dragWindowGap: 15,
1238 dragWindowBorder: true,
1239 animateFromElement: true,
1240 /**
1241 * @deprecated
1242 */
1243 alignMiddle: true,
1244 smoothContent: true,
1245 content: 'Are you sure to continue?',
1246 buttons: {},
1247 defaultButtons: {
1248 ok: {
1249 action: function () {
1250 }
1251 },
1252 close: {
1253 action: function () {
1254 }
1255 }
1256 },
1257 contentLoaded: function () {
1258 },
1259 icon: '',
1260 lazyOpen: false,
1261 bgOpacity: null,
1262 theme: 'light',
1263 animation: 'scale',
1264 closeAnimation: 'scale',
1265 animationSpeed: 400,
1266 animationBounce: 1,
1267 escapeKey: true,
1268 rtl: false,
1269 container: 'body',
1270 containerFluid: false,
1271 backgroundDismiss: false,
1272 backgroundDismissAnimation: 'shake',
1273 autoClose: false,
1274 closeIcon: null,
1275 closeIconClass: false,
1276 watchInterval: 100,
1277 columnClass: 'col-md-4 col-md-offset-4 col-sm-6 col-sm-offset-3 col-xs-10 col-xs-offset-1',
1278 boxWidth: '50%',
1279 scrollToPreviousElement: true,
1280 scrollToPreviousElementAnimate: true,
1281 useBootstrap: true,
1282 offsetTop: 40,
1283 offsetBottom: 40,
1284 bootstrapClasses: {
1285 container: 'container',
1286 containerFluid: 'container-fluid',
1287 row: 'row'
1288 },
1289 onContentReady: function () {
1290
1291 },
1292 onOpenBefore: function () {
1293
1294 },
1295 onOpen: function () {
1296
1297 },
1298 onClose: function () {
1299
1300 },
1301 onDestroy: function () {
1302
1303 },
1304 onAction: function () {
1305
1306 }
1307 };
1308
1309 /**
1310 * This refers to the issue #241 and #246
1311 *
1312 * Problem:
1313 * Button A is clicked (keydown) using the Keyboard ENTER key
1314 * A opens the jconfirm modal B,
1315 * B has registered ENTER key for one of its button C
1316 * A is released (keyup), B gets the keyup event and triggers C.
1317 *
1318 * Solution:
1319 * Register a global keydown event, that tells jconfirm if the keydown originated inside jconfirm
1320 */
1321 var keyDown = false;
1322 $(window).on('keydown', function (e) {
1323 if (!keyDown) {
1324 var $target = $(e.target);
1325 var pass = false;
1326 if ($target.closest('.jconfirm-box').length)
1327 pass = true;
1328 if (pass)
1329 $(window).trigger('jcKeyDown');
1330
1331 keyDown = true;
1332 }
1333 });
1334 $(window).on('keyup', function () {
1335 keyDown = false;
1336 });
1337 jconfirm.lastClicked = false;
1338 $(document).on('mousedown', 'button, a', function () {
1339 jconfirm.lastClicked = $(this);
1340 });
1341 })(jQuery, window);
1342