Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 espaco 1
/**
2
Core script to handle the entire theme and core functions
3
**/
4
var App = function() {
5
 
6
    // IE mode
7
    var isRTL = false;
8
    var isIE8 = false;
9
    var isIE9 = false;
10
    var isIE10 = false;
11
 
12
    var resizeHandlers = [];
13
 
14
    var assetsPath = '../assets/';
15
 
16
    var globalImgPath = 'global/img/';
17
 
18
    var globalPluginsPath = 'global/plugins/';
19
 
20
    var globalCssPath = 'global/css/';
21
 
22
    // theme layout color set
23
 
24
    var brandColors = {
25
        'blue': '#89C4F4',
26
        'red': '#F3565D',
27
        'green': '#1bbc9b',
28
        'purple': '#9b59b6',
29
        'grey': '#95a5a6',
30
        'yellow': '#F8CB00'
31
    };
32
 
33
    // initializes main settings
34
    var handleInit = function() {
35
 
36
        if ($('body').css('direction') === 'rtl') {
37
            isRTL = true;
38
        }
39
 
40
        isIE8 = !!navigator.userAgent.match(/MSIE 8.0/);
41
        isIE9 = !!navigator.userAgent.match(/MSIE 9.0/);
42
        isIE10 = !!navigator.userAgent.match(/MSIE 10.0/);
43
 
44
        if (isIE10) {
45
            $('html').addClass('ie10'); // detect IE10 version
46
        }
47
 
48
        if (isIE10 || isIE9 || isIE8) {
49
            $('html').addClass('ie'); // detect IE10 version
50
        }
51
    };
52
 
53
    // runs callback functions set by App.addResponsiveHandler().
54
    var _runResizeHandlers = function() {
55
        // reinitialize other subscribed elements
56
        for (var i = 0; i < resizeHandlers.length; i++) {
57
            var each = resizeHandlers[i];
58
            each.call();
59
        }
60
    };
61
 
62
    // handle the layout reinitialization on window resize
63
    var handleOnResize = function() {
64
        var resize;
65
        if (isIE8) {
66
            var currheight;
67
            $(window).resize(function() {
68
                if (currheight == document.documentElement.clientHeight) {
69
                    return; //quite event since only body resized not window.
70
                }
71
                if (resize) {
72
                    clearTimeout(resize);
73
                }
74
                resize = setTimeout(function() {
75
                    _runResizeHandlers();
76
                }, 50); // wait 50ms until window resize finishes.                
77
                currheight = document.documentElement.clientHeight; // store last body client height
78
            });
79
        } else {
80
            $(window).resize(function() {
81
                if (resize) {
82
                    clearTimeout(resize);
83
                }
84
                resize = setTimeout(function() {
85
                    _runResizeHandlers();
86
                }, 50); // wait 50ms until window resize finishes.
87
            });
88
        }
89
    };
90
 
91
    // Handles portlet tools & actions
92
    var handlePortletTools = function() {
93
        // handle portlet remove
94
        $('body').on('click', '.portlet > .portlet-title > .tools > a.remove', function(e) {
95
            e.preventDefault();
96
            var portlet = $(this).closest(".portlet");
97
 
98
            if ($('body').hasClass('page-portlet-fullscreen')) {
99
                $('body').removeClass('page-portlet-fullscreen');
100
            }
101
 
102
            portlet.find('.portlet-title .fullscreen').tooltip('destroy');
103
            portlet.find('.portlet-title > .tools > .reload').tooltip('destroy');
104
            portlet.find('.portlet-title > .tools > .remove').tooltip('destroy');
105
            portlet.find('.portlet-title > .tools > .config').tooltip('destroy');
106
            portlet.find('.portlet-title > .tools > .collapse, .portlet > .portlet-title > .tools > .expand').tooltip('destroy');
107
 
108
            portlet.remove();
109
        });
110
 
111
        // handle portlet fullscreen
112
        $('body').on('click', '.portlet > .portlet-title .fullscreen', function(e) {
113
            e.preventDefault();
114
            var portlet = $(this).closest(".portlet");
115
            if (portlet.hasClass('portlet-fullscreen')) {
116
                $(this).removeClass('on');
117
                portlet.removeClass('portlet-fullscreen');
118
                $('body').removeClass('page-portlet-fullscreen');
119
                portlet.children('.portlet-body').css('height', 'auto');
120
            } else {
121
                var height = App.getViewPort().height -
122
                    portlet.children('.portlet-title').outerHeight() -
123
                    parseInt(portlet.children('.portlet-body').css('padding-top')) -
124
                    parseInt(portlet.children('.portlet-body').css('padding-bottom'));
125
 
126
                $(this).addClass('on');
127
                portlet.addClass('portlet-fullscreen');
128
                $('body').addClass('page-portlet-fullscreen');
129
                portlet.children('.portlet-body').css('height', height);
130
            }
131
        });
132
 
133
        $('body').on('click', '.portlet > .portlet-title > .tools > a.reload', function(e) {
134
            e.preventDefault();
135
            var el = $(this).closest(".portlet").children(".portlet-body");
136
            var url = $(this).attr("data-url");
137
            var error = $(this).attr("data-error-display");
138
            if (url) {
139
                App.blockUI({
140
                    target: el,
141
                    animate: true,
142
                    overlayColor: 'none'
143
                });
144
                $.ajax({
145
                    type: "GET",
146
                    cache: false,
147
                    url: url,
148
                    dataType: "html",
149
                    success: function(res) {
150
                        App.unblockUI(el);
151
                        el.html(res);
152
                        App.initAjax() // reinitialize elements & plugins for newly loaded content
153
                    },
154
                    error: function(xhr, ajaxOptions, thrownError) {
155
                        App.unblockUI(el);
156
                        var msg = 'Error on reloading the content. Please check your connection and try again.';
157
                        if (error == "toastr" && toastr) {
158
                            toastr.error(msg);
159
                        } else if (error == "notific8" && $.notific8) {
160
                            $.notific8('zindex', 11500);
161
                            $.notific8(msg, {
162
                                theme: 'ruby',
163
                                life: 3000
164
                            });
165
                        } else {
166
                            alert(msg);
167
                        }
168
                    }
169
                });
170
            } else {
171
                // for demo purpose
172
                App.blockUI({
173
                    target: el,
174
                    animate: true,
175
                    overlayColor: 'none'
176
                });
177
                window.setTimeout(function() {
178
                    App.unblockUI(el);
179
                }, 1000);
180
            }
181
        });
182
 
183
        // load ajax data on page init
184
        $('.portlet .portlet-title a.reload[data-load="true"]').click();
185
 
186
        $('body').on('click', '.portlet > .portlet-title > .tools > .collapse, .portlet .portlet-title > .tools > .expand', function(e) {
187
            e.preventDefault();
188
            var el = $(this).closest(".portlet").children(".portlet-body");
189
            if ($(this).hasClass("collapse")) {
190
                $(this).removeClass("collapse").addClass("expand");
191
                el.slideUp(200);
192
            } else {
193
                $(this).removeClass("expand").addClass("collapse");
194
                el.slideDown(200);
195
            }
196
        });
197
    };
198
 
199
    // Handlesmaterial design checkboxes
200
    var handleMaterialDesign = function() {
201
 
202
        // Material design ckeckbox and radio effects
203
        $('body').on('click', '.md-checkbox > label, .md-radio > label', function() {
204
            var the = $(this);
205
            // find the first span which is our circle/bubble
206
            var el = $(this).children('span:first-child');
207
 
208
            // add the bubble class (we do this so it doesnt show on page load)
209
            el.addClass('inc');
210
 
211
            // clone it
212
            var newone = el.clone(true);  
213
 
214
            // add the cloned version before our original
215
            el.before(newone);  
216
 
217
            // remove the original so that it is ready to run on next click
218
            $("." + el.attr("class") + ":last", the).remove();
219
        });
220
 
221
        if ($('body').hasClass('page-md')) {
222
            // Material design click effect
223
            // credit where credit's due; http://thecodeplayer.com/walkthrough/ripple-click-effect-google-material-design       
224
            var element, circle, d, x, y;
225
            $('body').on('click', 'a.btn, button.btn, input.btn, label.btn', function(e) {
226
                element = $(this);
227
 
228
                if(element.find(".md-click-circle").length == 0) {
229
                    element.prepend("<span class='md-click-circle'></span>");
230
                }
231
 
232
                circle = element.find(".md-click-circle");
233
                circle.removeClass("md-click-animate");
234
 
235
                if(!circle.height() && !circle.width()) {
236
                    d = Math.max(element.outerWidth(), element.outerHeight());
237
                    circle.css({height: d, width: d});
238
                }
239
 
240
                x = e.pageX - element.offset().left - circle.width()/2;
241
                y = e.pageY - element.offset().top - circle.height()/2;
242
 
243
                circle.css({top: y+'px', left: x+'px'}).addClass("md-click-animate");
244
 
245
                setTimeout(function() {
246
                    circle.remove();      
247
                }, 1000);
248
            });
249
        }
250
 
251
        // Floating labels
252
        var handleInput = function(el) {
253
            if (el.val() != "") {
254
                el.addClass('edited');
255
            } else {
256
                el.removeClass('edited');
257
            }
258
        }
259
 
260
        $('body').on('keydown', '.form-md-floating-label .form-control', function(e) {
261
            handleInput($(this));
262
        });
263
        $('body').on('blur', '.form-md-floating-label .form-control', function(e) {
264
            handleInput($(this));
265
        });        
266
 
267
        $('.form-md-floating-label .form-control').each(function(){
268
            if ($(this).val().length > 0) {
269
                $(this).addClass('edited');
270
            }
271
        });
272
    }
273
 
274
    // Handles custom checkboxes & radios using jQuery iCheck plugin
275
    var handleiCheck = function() {
276
        if (!$().iCheck) {
277
            return;
278
        }
279
 
280
        $('.icheck').each(function() {
281
            var checkboxClass = $(this).attr('data-checkbox') ? $(this).attr('data-checkbox') : 'icheckbox_minimal-grey';
282
            var radioClass = $(this).attr('data-radio') ? $(this).attr('data-radio') : 'iradio_minimal-grey';
283
 
284
            if (checkboxClass.indexOf('_line') > -1 || radioClass.indexOf('_line') > -1) {
285
                $(this).iCheck({
286
                    checkboxClass: checkboxClass,
287
                    radioClass: radioClass,
288
                    insert: '<div class="icheck_line-icon"></div>' + $(this).attr("data-label")
289
                });
290
            } else {
291
                $(this).iCheck({
292
                    checkboxClass: checkboxClass,
293
                    radioClass: radioClass
294
                });
295
            }
296
        });
297
    };
298
 
299
    // Handles Bootstrap switches
300
    var handleBootstrapSwitch = function() {
301
        if (!$().bootstrapSwitch) {
302
            return;
303
        }
304
        $('.make-switch').bootstrapSwitch();
305
    };
306
 
307
    // Handles Bootstrap confirmations
308
    var handleBootstrapConfirmation = function() {
309
        if (!$().confirmation) {
310
            return;
311
        }
312
        $('[data-toggle=confirmation]').confirmation({ btnOkClass: 'btn btn-sm btn-success', btnCancelClass: 'btn btn-sm btn-danger'});
313
    }
314
 
315
    // Handles Bootstrap Accordions.
316
    var handleAccordions = function() {
317
        $('body').on('shown.bs.collapse', '.accordion.scrollable', function(e) {
318
            App.scrollTo($(e.target));
319
        });
320
    };
321
 
322
    // Handles Bootstrap Tabs.
323
    var handleTabs = function() {
324
        //activate tab if tab id provided in the URL
325
        if (encodeURI(location.hash)) {
326
            var tabid = encodeURI(location.hash.substr(1));
327
            $('a[href="#' + tabid + '"]').parents('.tab-pane:hidden').each(function() {
328
                var tabid = $(this).attr("id");
329
                $('a[href="#' + tabid + '"]').click();
330
            });
331
            $('a[href="#' + tabid + '"]').click();
332
        }
333
 
334
        if ($().tabdrop) {
335
            $('.tabbable-tabdrop .nav-pills, .tabbable-tabdrop .nav-tabs').tabdrop({
336
                text: '<i class="fa fa-ellipsis-v"></i>&nbsp;<i class="fa fa-angle-down"></i>'
337
            });
338
        }
339
    };
340
 
341
    // Handles Bootstrap Modals.
342
    var handleModals = function() {        
343
        // fix stackable modal issue: when 2 or more modals opened, closing one of modal will remove .modal-open class. 
344
        $('body').on('hide.bs.modal', function() {
345
            if ($('.modal:visible').size() > 1 && $('html').hasClass('modal-open') === false) {
346
                $('html').addClass('modal-open');
347
            } else if ($('.modal:visible').size() <= 1) {
348
                $('html').removeClass('modal-open');
349
            }
350
        });
351
 
352
        // fix page scrollbars issue
353
        $('body').on('show.bs.modal', '.modal', function() {
354
            if ($(this).hasClass("modal-scroll")) {
355
                $('body').addClass("modal-open-noscroll");
356
            }
357
        });
358
 
359
        // fix page scrollbars issue
360
        $('body').on('hidden.bs.modal', '.modal', function() {
361
            $('body').removeClass("modal-open-noscroll");
362
        });
363
 
364
        // remove ajax content and remove cache on modal closed 
365
        $('body').on('hidden.bs.modal', '.modal:not(.modal-cached)', function () {
366
            $(this).removeData('bs.modal');
367
        });
368
    };
369
 
370
    // Handles Bootstrap Tooltips.
371
    var handleTooltips = function() {
372
        // global tooltips
373
        $('.tooltips').tooltip();
374
 
375
        // portlet tooltips
376
        $('.portlet > .portlet-title .fullscreen').tooltip({
377
            trigger: 'hover',
378
            container: 'body',
379
            title: 'Fullscreen'
380
        });
381
        $('.portlet > .portlet-title > .tools > .reload').tooltip({
382
            trigger: 'hover',
383
            container: 'body',
384
            title: 'Reload'
385
        });
386
        $('.portlet > .portlet-title > .tools > .remove').tooltip({
387
            trigger: 'hover',
388
            container: 'body',
389
            title: 'Remove'
390
        });
391
        $('.portlet > .portlet-title > .tools > .config').tooltip({
392
            trigger: 'hover',
393
            container: 'body',
394
            title: 'Settings'
395
        });
396
        $('.portlet > .portlet-title > .tools > .collapse, .portlet > .portlet-title > .tools > .expand').tooltip({
397
            trigger: 'hover',
398
            container: 'body',
399
            title: 'Collapse/Expand'
400
        });
401
    };
402
 
403
    // Handles Bootstrap Dropdowns
404
    var handleDropdowns = function() {
405
        /*
406
          Hold dropdown on click  
407
        */
408
        $('body').on('click', '.dropdown-menu.hold-on-click', function(e) {
409
            e.stopPropagation();
410
        });
411
    };
412
 
413
    var handleAlerts = function() {
414
        $('body').on('click', '[data-close="alert"]', function(e) {
415
            $(this).parent('.alert').hide();
416
            $(this).closest('.note').hide();
417
            e.preventDefault();
418
        });
419
 
420
        $('body').on('click', '[data-close="note"]', function(e) {
421
            $(this).closest('.note').hide();
422
            e.preventDefault();
423
        });
424
 
425
        $('body').on('click', '[data-remove="note"]', function(e) {
426
            $(this).closest('.note').remove();
427
            e.preventDefault();
428
        });
429
    };
430
 
431
    // Handle Hower Dropdowns
432
    var handleDropdownHover = function() {
433
        $('[data-hover="dropdown"]').not('.hover-initialized').each(function() {
434
            $(this).dropdownHover();
435
            $(this).addClass('hover-initialized');
436
        });
437
    };
438
 
439
    // Handle textarea autosize 
440
    var handleTextareaAutosize = function() {
441
        if (typeof(autosize) == "function") {
442
            autosize(document.querySelector('textarea.autosizeme'));
443
        }
444
    }
445
 
446
    // Handles Bootstrap Popovers
447
 
448
    // last popep popover
449
    var lastPopedPopover;
450
 
451
    var handlePopovers = function() {
452
        $('.popovers').popover();
453
 
454
        // close last displayed popover
455
 
456
        $(document).on('click.bs.popover.data-api', function(e) {
457
            if (lastPopedPopover) {
458
                lastPopedPopover.popover('hide');
459
            }
460
        });
461
    };
462
 
463
    // Handles scrollable contents using jQuery SlimScroll plugin.
464
    var handleScrollers = function() {
465
        App.initSlimScroll('.scroller');
466
    };
467
 
468
    // Handles Image Preview using jQuery Fancybox plugin
469
    var handleFancybox = function() {
470
        if (!jQuery.fancybox) {
471
            return;
472
        }
473
 
474
        if ($(".fancybox-button").size() > 0) {
475
            $(".fancybox-button").fancybox({
476
                groupAttr: 'data-rel',
477
                prevEffect: 'none',
478
                nextEffect: 'none',
479
                closeBtn: true,
480
                helpers: {
481
                    title: {
482
                        type: 'inside'
483
                    }
484
                }
485
            });
486
        }
487
    };
488
 
489
    // Handles counterup plugin wrapper
490
    var handleCounterup = function() {
491
        if (!$().counterUp) {
492
            return;
493
        }
494
 
495
        $("[data-counter='counterup']").counterUp({
496
            delay: 10,
497
            time: 1000
498
        });
499
    };
500
 
501
    // Fix input placeholder issue for IE8 and IE9
502
    var handleFixInputPlaceholderForIE = function() {
503
        //fix html5 placeholder attribute for ie7 & ie8
504
        if (isIE8 || isIE9) { // ie8 & ie9
505
            // this is html5 placeholder fix for inputs, inputs with placeholder-no-fix class will be skipped(e.g: we need this for password fields)
506
            $('input[placeholder]:not(.placeholder-no-fix), textarea[placeholder]:not(.placeholder-no-fix)').each(function() {
507
                var input = $(this);
508
 
509
                if (input.val() === '' && input.attr("placeholder") !== '') {
510
                    input.addClass("placeholder").val(input.attr('placeholder'));
511
                }
512
 
513
                input.focus(function() {
514
                    if (input.val() == input.attr('placeholder')) {
515
                        input.val('');
516
                    }
517
                });
518
 
519
                input.blur(function() {
520
                    if (input.val() === '' || input.val() == input.attr('placeholder')) {
521
                        input.val(input.attr('placeholder'));
522
                    }
523
                });
524
            });
525
        }
526
    };
527
 
528
    // Handle Select2 Dropdowns
529
    var handleSelect2 = function() {
530
        if ($().select2) {
531
            $.fn.select2.defaults.set("theme", "bootstrap");
532
            $('.select2me').select2({
533
                placeholder: "Select",
534
                width: 'auto',
535
                allowClear: true
536
            });
537
        }
538
    };
539
 
540
    // handle group element heights
541
   var handleHeight = function() {
542
       $('[data-auto-height]').each(function() {
543
            var parent = $(this);
544
            var items = $('[data-height]', parent);
545
            var height = 0;
546
            var mode = parent.attr('data-mode');
547
            var offset = parseInt(parent.attr('data-offset') ? parent.attr('data-offset') : 0);
548
 
549
            items.each(function() {
550
                if ($(this).attr('data-height') == "height") {
551
                    $(this).css('height', '');
552
                } else {
553
                    $(this).css('min-height', '');
554
                }
555
 
556
                var height_ = (mode == 'base-height' ? $(this).outerHeight() : $(this).outerHeight(true));
557
                if (height_ > height) {
558
                    height = height_;
559
                }
560
            });
561
 
562
            height = height + offset;
563
 
564
            items.each(function() {
565
                if ($(this).attr('data-height') == "height") {
566
                    $(this).css('height', height);
567
                } else {
568
                    $(this).css('min-height', height);
569
                }
570
            });
571
 
572
            if(parent.attr('data-related')) {
573
                $(parent.attr('data-related')).css('height', parent.height());
574
            }
575
       });      
576
    }
577
 
578
    //* END:CORE HANDLERS *//
579
 
580
    return {
581
 
582
        //main function to initiate the theme
583
        init: function() {
584
            //IMPORTANT!!!: Do not modify the core handlers call order.
585
 
586
            //Core handlers
587
            handleInit(); // initialize core variables
588
            handleOnResize(); // set and handle responsive    
589
 
590
            //UI Component handlers     
591
            handleMaterialDesign(); // handle material design       
592
            handleiCheck(); // handles custom icheck radio and checkboxes
593
            handleBootstrapSwitch(); // handle bootstrap switch plugin
594
            handleScrollers(); // handles slim scrolling contents 
595
            handleFancybox(); // handle fancy box
596
            handleSelect2(); // handle custom Select2 dropdowns
597
            handlePortletTools(); // handles portlet action bar functionality(refresh, configure, toggle, remove)
598
            handleAlerts(); //handle closabled alerts
599
            handleDropdowns(); // handle dropdowns
600
            handleTabs(); // handle tabs
601
            handleTooltips(); // handle bootstrap tooltips
602
            handlePopovers(); // handles bootstrap popovers
603
            handleAccordions(); //handles accordions 
604
            handleModals(); // handle modals
605
            handleBootstrapConfirmation(); // handle bootstrap confirmations
606
            handleTextareaAutosize(); // handle autosize textareas
607
            handleCounterup(); // handle counterup instances
608
 
609
            //Handle group element heights
610
            this.addResizeHandler(handleHeight); // handle auto calculating height on window resize
611
 
612
            // Hacks
613
            handleFixInputPlaceholderForIE(); //IE8 & IE9 input placeholder issue fix
614
        },
615
 
616
        //main function to initiate core javascript after ajax complete
617
        initAjax: function() {
618
            //handleUniform(); // handles custom radio & checkboxes     
619
            handleiCheck(); // handles custom icheck radio and checkboxes
620
            handleBootstrapSwitch(); // handle bootstrap switch plugin
621
            handleDropdownHover(); // handles dropdown hover       
622
            handleScrollers(); // handles slim scrolling contents 
623
            handleSelect2(); // handle custom Select2 dropdowns
624
            handleFancybox(); // handle fancy box
625
            handleDropdowns(); // handle dropdowns
626
            handleTooltips(); // handle bootstrap tooltips
627
            handlePopovers(); // handles bootstrap popovers
628
            handleAccordions(); //handles accordions 
629
            handleBootstrapConfirmation(); // handle bootstrap confirmations
630
        },
631
 
632
        //init main components 
633
        initComponents: function() {
634
            this.initAjax();
635
        },
636
 
637
        //public function to remember last opened popover that needs to be closed on click
638
        setLastPopedPopover: function(el) {
639
            lastPopedPopover = el;
640
        },
641
 
642
        //public function to add callback a function which will be called on window resize
643
        addResizeHandler: function(func) {
644
            resizeHandlers.push(func);
645
        },
646
 
647
        //public functon to call _runresizeHandlers
648
        runResizeHandlers: function() {
649
            _runResizeHandlers();
650
        },
651
 
652
        // wrApper function to scroll(focus) to an element
653
        scrollTo: function(el, offeset) {
654
            var pos = (el && el.size() > 0) ? el.offset().top : 0;
655
 
656
            if (el) {
657
                if ($('body').hasClass('page-header-fixed')) {
658
                    pos = pos - $('.page-header').height();
659
                } else if ($('body').hasClass('page-header-top-fixed')) {
660
                    pos = pos - $('.page-header-top').height();
661
                } else if ($('body').hasClass('page-header-menu-fixed')) {
662
                    pos = pos - $('.page-header-menu').height();
663
                }
664
                pos = pos + (offeset ? offeset : -1 * el.height());
665
            }
666
 
667
            $('html,body').animate({
668
                scrollTop: pos
669
            }, 'slow');
670
        },
671
 
672
        initSlimScroll: function(el) {
673
            if (!$().slimScroll) {
674
                return;
675
            }
676
 
677
            $(el).each(function() {
678
                if ($(this).attr("data-initialized")) {
679
                    return; // exit
680
                }
681
 
682
                var height;
683
 
684
                if ($(this).attr("data-height")) {
685
                    height = $(this).attr("data-height");
686
                } else {
687
                    height = $(this).css('height');
688
                }
689
 
690
                $(this).slimScroll({
691
                    allowPageScroll: true, // allow page scroll when the element scroll is ended
692
                    size: '7px',
693
                    color: ($(this).attr("data-handle-color") ? $(this).attr("data-handle-color") : '#bbb'),
694
                    wrapperClass: ($(this).attr("data-wrapper-class") ? $(this).attr("data-wrapper-class") : 'slimScrollDiv'),
695
                    railColor: ($(this).attr("data-rail-color") ? $(this).attr("data-rail-color") : '#eaeaea'),
696
                    position: isRTL ? 'left' : 'right',
697
                    height: height,
698
                    alwaysVisible: ($(this).attr("data-always-visible") == "1" ? true : false),
699
                    railVisible: ($(this).attr("data-rail-visible") == "1" ? true : false),
700
                    disableFadeOut: true
701
                });
702
 
703
                $(this).attr("data-initialized", "1");
704
            });
705
        },
706
 
707
        destroySlimScroll: function(el) {
708
            if (!$().slimScroll) {
709
                return;
710
            }
711
 
712
            $(el).each(function() {
713
                if ($(this).attr("data-initialized") === "1") { // destroy existing instance before updating the height
714
                    $(this).removeAttr("data-initialized");
715
                    $(this).removeAttr("style");
716
 
717
                    var attrList = {};
718
 
719
                    // store the custom attribures so later we will reassign.
720
                    if ($(this).attr("data-handle-color")) {
721
                        attrList["data-handle-color"] = $(this).attr("data-handle-color");
722
                    }
723
                    if ($(this).attr("data-wrapper-class")) {
724
                        attrList["data-wrapper-class"] = $(this).attr("data-wrapper-class");
725
                    }
726
                    if ($(this).attr("data-rail-color")) {
727
                        attrList["data-rail-color"] = $(this).attr("data-rail-color");
728
                    }
729
                    if ($(this).attr("data-always-visible")) {
730
                        attrList["data-always-visible"] = $(this).attr("data-always-visible");
731
                    }
732
                    if ($(this).attr("data-rail-visible")) {
733
                        attrList["data-rail-visible"] = $(this).attr("data-rail-visible");
734
                    }
735
 
736
                    $(this).slimScroll({
737
                        wrapperClass: ($(this).attr("data-wrapper-class") ? $(this).attr("data-wrapper-class") : 'slimScrollDiv'),
738
                        destroy: true
739
                    });
740
 
741
                    var the = $(this);
742
 
743
                    // reassign custom attributes
744
                    $.each(attrList, function(key, value) {
745
                        the.attr(key, value);
746
                    });
747
 
748
                }
749
            });
750
        },
751
 
752
        // function to scroll to the top
753
        scrollTop: function() {
754
            App.scrollTo();
755
        },
756
 
757
        // wrApper function to  block element(indicate loading)
758
        blockUI: function(options) {
759
            options = $.extend(true, {}, options);
760
            var html = '';
761
            if (options.animate) {
762
                html = '<div class="loading-message ' + (options.boxed ? 'loading-message-boxed' : '') + '">' + '<div class="block-spinner-bar"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>' + '</div>';
763
            } else if (options.iconOnly) {
764
                html = '<div class="loading-message ' + (options.boxed ? 'loading-message-boxed' : '') + '"><img src="' + this.getGlobalImgPath() + 'loading-spinner-grey.gif" align=""></div>';
765
            } else if (options.textOnly) {
766
                html = '<div class="loading-message ' + (options.boxed ? 'loading-message-boxed' : '') + '"><span>&nbsp;&nbsp;' + (options.message ? options.message : 'LOADING...') + '</span></div>';
767
            } else {
768
                html = '<div class="loading-message ' + (options.boxed ? 'loading-message-boxed' : '') + '"><img src="' + this.getGlobalImgPath() + 'loading-spinner-grey.gif" align=""><span>&nbsp;&nbsp;' + (options.message ? options.message : 'LOADING...') + '</span></div>';
769
            }
770
 
771
            if (options.target) { // element blocking
772
                var el = $(options.target);
773
                if (el.height() <= ($(window).height())) {
774
                    options.cenrerY = true;
775
                }
776
                el.block({
777
                    message: html,
778
                    baseZ: options.zIndex ? options.zIndex : 1000,
779
                    centerY: options.cenrerY !== undefined ? options.cenrerY : false,
780
                    css: {
781
                        top: '10%',
782
                        border: '0',
783
                        padding: '0',
784
                        backgroundColor: 'none'
785
                    },
786
                    overlayCSS: {
787
                        backgroundColor: options.overlayColor ? options.overlayColor : '#555',
788
                        opacity: options.boxed ? 0.05 : 0.1,
789
                        cursor: 'wait'
790
                    }
791
                });
792
            } else { // page blocking
793
                $.blockUI({
794
                    message: html,
795
                    baseZ: options.zIndex ? options.zIndex : 1000,
796
                    css: {
797
                        border: '0',
798
                        padding: '0',
799
                        backgroundColor: 'none'
800
                    },
801
                    overlayCSS: {
802
                        backgroundColor: options.overlayColor ? options.overlayColor : '#555',
803
                        opacity: options.boxed ? 0.05 : 0.1,
804
                        cursor: 'wait'
805
                    }
806
                });
807
            }
808
        },
809
 
810
        // wrApper function to  un-block element(finish loading)
811
        unblockUI: function(target) {
812
            if (target) {
813
                $(target).unblock({
814
                    onUnblock: function() {
815
                        $(target).css('position', '');
816
                        $(target).css('zoom', '');
817
                    }
818
                });
819
            } else {
820
                $.unblockUI();
821
            }
822
        },
823
 
824
        startPageLoading: function(options) {
825
            if (options && options.animate) {
826
                $('.page-spinner-bar').remove();
827
                $('body').append('<div class="page-spinner-bar"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>');
828
            } else {
829
                $('.page-loading').remove();
830
                $('body').append('<div class="page-loading"><img src="' + this.getGlobalImgPath() + 'loading-spinner-grey.gif"/>&nbsp;&nbsp;<span>' + (options && options.message ? options.message : 'Loading...') + '</span></div>');
831
            }
832
        },
833
 
834
        stopPageLoading: function() {
835
            $('.page-loading, .page-spinner-bar').remove();
836
        },
837
 
838
        alert: function(options) {
839
 
840
            options = $.extend(true, {
841
                container: "", // alerts parent container(by default placed after the page breadcrumbs)
842
                place: "append", // "append" or "prepend" in container 
843
                type: 'success', // alert's type
844
                message: "", // alert's message
845
                close: true, // make alert closable
846
                reset: true, // close all previouse alerts first
847
                focus: true, // auto scroll to the alert after shown
848
                closeInSeconds: 0, // auto close after defined seconds
849
                icon: "" // put icon before the message
850
            }, options);
851
 
852
            var id = App.getUniqueID("App_alert");
853
 
854
            var html = '<div id="' + id + '" class="custom-alerts alert alert-' + options.type + ' fade in">' + (options.close ? '<button type="button" class="close" data-dismiss="alert" aria-hidden="true"></button>' : '') + (options.icon !== "" ? '<i class="fa-lg fa fa-' + options.icon + '"></i>  ' : '') + options.message + '</div>';
855
 
856
            if (options.reset) {
857
                $('.custom-alerts').remove();
858
            }
859
 
860
            if (!options.container) {
861
                if ($('.page-fixed-main-content').size() === 1) {
862
                    $('.page-fixed-main-content').prepend(html);
863
                } else if (($('body').hasClass("page-container-bg-solid") || $('body').hasClass("page-content-white")) && $('.page-head').size() === 0) {
864
                    $('.page-title').after(html);
865
                } else {
866
                    if ($('.page-bar').size() > 0) {
867
                        $('.page-bar').after(html);
868
                    } else {
869
                        $('.page-breadcrumb, .breadcrumbs').after(html);
870
                    }
871
                }
872
            } else {
873
                if (options.place == "append") {
874
                    $(options.container).append(html);
875
                } else {
876
                    $(options.container).prepend(html);
877
                }
878
            }
879
 
880
            if (options.focus) {
881
                App.scrollTo($('#' + id));
882
            }
883
 
884
            if (options.closeInSeconds > 0) {
885
                setTimeout(function() {
886
                    $('#' + id).remove();
887
                }, options.closeInSeconds * 1000);
888
            }
889
 
890
            return id;
891
        },
892
 
893
        //public function to initialize the fancybox plugin
894
        initFancybox: function() {
895
            handleFancybox();
896
        },
897
 
898
        //public helper function to get actual input value(used in IE9 and IE8 due to placeholder attribute not supported)
899
        getActualVal: function(el) {
900
            el = $(el);
901
            if (el.val() === el.attr("placeholder")) {
902
                return "";
903
            }
904
            return el.val();
905
        },
906
 
907
        //public function to get a paremeter by name from URL
908
        getURLParameter: function(paramName) {
909
            var searchString = window.location.search.substring(1),
910
                i, val, params = searchString.split("&");
911
 
912
            for (i = 0; i < params.length; i++) {
913
                val = params[i].split("=");
914
                if (val[0] == paramName) {
915
                    return unescape(val[1]);
916
                }
917
            }
918
            return null;
919
        },
920
 
921
        // check for device touch support
922
        isTouchDevice: function() {
923
            try {
924
                document.createEvent("TouchEvent");
925
                return true;
926
            } catch (e) {
927
                return false;
928
            }
929
        },
930
 
931
        // To get the correct viewport width based on  http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
932
        getViewPort: function() {
933
            var e = window,
934
                a = 'inner';
935
            if (!('innerWidth' in window)) {
936
                a = 'client';
937
                e = document.documentElement || document.body;
938
            }
939
 
940
            return {
941
                width: e[a + 'Width'],
942
                height: e[a + 'Height']
943
            };
944
        },
945
 
946
        getUniqueID: function(prefix) {
947
            return 'prefix_' + Math.floor(Math.random() * (new Date()).getTime());
948
        },
949
 
950
        // check IE8 mode
951
        isIE8: function() {
952
            return isIE8;
953
        },
954
 
955
        // check IE9 mode
956
        isIE9: function() {
957
            return isIE9;
958
        },
959
 
960
        //check RTL mode
961
        isRTL: function() {
962
            return isRTL;
963
        },
964
 
965
        // check IE8 mode
966
        isAngularJsApp: function() {
967
            return (typeof angular == 'undefined') ? false : true;
968
        },
969
 
970
        getAssetsPath: function() {
971
            return assetsPath;
972
        },
973
 
974
        setAssetsPath: function(path) {
975
            assetsPath = path;
976
        },
977
 
978
        setGlobalImgPath: function(path) {
979
            globalImgPath = path;
980
        },
981
 
982
        getGlobalImgPath: function() {
983
            return assetsPath + globalImgPath;
984
        },
985
 
986
        setGlobalPluginsPath: function(path) {
987
            globalPluginsPath = path;
988
        },
989
 
990
        getGlobalPluginsPath: function() {
991
            return assetsPath + globalPluginsPath;
992
        },
993
 
994
        getGlobalCssPath: function() {
995
            return assetsPath + globalCssPath;
996
        },
997
 
998
        // get layout color code by color name
999
        getBrandColor: function(name) {
1000
            if (brandColors[name]) {
1001
                return brandColors[name];
1002
            } else {
1003
                return '';
1004
            }
1005
        },
1006
 
1007
        getResponsiveBreakpoint: function(size) {
1008
            // bootstrap responsive breakpoints
1009
            var sizes = {
1010
                'xs' : 480,     // extra small
1011
                'sm' : 768,     // small
1012
                'md' : 992,     // medium
1013
                'lg' : 1200     // large
1014
            };
1015
 
1016
            return sizes[size] ? sizes[size] : 0;
1017
        }
1018
    };
1019
 
1020
}();
1021
 
1022
<!-- END THEME LAYOUT SCRIPTS -->
1023
 
1024
jQuery(document).ready(function() {    
1025
   App.init(); // init metronic core componets
1026
});