github.com/apremalal/vamps-core@v1.0.1-0.20161221121535-d430b56ec174/server/webapps/app/base/js/metronic.js (about)

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