3 * Main JS application file for AdminLTE v2. This file
4 * should be included in all pages. It controls some layout
5 * options and implements exclusive AdminLTE plugins.
7 * @Author Almsaeed Studio
8 * @Support <http://www.almsaeedstudio.com>
9 * @Email <abdullah@almsaeedstudio.com>
11 * @license MIT <http://opensource.org/licenses/MIT>
14 //Make sure jQuery has been loaded before app.js
15 if (typeof jQuery === "undefined") {
16 throw new Error("AdminLTE requires jQuery");
22 * @description $.AdminLTE is the main object for the template's app.
23 * It's used for implementing functions and options related
24 * to the template. Keeping everything wrapped in an object
25 * prevents conflict with other plugins and is a better
26 * way to organize our code.
30 /* --------------------
31 * - AdminLTE Options -
32 * --------------------
33 * Modify these options to suit your implementation
35 $.AdminLTE.options = {
36 //Add slimscroll to navbar menus
37 //This requires you to load the slimscroll plugin
38 //in every page before app.js
39 navbarMenuSlimscroll: true,
40 navbarMenuSlimscrollWidth: "3px", //The width of the scroll bar
41 navbarMenuHeight: "200px", //The height of the inner menu
42 //General animation speed for JS animated elements such as box collapse/expand and
43 //sidebar treeview slide up/down. This options accepts an integer as milliseconds,
44 //'fast', 'normal', or 'slow'
46 //Sidebar push menu toggle button selector
47 sidebarToggleSelector: "[data-toggle='offcanvas']",
48 //Activate sidebar push menu
49 sidebarPushMenu: true,
50 //Activate sidebar slimscroll if the fixed layout is set (requires SlimScroll Plugin)
51 sidebarSlimScroll: true,
52 //Enable sidebar expand on hover effect for sidebar mini
53 //This option is forced to true if both the fixed layout and sidebar mini
55 sidebarExpandOnHover: false,
57 enableBoxRefresh: true,
58 //Bootstrap.js tooltip
59 enableBSToppltip: true,
60 BSTooltipSelector: "[data-toggle='tooltip']",
61 //Enable Fast Click. Fastclick.js creates a more
62 //native touch experience with touch devices. If you
63 //choose to enable the plugin, make sure you load the script
64 //before AdminLTE's app.js
65 enableFastclick: false,
66 //Control Sidebar Options
67 enableControlSidebar: true,
68 controlSidebarOptions: {
69 //Which button should trigger the open/close event
70 toggleBtnSelector: "[data-toggle='control-sidebar']",
71 //The sidebar selector
72 selector: ".control-sidebar",
73 //Enable slide over content
76 //Box Widget Plugin. Enable this plugin
77 //to allow boxes to be collapsed and/or removed
78 enableBoxWidget: true,
79 //Box Widget plugin options
90 //Remove button selector
91 remove: '[data-widget="remove"]',
92 //Collapse button selector
93 collapse: '[data-widget="collapse"]'
96 //Direct Chat plugin options
98 //Enable direct chat by default
100 //The button to open and close the chat contacts pane
101 contactToggleSelector: '[data-widget="chat-pane-toggle"]'
103 //Define the set of colors to use globally around the website
105 lightBlue: "#3c8dbc",
122 //The standard screen sizes that bootstrap uses.
123 //If you change these in the variables.less file, change
133 /* ------------------
136 * The next block of code implements AdminLTE's
137 * functions and plugins as specified by the
143 //Fix for IE page transitions
144 $("body").removeClass("hold-transition");
146 //Extend options if external options exist
147 if (typeof AdminLTEOptions !== "undefined") {
153 //Easy access to options
154 var o = $.AdminLTE.options;
159 //Activate the layout maker
160 $.AdminLTE.layout.activate();
162 //Enable sidebar tree view controls
163 $.AdminLTE.tree('.sidebar');
165 //Enable control sidebar
166 if (o.enableControlSidebar) {
167 $.AdminLTE.controlSidebar.activate();
170 //Add slimscroll to navbar dropdown
171 if (o.navbarMenuSlimscroll && typeof $.fn.slimscroll != 'undefined') {
172 $(".navbar .menu").slimscroll({
173 height: o.navbarMenuHeight,
174 alwaysVisible: false,
175 size: o.navbarMenuSlimscrollWidth
176 }).css("width", "100%");
179 //Activate sidebar push menu
180 if (o.sidebarPushMenu) {
181 $.AdminLTE.pushMenu.activate(o.sidebarToggleSelector);
184 //Activate Bootstrap tooltip
185 if (o.enableBSToppltip) {
187 selector: o.BSTooltipSelector
191 //Activate box widget
192 if (o.enableBoxWidget) {
193 $.AdminLTE.boxWidget.activate();
196 //Activate fast click
197 if (o.enableFastclick && typeof FastClick != 'undefined') {
198 FastClick.attach(document.body);
201 //Activate direct chat widget
202 if (o.directChat.enable) {
203 $(document).on('click', o.directChat.contactToggleSelector, function () {
204 var box = $(this).parents('.direct-chat').first();
205 box.toggleClass('direct-chat-contacts-open');
210 * INITIALIZE BUTTON TOGGLE
211 * ------------------------
213 $('.btn-group[data-toggle="btn-toggle"]').each(function () {
215 $(this).find(".btn").on('click', function (e) {
216 group.find(".btn.active").removeClass("active");
217 $(this).addClass("active");
224 /* ----------------------------------
225 * - Initialize the AdminLTE Object -
226 * ----------------------------------
227 * All AdminLTE functions are implemented below.
233 * Fixes the layout height in case min-height fails.
236 * @usage $.AdminLTE.layout.activate()
237 * $.AdminLTE.layout.fix()
238 * $.AdminLTE.layout.fixSidebar()
240 $.AdminLTE.layout = {
241 activate: function () {
245 $(window, ".wrapper").resize(function () {
251 //Get window height and the wrapper height
252 var neg = $('.main-header').outerHeight() + $('.main-footer').outerHeight();
253 var window_height = $(window).height();
254 var sidebar_height = $(".sidebar").height();
255 //Set the min-height of the content and sidebar based on the
256 //the height of the document.
257 if ($("body").hasClass("fixed")) {
258 $(".content-wrapper, .right-side").css('min-height', window_height - $('.main-footer').outerHeight());
261 if (window_height >= sidebar_height) {
262 $(".content-wrapper, .right-side").css('min-height', window_height - neg);
263 postSetWidth = window_height - neg;
265 $(".content-wrapper, .right-side").css('min-height', sidebar_height);
266 postSetWidth = sidebar_height;
269 //Fix for the control sidebar height
270 var controlSidebar = $($.AdminLTE.options.controlSidebarOptions.selector);
271 if (typeof controlSidebar !== "undefined") {
272 if (controlSidebar.height() > postSetWidth)
273 $(".content-wrapper, .right-side").css('min-height', controlSidebar.height());
278 fixSidebar: function () {
279 //Make sure the body tag has the .fixed class
280 if (!$("body").hasClass("fixed")) {
281 if (typeof $.fn.slimScroll != 'undefined') {
282 $(".sidebar").slimScroll({destroy: true}).height("auto");
285 } else if (typeof $.fn.slimScroll == 'undefined' && window.console) {
286 window.console.error("Error: the fixed layout requires the slimscroll plugin!");
288 //Enable slimscroll for fixed layout
289 if ($.AdminLTE.options.sidebarSlimScroll) {
290 if (typeof $.fn.slimScroll != 'undefined') {
291 //Destroy if it exists
292 $(".sidebar").slimScroll({destroy: true}).height("auto");
294 $(".sidebar").slimscroll({
295 height: ($(window).height() - $(".main-header").height()) + "px",
296 color: "rgba(0,0,0,0.2)",
306 * Adds the push menu functionality to the sidebar.
309 * @usage: $.AdminLTE.pushMenu("[data-toggle='offcanvas']")
311 $.AdminLTE.pushMenu = {
312 activate: function (toggleBtn) {
313 //Get the screen sizes
314 var screenSizes = $.AdminLTE.options.screenSizes;
316 //Enable sidebar toggle
317 $(document).on('click', toggleBtn, function (e) {
320 //Enable sidebar push menu
321 if ($(window).width() > (screenSizes.sm - 1)) {
322 if ($("body").hasClass('sidebar-collapse')) {
323 $("body").removeClass('sidebar-collapse').trigger('expanded.pushMenu');
325 $("body").addClass('sidebar-collapse').trigger('collapsed.pushMenu');
328 //Handle sidebar push menu for small screens
330 if ($("body").hasClass('sidebar-open')) {
331 $("body").removeClass('sidebar-open').removeClass('sidebar-collapse').trigger('collapsed.pushMenu');
333 $("body").addClass('sidebar-open').trigger('expanded.pushMenu');
338 $(".content-wrapper").click(function () {
339 //Enable hide menu when clicking on the content-wrapper on small screens
340 if ($(window).width() <= (screenSizes.sm - 1) && $("body").hasClass("sidebar-open")) {
341 $("body").removeClass('sidebar-open');
345 //Enable expand on hover for sidebar mini
346 if ($.AdminLTE.options.sidebarExpandOnHover
347 || ($('body').hasClass('fixed')
348 && $('body').hasClass('sidebar-mini'))) {
349 this.expandOnHover();
352 expandOnHover: function () {
354 var screenWidth = $.AdminLTE.options.screenSizes.sm - 1;
355 //Expand sidebar on hover
356 $('.main-sidebar').hover(function () {
357 if ($('body').hasClass('sidebar-mini')
358 && $("body").hasClass('sidebar-collapse')
359 && $(window).width() > screenWidth) {
363 if ($('body').hasClass('sidebar-mini')
364 && $('body').hasClass('sidebar-expanded-on-hover')
365 && $(window).width() > screenWidth) {
370 expand: function () {
371 $("body").removeClass('sidebar-collapse').addClass('sidebar-expanded-on-hover');
373 collapse: function () {
374 if ($('body').hasClass('sidebar-expanded-on-hover')) {
375 $('body').removeClass('sidebar-expanded-on-hover').addClass('sidebar-collapse');
382 * Converts the sidebar into a multilevel
386 * @Usage: $.AdminLTE.tree('.sidebar')
388 $.AdminLTE.tree = function (menu) {
390 var animationSpeed = $.AdminLTE.options.animationSpeed;
391 $(document).off('click', menu + ' li a')
392 .on('click', menu + ' li a', function (e) {
393 //Get the clicked link and the next element
395 var checkElement = $this.next();
397 //Check if the next element is a menu and is visible
398 if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible')) && (!$('body').hasClass('sidebar-collapse'))) {
400 checkElement.slideUp(animationSpeed, function () {
401 checkElement.removeClass('menu-open');
402 //Fix the layout in case the sidebar stretches over the height of the window
403 //_this.layout.fix();
405 checkElement.parent("li").removeClass("active");
407 //If the menu is not visible
408 else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) {
409 //Get the parent menu
410 var parent = $this.parents('ul').first();
411 //Close all open menus within the parent
412 var ul = parent.find('ul:visible').slideUp(animationSpeed);
413 //Remove the menu-open class from the parent
414 ul.removeClass('menu-open');
416 var parent_li = $this.parent("li");
418 //Open the target menu and add the menu-open class
419 checkElement.slideDown(animationSpeed, function () {
420 //Add the class active to the parent li
421 checkElement.addClass('menu-open');
422 parent.find('li.active').removeClass('active');
423 parent_li.addClass('active');
424 //Fix the layout in case the sidebar stretches over the height of the window
428 //if this isn't a link, prevent the page from being redirected
429 if (checkElement.is('.treeview-menu')) {
437 * Adds functionality to the right sidebar
440 * @usage $.AdminLTE.controlSidebar.activate(options)
442 $.AdminLTE.controlSidebar = {
443 //instantiate the object
444 activate: function () {
448 var o = $.AdminLTE.options.controlSidebarOptions;
450 var sidebar = $(o.selector);
452 var btn = $(o.toggleBtnSelector);
454 //Listen to the click event
455 btn.on('click', function (e) {
457 //If the sidebar is not open
458 if (!sidebar.hasClass('control-sidebar-open')
459 && !$('body').hasClass('control-sidebar-open')) {
461 _this.open(sidebar, o.slide);
463 _this.close(sidebar, o.slide);
467 //If the body has a boxed layout, fix the sidebar bg position
468 var bg = $(".control-sidebar-bg");
471 //If the body has a fixed layout, make the control sidebar fixed
472 if ($('body').hasClass('fixed')) {
473 _this._fixForFixed(sidebar);
475 //If the content height is less than the sidebar's height, force max height
476 if ($('.content-wrapper, .right-side').height() < sidebar.height()) {
477 _this._fixForContent(sidebar);
481 //Open the control sidebar
482 open: function (sidebar, slide) {
485 sidebar.addClass('control-sidebar-open');
487 //Push the content by adding the open class to the body instead
488 //of the sidebar itself
489 $('body').addClass('control-sidebar-open');
492 //Close the control sidebar
493 close: function (sidebar, slide) {
495 sidebar.removeClass('control-sidebar-open');
497 $('body').removeClass('control-sidebar-open');
500 _fix: function (sidebar) {
502 if ($("body").hasClass('layout-boxed')) {
503 sidebar.css('position', 'absolute');
504 sidebar.height($(".wrapper").height());
505 if (_this.hasBindedResize) {
508 $(window).resize(function () {
511 _this.hasBindedResize = true;
519 _fixForFixed: function (sidebar) {
522 'max-height': '100%',
524 'padding-bottom': '50px'
527 _fixForContent: function (sidebar) {
528 $(".content-wrapper, .right-side").css('min-height', sidebar.height());
534 * BoxWidget is a plugin to handle collapsing and
535 * removing boxes from the screen.
538 * @usage $.AdminLTE.boxWidget.activate()
539 * Set all your options in the main $.AdminLTE.options object
541 $.AdminLTE.boxWidget = {
542 selectors: $.AdminLTE.options.boxWidgetOptions.boxWidgetSelectors,
543 icons: $.AdminLTE.options.boxWidgetOptions.boxWidgetIcons,
544 animationSpeed: $.AdminLTE.options.animationSpeed,
545 activate: function (_box) {
548 _box = document; // activate all boxes per default
550 //Listen for collapse event triggers
551 $(_box).on('click', _this.selectors.collapse, function (e) {
553 _this.collapse($(this));
556 //Listen for remove event triggers
557 $(_box).on('click', _this.selectors.remove, function (e) {
559 _this.remove($(this));
562 collapse: function (element) {
564 //Find the box parent
565 var box = element.parents(".box").first();
566 //Find the body and the footer
567 var box_content = box.find("> .box-body, > .box-footer, > form >.box-body, > form > .box-footer");
568 if (!box.hasClass("collapsed-box")) {
569 //Convert minus into plus
570 element.children(":first")
571 .removeClass(_this.icons.collapse)
572 .addClass(_this.icons.open);
574 box_content.slideUp(_this.animationSpeed, function () {
575 box.addClass("collapsed-box");
578 //Convert plus into minus
579 element.children(":first")
580 .removeClass(_this.icons.open)
581 .addClass(_this.icons.collapse);
583 box_content.slideDown(_this.animationSpeed, function () {
584 box.removeClass("collapsed-box");
588 remove: function (element) {
589 //Find the box parent
590 var box = element.parents(".box").first();
591 box.slideUp(this.animationSpeed);
596 /* ------------------
599 * All custom plugins are defined below.
605 * This is a custom plugin to use with the component BOX. It allows you to add
606 * a refresh button to the box. It converts the box's state to a loading state.
609 * @usage $("#box-widget").boxRefresh( options );
615 $.fn.boxRefresh = function (options) {
618 var settings = $.extend({
619 //Refresh button selector
620 trigger: ".refresh-btn",
621 //File source to be loaded (e.g: ajax/src.php)
624 onLoadStart: function (box) {
626 }, //Right after the button has been clicked
627 onLoadDone: function (box) {
629 } //When the source has been loaded
634 var overlay = $('<div class="overlay"><div class="fa fa-refresh fa-spin"></div></div>');
636 return this.each(function () {
637 //if a source is specified
638 if (settings.source === "") {
639 if (window.console) {
640 window.console.log("Please specify a source first - boxRefresh()");
647 var rBtn = box.find(settings.trigger).first();
650 rBtn.on('click', function (e) {
652 //Add loading overlay
656 box.find(".box-body").load(settings.source, function () {
662 function start(box) {
663 //Add overlay and loading img
666 settings.onLoadStart.call(box);
670 //Remove overlay and loading img
671 box.find(overlay).remove();
673 settings.onLoadDone.call(box);
681 * EXPLICIT BOX CONTROLS
682 * -----------------------
683 * This is a custom plugin to use with the component BOX. It allows you to activate
684 * a box inserted in the DOM after the app.js was loaded, toggle and remove box.
687 * @usage $("#box-widget").activateBox();
688 * @usage $("#box-widget").toggleBox();
689 * @usage $("#box-widget").removeBox();
695 $.fn.activateBox = function () {
696 $.AdminLTE.boxWidget.activate(this);
699 $.fn.toggleBox = function () {
700 var button = $($.AdminLTE.boxWidget.selectors.collapse, this);
701 $.AdminLTE.boxWidget.collapse(button);
704 $.fn.removeBox = function () {
705 var button = $($.AdminLTE.boxWidget.selectors.remove, this);
706 $.AdminLTE.boxWidget.remove(button);
712 * TODO LIST CUSTOM PLUGIN
713 * -----------------------
714 * This plugin depends on iCheck plugin for checkbox and radio inputs
717 * @usage $("#todo-widget").todolist( options );
723 $.fn.todolist = function (options) {
725 var settings = $.extend({
726 //When the user checks the input
727 onCheck: function (ele) {
730 //When the user unchecks the input
731 onUncheck: function (ele) {
736 return this.each(function () {
738 if (typeof $.fn.iCheck != 'undefined') {
739 $('input', this).on('ifChecked', function () {
740 var ele = $(this).parents("li").first();
741 ele.toggleClass("done");
742 settings.onCheck.call(ele);
745 $('input', this).on('ifUnchecked', function () {
746 var ele = $(this).parents("li").first();
747 ele.toggleClass("done");
748 settings.onUncheck.call(ele);
751 $('input', this).on('change', function () {
752 var ele = $(this).parents("li").first();
753 ele.toggleClass("done");
754 if ($('input', ele).is(":checked")) {
755 settings.onCheck.call(ele);
757 settings.onUncheck.call(ele);