adminlte.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. /*! AdminLTE app.js
  2. * ================
  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.
  6. *
  7. * @Author Almsaeed Studio
  8. * @Support <http://www.almsaeedstudio.com>
  9. * @Email <abdullah@almsaeedstudio.com>
  10. * @version 2.3.8
  11. * @license MIT <http://opensource.org/licenses/MIT>
  12. */
  13. //Make sure jQuery has been loaded before app.js
  14. if (typeof jQuery === "undefined") {
  15. throw new Error("AdminLTE requires jQuery");
  16. }
  17. /* AdminLTE
  18. *
  19. * @type Object
  20. * @description $.AdminLTE is the main object for the template's app.
  21. * It's used for implementing functions and options related
  22. * to the template. Keeping everything wrapped in an object
  23. * prevents conflict with other plugins and is a better
  24. * way to organize our code.
  25. */
  26. $.AdminLTE = {};
  27. /* --------------------
  28. * - AdminLTE Options -
  29. * --------------------
  30. * Modify these options to suit your implementation
  31. */
  32. $.AdminLTE.options = {
  33. //Add slimscroll to navbar menus
  34. //This requires you to load the slimscroll plugin
  35. //in every page before app.js
  36. navbarMenuSlimscroll: true,
  37. navbarMenuSlimscrollWidth: "3px", //The width of the scroll bar
  38. navbarMenuHeight: "200px", //The height of the inner menu
  39. //General animation speed for JS animated elements such as box collapse/expand and
  40. //sidebar treeview slide up/down. This options accepts an integer as milliseconds,
  41. //'fast', 'normal', or 'slow'
  42. animationSpeed: 300,
  43. //Sidebar push menu toggle button selector
  44. sidebarToggleSelector: "[data-toggle='offcanvas']",
  45. //Activate sidebar push menu
  46. sidebarPushMenu: true,
  47. //Activate sidebar slimscroll if the fixed layout is set (requires SlimScroll Plugin)
  48. sidebarSlimScroll: true,
  49. //Enable sidebar expand on hover effect for sidebar mini
  50. //This option is forced to true if both the fixed layout and sidebar mini
  51. //are used together
  52. sidebarExpandOnHover: false,
  53. //BoxRefresh Plugin
  54. enableBoxRefresh: true,
  55. //Bootstrap.js tooltip
  56. enableBSToppltip: true,
  57. BSTooltipSelector: "[data-toggle='tooltip']",
  58. //Enable Fast Click. Fastclick.js creates a more
  59. //native touch experience with touch devices. If you
  60. //choose to enable the plugin, make sure you load the script
  61. //before AdminLTE's app.js
  62. enableFastclick: false,
  63. //Control Sidebar Tree views
  64. enableControlTreeView: true,
  65. //Control Sidebar Options
  66. enableControlSidebar: true,
  67. controlSidebarOptions: {
  68. //Which button should trigger the open/close event
  69. toggleBtnSelector: "[data-toggle='control-sidebar']",
  70. //The sidebar selector
  71. selector: ".control-sidebar",
  72. //Enable slide over content
  73. slide: true
  74. },
  75. //Box Widget Plugin. Enable this plugin
  76. //to allow boxes to be collapsed and/or removed
  77. enableBoxWidget: true,
  78. //Box Widget plugin options
  79. boxWidgetOptions: {
  80. boxWidgetIcons: {
  81. //Collapse icon
  82. collapse: 'fa-minus',
  83. //Open icon
  84. open: 'fa-plus',
  85. //Remove icon
  86. remove: 'fa-times'
  87. },
  88. boxWidgetSelectors: {
  89. //Remove button selector
  90. remove: '[data-widget="remove"]',
  91. //Collapse button selector
  92. collapse: '[data-widget="collapse"]'
  93. }
  94. },
  95. //Direct Chat plugin options
  96. directChat: {
  97. //Enable direct chat by default
  98. enable: true,
  99. //The button to open and close the chat contacts pane
  100. contactToggleSelector: '[data-widget="chat-pane-toggle"]'
  101. },
  102. //Define the set of colors to use globally around the website
  103. colors: {
  104. lightBlue: "#3c8dbc",
  105. red: "#f56954",
  106. green: "#00a65a",
  107. aqua: "#00c0ef",
  108. yellow: "#f39c12",
  109. blue: "#0073b7",
  110. navy: "#001F3F",
  111. teal: "#39CCCC",
  112. olive: "#3D9970",
  113. lime: "#01FF70",
  114. orange: "#FF851B",
  115. fuchsia: "#F012BE",
  116. purple: "#8E24AA",
  117. maroon: "#D81B60",
  118. black: "#222222",
  119. gray: "#d2d6de"
  120. },
  121. //The standard screen sizes that bootstrap uses.
  122. //If you change these in the variables.less file, change
  123. //them here too.
  124. screenSizes: {
  125. xs: 480,
  126. sm: 768,
  127. md: 992,
  128. lg: 1200
  129. }
  130. };
  131. /* ------------------
  132. * - Implementation -
  133. * ------------------
  134. * The next block of code implements AdminLTE's
  135. * functions and plugins as specified by the
  136. * options above.
  137. */
  138. $(function () {
  139. "use strict";
  140. //Fix for IE page transitions
  141. $("body").removeClass("hold-transition");
  142. //Extend options if external options exist
  143. if (typeof AdminLTEOptions !== "undefined") {
  144. $.extend(true,
  145. $.AdminLTE.options,
  146. AdminLTEOptions);
  147. }
  148. if ('ontouchstart' in document.documentElement) {
  149. $.AdminLTE.options.sidebarSlimScroll = false;
  150. $(".main-sidebar").css({height: ($(window).height() - $(".main-header").height()) + "px", overflow: "scroll"});
  151. }
  152. //Easy access to options
  153. var o = $.AdminLTE.options;
  154. //Set up the object
  155. _init();
  156. //Activate the layout maker
  157. $.AdminLTE.layout.activate();
  158. //Enable sidebar tree view controls
  159. if (o.enableControlTreeView) {
  160. $.AdminLTE.tree('.sidebar');
  161. }
  162. //Enable control sidebar
  163. if (o.enableControlSidebar) {
  164. $.AdminLTE.controlSidebar.activate();
  165. }
  166. //Add slimscroll to navbar dropdown
  167. if (o.navbarMenuSlimscroll && typeof $.fn.slimscroll != 'undefined') {
  168. $(".navbar .menu").slimscroll({
  169. height: o.navbarMenuHeight,
  170. alwaysVisible: false,
  171. size: o.navbarMenuSlimscrollWidth
  172. }).css("width", "100%");
  173. }
  174. //Activate sidebar push menu
  175. if (o.sidebarPushMenu) {
  176. $.AdminLTE.pushMenu.activate(o.sidebarToggleSelector);
  177. }
  178. //Activate Bootstrap tooltip
  179. if (o.enableBSToppltip) {
  180. $('body').tooltip({
  181. selector: o.BSTooltipSelector,
  182. container: 'body'
  183. });
  184. }
  185. //Activate box widget
  186. if (o.enableBoxWidget) {
  187. $.AdminLTE.boxWidget.activate();
  188. }
  189. //Activate fast click
  190. if (o.enableFastclick && typeof FastClick != 'undefined') {
  191. FastClick.attach(document.body);
  192. }
  193. //Activate direct chat widget
  194. if (o.directChat.enable) {
  195. $(document).on('click', o.directChat.contactToggleSelector, function () {
  196. var box = $(this).parents('.direct-chat').first();
  197. box.toggleClass('direct-chat-contacts-open');
  198. });
  199. }
  200. /*
  201. * INITIALIZE BUTTON TOGGLE
  202. * ------------------------
  203. */
  204. $('.btn-group[data-toggle="btn-toggle"]').each(function () {
  205. var group = $(this);
  206. $(this).find(".btn").on('click', function (e) {
  207. group.find(".btn.active").removeClass("active");
  208. $(this).addClass("active");
  209. e.preventDefault();
  210. });
  211. });
  212. });
  213. /* ----------------------------------
  214. * - Initialize the AdminLTE Object -
  215. * ----------------------------------
  216. * All AdminLTE functions are implemented below.
  217. */
  218. function _init() {
  219. 'use strict';
  220. /* Layout
  221. * ======
  222. * Fixes the layout height in case min-height fails.
  223. *
  224. * @type Object
  225. * @usage $.AdminLTE.layout.activate()
  226. * $.AdminLTE.layout.fix()
  227. * $.AdminLTE.layout.fixSidebar()
  228. */
  229. $.AdminLTE.layout = {
  230. activate: function () {
  231. var _this = this;
  232. //_this.fix();
  233. _this.fixSidebar();
  234. //$('body, html, .wrapper').css('height', 'auto');
  235. $(window, ".wrapper").resize(function () {
  236. //_this.fix();
  237. _this.fixSidebar();
  238. });
  239. },
  240. fix: function () {
  241. // Remove overflow from .wrapper if layout-boxed exists
  242. $(".layout-boxed > .wrapper").css('overflow', 'hidden');
  243. //Get window height and the wrapper height
  244. var footer_height = $('.main-footer').outerHeight() || 0;
  245. var neg = $('.main-header').outerHeight() + footer_height;
  246. var window_height = $(window).height();
  247. var sidebar_height = $(".sidebar").height() || 0;
  248. //Set the min-height of the content and sidebar based on the
  249. //the height of the document.
  250. if ($("body").hasClass("fixed")) {
  251. $(".content-wrapper, .right-side").css('min-height', window_height - footer_height);
  252. } else {
  253. var postSetWidth;
  254. if (window_height >= sidebar_height) {
  255. $(".content-wrapper, .right-side").css('min-height', window_height - neg);
  256. postSetWidth = window_height - neg;
  257. } else {
  258. $(".content-wrapper, .right-side").css('min-height', sidebar_height);
  259. postSetWidth = sidebar_height;
  260. }
  261. //Fix for the control sidebar height
  262. var controlSidebar = $($.AdminLTE.options.controlSidebarOptions.selector);
  263. if (typeof controlSidebar !== "undefined") {
  264. if (controlSidebar.height() > postSetWidth)
  265. $(".content-wrapper, .right-side").css('min-height', controlSidebar.height());
  266. }
  267. }
  268. },
  269. fixSidebar: function () {
  270. //Make sure the body tag has the .fixed class
  271. if (!$("body").hasClass("fixed")) {
  272. if (typeof $.fn.slimScroll != 'undefined') {
  273. $(".sidebar").slimScroll({destroy: true}).height("auto");
  274. }
  275. return;
  276. } else if (typeof $.fn.slimScroll == 'undefined' && window.console) {
  277. window.console.error("Error: the fixed layout requires the slimscroll plugin!");
  278. }
  279. //Enable slimscroll for fixed layout
  280. if ($.AdminLTE.options.sidebarSlimScroll) {
  281. if (typeof $.fn.slimScroll != 'undefined') {
  282. //Destroy if it exists
  283. $(".sidebar").slimScroll({destroy: true}).height("auto").css("overflow", "inherit");
  284. if (!$("body").hasClass('sidebar-collapse')) {
  285. $(".sidebar").off("mousewheel").css("margin-top", 0);
  286. $('.sidebar .treeview-menu').off('mousewheel').removeAttr("style");
  287. //Add slimscroll
  288. $(".sidebar").slimscroll({
  289. height: ($(window).height() - $(".main-header").height()) + "px",
  290. color: "rgba(0,0,0,0.2)",
  291. size: "8px"
  292. });
  293. $(".sidebar").trigger("mouseover");
  294. } else {
  295. var sidebarHeight = $(".sidebar").height();
  296. var maxHeight = $(window).height() - $(".main-header").height();
  297. var overflowHeight = sidebarHeight + $(".main-header").height() - $(window).height();
  298. if (overflowHeight > 0) {
  299. $(".sidebar").height(maxHeight);
  300. $(".sidebar").on("mousewheel", function (e) {
  301. e.preventDefault();
  302. if (e.originalEvent.pageX < $(".sidebar").width()) {
  303. var marginTop = parseInt($(".sidebar").css("margin-top").replace("px", "")) + e.originalEvent.wheelDelta;
  304. if (marginTop < 0 && Math.abs(marginTop) > overflowHeight) {
  305. marginTop = Math.min(overflowHeight, marginTop);
  306. marginTop = -overflowHeight;
  307. }
  308. marginTop = Math.min(0, marginTop);
  309. $(".sidebar").css("margin-top", marginTop);
  310. }
  311. });
  312. $('.sidebar .treeview-menu').on('mousewheel', function (e) {
  313. e.stopPropagation();
  314. });
  315. }
  316. }
  317. }
  318. }
  319. }
  320. };
  321. /* PushMenu()
  322. * ==========
  323. * Adds the push menu functionality to the sidebar.
  324. *
  325. * @type Function
  326. * @usage: $.AdminLTE.pushMenu("[data-toggle='offcanvas']")
  327. */
  328. $.AdminLTE.pushMenu = {
  329. activate: function (toggleBtn) {
  330. //Get the screen sizes
  331. var screenSizes = $.AdminLTE.options.screenSizes;
  332. //Enable sidebar toggle
  333. $(document).on('click', toggleBtn, function (e) {
  334. e.preventDefault();
  335. //Enable sidebar push menu
  336. if ($(window).width() > (screenSizes.sm - 1)) {
  337. if ($("body").hasClass('sidebar-collapse')) {
  338. $("body").removeClass('sidebar-collapse').trigger('expanded.pushMenu');
  339. } else {
  340. $("body").addClass('sidebar-collapse').trigger('collapsed.pushMenu');
  341. }
  342. }
  343. //Handle sidebar push menu for small screens
  344. else {
  345. if ($("body").hasClass('sidebar-open')) {
  346. $("body").removeClass('sidebar-open').removeClass('sidebar-collapse').trigger('collapsed.pushMenu');
  347. } else {
  348. $("body").addClass('sidebar-open').trigger('expanded.pushMenu');
  349. }
  350. }
  351. $.AdminLTE.layout.fixSidebar();
  352. });
  353. $(".content-wrapper").click(function () {
  354. //Enable hide menu when clicking on the content-wrapper on small screens
  355. if ($(window).width() <= (screenSizes.sm - 1) && $("body").hasClass("sidebar-open")) {
  356. $("body").removeClass('sidebar-open');
  357. }
  358. });
  359. //Enable expand on hover for sidebar mini
  360. if ($.AdminLTE.options.sidebarExpandOnHover) {
  361. this.expandOnHover();
  362. }
  363. },
  364. expandOnHover: function () {
  365. var _this = this;
  366. var screenWidth = $.AdminLTE.options.screenSizes.sm - 1;
  367. //Expand sidebar on hover
  368. $('.main-sidebar').hover(function () {
  369. if ($.AdminLTE.options.sidebarExpandOnHover) {
  370. if ($('body').hasClass('sidebar-mini')
  371. && $("body").hasClass('sidebar-collapse')
  372. && $(window).width() > screenWidth) {
  373. _this.expand();
  374. }
  375. }
  376. }, function () {
  377. if ($('body').hasClass('sidebar-mini')
  378. && $('body').hasClass('sidebar-expanded-on-hover')
  379. && $(window).width() > screenWidth) {
  380. _this.collapse();
  381. }
  382. });
  383. },
  384. expand: function () {
  385. $("body").removeClass('sidebar-collapse').addClass('sidebar-expanded-on-hover');
  386. $.AdminLTE.layout.fixSidebar();
  387. },
  388. collapse: function () {
  389. if ($('body').hasClass('sidebar-expanded-on-hover')) {
  390. $('body').removeClass('sidebar-expanded-on-hover').addClass('sidebar-collapse');
  391. // $.AdminLTE.layout.fixSidebar();
  392. }
  393. }
  394. };
  395. /* Tree()
  396. * ======
  397. * Converts the sidebar into a multilevel
  398. * tree view menu.
  399. *
  400. * @type Function
  401. * @Usage: $.AdminLTE.tree('.sidebar')
  402. */
  403. $.AdminLTE.tree = function (menu) {
  404. var _this = this;
  405. var animationSpeed = $.AdminLTE.options.animationSpeed;
  406. $(document).off('mouseenter', menu + ' .sidebar-menu > li')
  407. .on('mouseenter', menu + ' .sidebar-menu > li', function () {
  408. var treemenu = $(this).find("> .treeview-menu");
  409. if (treemenu.length > 0) {
  410. if ($("body").hasClass("sidebar-collapse")) {
  411. var liHeight = $(this).height();
  412. var headerHeight = $(".main-header").height();
  413. var maxBottomHeight = $(window).height() - ($(this).offset().top + headerHeight);
  414. var maxTopHeight = $(window).height() - maxBottomHeight - liHeight;
  415. var maxHeight = maxBottomHeight;
  416. if (maxBottomHeight < 300 || maxTopHeight > maxBottomHeight) {
  417. treemenu.css("top", "unset").css("bottom", liHeight);
  418. maxHeight = maxTopHeight;
  419. }
  420. treemenu.css("max-height", maxHeight).css("overflow-y", "auto");
  421. } else {
  422. treemenu.css("max-height", "inherit").css("overflow-y", "unset");
  423. }
  424. }
  425. });
  426. $(document).off('click', menu + ' li a')
  427. .on('click', menu + ' li a', function (e) {
  428. //Get the clicked link and the next element
  429. var $this = $(this);
  430. var checkElement = $this.next();
  431. //Check if the next element is a menu and is visible
  432. if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible'))) {
  433. if ($("body").hasClass("sidebar-collapse") && $this.parent().parent().hasClass("sidebar-menu")) {
  434. return false;
  435. }
  436. //Close the menu
  437. checkElement.slideUp(animationSpeed, function () {
  438. checkElement.removeClass('menu-open');
  439. //Fix the layout in case the sidebar stretches over the height of the window
  440. //_this.layout.fix();
  441. });
  442. checkElement.parent("li").removeClass("active");
  443. checkElement.parent("li").removeClass('treeview-open');
  444. }
  445. //If the menu is not visible
  446. else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) {
  447. //Get the parent menu
  448. var parent = $this.parents('ul').first();
  449. // modified by FastAdmin
  450. if ($(".show-submenu", menu).length == 0) {
  451. //Close all open menus within the parent
  452. var ul = parent.find('ul:visible').slideUp(animationSpeed);
  453. //Remove the menu-open class from the parent
  454. ul.removeClass('menu-open');
  455. parent.find('li.treeview').removeClass("treeview-open");
  456. }
  457. //Get the parent li
  458. var parent_li = $this.parent("li");
  459. //Open the target menu and add the menu-open class
  460. checkElement.slideDown(animationSpeed, function () {
  461. //Add the class active to the parent li
  462. checkElement.addClass('menu-open');
  463. //parent.find('li.active').removeClass('active');
  464. //parent_li.addClass('active');
  465. //Fix the layout in case the sidebar stretches over the height of the window
  466. // _this.layout.fix();
  467. });
  468. parent_li.addClass('treeview-open');
  469. } else {
  470. if (!$this.parent().hasClass("active")) {
  471. // $this.parent().addClass("active");
  472. }
  473. // modified by FastAdmin
  474. if ($(".show-submenu", menu).length == 0 && $this.parent().parent().hasClass("sidebar-menu")) {
  475. $this.parent().siblings().find("ul.menu-open").slideUp();
  476. $this.parent().siblings("li.treeview-open").removeClass("treeview-open");
  477. }
  478. }
  479. //if this isn't a link, prevent the page from being redirected
  480. if (checkElement.is('.treeview-menu')) {
  481. e.preventDefault();
  482. }
  483. });
  484. };
  485. /* ControlSidebar
  486. * ==============
  487. * Adds functionality to the right sidebar
  488. *
  489. * @type Object
  490. * @usage $.AdminLTE.controlSidebar.activate(options)
  491. */
  492. $.AdminLTE.controlSidebar = {
  493. //instantiate the object
  494. activate: function () {
  495. //Get the object
  496. var _this = this;
  497. //Update options
  498. var o = $.AdminLTE.options.controlSidebarOptions;
  499. //Get the sidebar
  500. var sidebar = $(o.selector);
  501. //The toggle button
  502. var btn = $(o.toggleBtnSelector);
  503. //Listen to the click event
  504. btn.on('click', function (e) {
  505. e.preventDefault();
  506. //If the sidebar is not open
  507. if (!sidebar.hasClass('control-sidebar-open')
  508. && !$('body').hasClass('control-sidebar-open')) {
  509. //Open the sidebar
  510. _this.open(sidebar, o.slide);
  511. } else {
  512. _this.close(sidebar, o.slide);
  513. }
  514. });
  515. //If the body has a boxed layout, fix the sidebar bg position
  516. var bg = $(".control-sidebar-bg");
  517. _this._fix(bg);
  518. //If the body has a fixed layout, make the control sidebar fixed
  519. if ($('body').hasClass('fixed')) {
  520. _this._fixForFixed(sidebar);
  521. } else {
  522. //If the content height is less than the sidebar's height, force max height
  523. if ($('.content-wrapper, .right-side').height() < sidebar.height()) {
  524. _this._fixForContent(sidebar);
  525. }
  526. }
  527. },
  528. //Open the control sidebar
  529. open: function (sidebar, slide) {
  530. //Slide over content
  531. if (slide) {
  532. sidebar.addClass('control-sidebar-open');
  533. } else {
  534. //Push the content by adding the open class to the body instead
  535. //of the sidebar itself
  536. $('body').addClass('control-sidebar-open');
  537. }
  538. },
  539. //Close the control sidebar
  540. close: function (sidebar, slide) {
  541. if (slide) {
  542. sidebar.removeClass('control-sidebar-open');
  543. } else {
  544. $('body').removeClass('control-sidebar-open');
  545. }
  546. },
  547. _fix: function (sidebar) {
  548. var _this = this;
  549. if ($("body").hasClass('layout-boxed')) {
  550. sidebar.css('position', 'absolute');
  551. sidebar.height($(".wrapper").height());
  552. if (_this.hasBindedResize) {
  553. return;
  554. }
  555. $(window).resize(function () {
  556. _this._fix(sidebar);
  557. });
  558. _this.hasBindedResize = true;
  559. } else {
  560. sidebar.css({
  561. 'position': 'fixed',
  562. 'height': 'auto'
  563. });
  564. }
  565. },
  566. _fixForFixed: function (sidebar) {
  567. sidebar.css({
  568. 'position': 'fixed',
  569. 'max-height': '100%',
  570. 'overflow': 'auto',
  571. });
  572. },
  573. _fixForContent: function (sidebar) {
  574. $(".content-wrapper, .right-side").css('min-height', sidebar.height());
  575. }
  576. };
  577. /* BoxWidget
  578. * =========
  579. * BoxWidget is a plugin to handle collapsing and
  580. * removing boxes from the screen.
  581. *
  582. * @type Object
  583. * @usage $.AdminLTE.boxWidget.activate()
  584. * Set all your options in the main $.AdminLTE.options object
  585. */
  586. $.AdminLTE.boxWidget = {
  587. selectors: $.AdminLTE.options.boxWidgetOptions.boxWidgetSelectors,
  588. icons: $.AdminLTE.options.boxWidgetOptions.boxWidgetIcons,
  589. animationSpeed: $.AdminLTE.options.animationSpeed,
  590. activate: function (_box) {
  591. var _this = this;
  592. if (!_box) {
  593. _box = document; // activate all boxes per default
  594. }
  595. //Listen for collapse event triggers
  596. $(_box).on('click', _this.selectors.collapse, function (e) {
  597. e.preventDefault();
  598. _this.collapse($(this));
  599. });
  600. //Listen for remove event triggers
  601. $(_box).on('click', _this.selectors.remove, function (e) {
  602. e.preventDefault();
  603. _this.remove($(this));
  604. });
  605. },
  606. collapse: function (element) {
  607. var _this = this;
  608. //Find the box parent
  609. var box = element.parents(".box").first();
  610. //Find the body and the footer
  611. var box_content = box.find("> .box-body, > .box-footer, > form >.box-body, > form > .box-footer");
  612. if (!box.hasClass("collapsed-box")) {
  613. //Convert minus into plus
  614. element.children(":first")
  615. .removeClass(_this.icons.collapse)
  616. .addClass(_this.icons.open);
  617. //Hide the content
  618. box_content.slideUp(_this.animationSpeed, function () {
  619. box.addClass("collapsed-box");
  620. });
  621. } else {
  622. //Convert plus into minus
  623. element.children(":first")
  624. .removeClass(_this.icons.open)
  625. .addClass(_this.icons.collapse);
  626. //Show the content
  627. box_content.slideDown(_this.animationSpeed, function () {
  628. box.removeClass("collapsed-box");
  629. });
  630. }
  631. },
  632. remove: function (element) {
  633. //Find the box parent
  634. var box = element.parents(".box").first();
  635. box.slideUp(this.animationSpeed);
  636. }
  637. };
  638. }
  639. /* ------------------
  640. * - Custom Plugins -
  641. * ------------------
  642. * All custom plugins are defined below.
  643. */
  644. /*
  645. * BOX REFRESH BUTTON
  646. * ------------------
  647. * This is a custom plugin to use with the component BOX. It allows you to add
  648. * a refresh button to the box. It converts the box's state to a loading state.
  649. *
  650. * @type plugin
  651. * @usage $("#box-widget").boxRefresh( options );
  652. */
  653. (function ($) {
  654. "use strict";
  655. $.fn.boxRefresh = function (options) {
  656. // Render options
  657. var settings = $.extend({
  658. //Refresh button selector
  659. trigger: ".refresh-btn",
  660. //File source to be loaded (e.g: ajax/src.php)
  661. source: "",
  662. //Callbacks
  663. onLoadStart: function (box) {
  664. return box;
  665. }, //Right after the button has been clicked
  666. onLoadDone: function (box) {
  667. return box;
  668. } //When the source has been loaded
  669. }, options);
  670. //The overlay
  671. var overlay = $('<div class="overlay"><div class="fa fa-refresh fa-spin"></div></div>');
  672. return this.each(function () {
  673. //if a source is specified
  674. if (settings.source === "") {
  675. if (window.console) {
  676. window.console.log("Please specify a source first - boxRefresh()");
  677. }
  678. return;
  679. }
  680. //the box
  681. var box = $(this);
  682. //the button
  683. var rBtn = box.find(settings.trigger).first();
  684. //On trigger click
  685. rBtn.on('click', function (e) {
  686. e.preventDefault();
  687. //Add loading overlay
  688. start(box);
  689. //Perform ajax call
  690. box.find(".box-body").load(settings.source, function () {
  691. done(box);
  692. });
  693. });
  694. });
  695. function start(box) {
  696. //Add overlay and loading img
  697. box.append(overlay);
  698. settings.onLoadStart.call(box);
  699. }
  700. function done(box) {
  701. //Remove overlay and loading img
  702. box.find(overlay).remove();
  703. settings.onLoadDone.call(box);
  704. }
  705. };
  706. })(jQuery);
  707. /*
  708. * EXPLICIT BOX CONTROLS
  709. * -----------------------
  710. * This is a custom plugin to use with the component BOX. It allows you to activate
  711. * a box inserted in the DOM after the app.js was loaded, toggle and remove box.
  712. *
  713. * @type plugin
  714. * @usage $("#box-widget").activateBox();
  715. * @usage $("#box-widget").toggleBox();
  716. * @usage $("#box-widget").removeBox();
  717. */
  718. (function ($) {
  719. 'use strict';
  720. $.fn.activateBox = function () {
  721. $.AdminLTE.boxWidget.activate(this);
  722. };
  723. $.fn.toggleBox = function () {
  724. var button = $($.AdminLTE.boxWidget.selectors.collapse, this);
  725. $.AdminLTE.boxWidget.collapse(button);
  726. };
  727. $.fn.removeBox = function () {
  728. var button = $($.AdminLTE.boxWidget.selectors.remove, this);
  729. $.AdminLTE.boxWidget.remove(button);
  730. };
  731. })(jQuery);
  732. /*
  733. * TODO LIST CUSTOM PLUGIN
  734. * -----------------------
  735. * This plugin depends on iCheck plugin for checkbox and radio inputs
  736. *
  737. * @type plugin
  738. * @usage $("#todo-widget").todolist( options );
  739. */
  740. (function ($) {
  741. 'use strict';
  742. $.fn.todolist = function (options) {
  743. // Render options
  744. var settings = $.extend({
  745. //When the user checks the input
  746. onCheck: function (ele) {
  747. return ele;
  748. },
  749. //When the user unchecks the input
  750. onUncheck: function (ele) {
  751. return ele;
  752. }
  753. }, options);
  754. return this.each(function () {
  755. if (typeof $.fn.iCheck != 'undefined') {
  756. $('input', this).on('ifChecked', function () {
  757. var ele = $(this).parents("li").first();
  758. ele.toggleClass("done");
  759. settings.onCheck.call(ele);
  760. });
  761. $('input', this).on('ifUnchecked', function () {
  762. var ele = $(this).parents("li").first();
  763. ele.toggleClass("done");
  764. settings.onUncheck.call(ele);
  765. });
  766. } else {
  767. $('input', this).on('change', function () {
  768. var ele = $(this).parents("li").first();
  769. ele.toggleClass("done");
  770. if ($('input', ele).is(":checked")) {
  771. settings.onCheck.call(ele);
  772. } else {
  773. settings.onUncheck.call(ele);
  774. }
  775. });
  776. }
  777. });
  778. };
  779. //set/get form element value
  780. $.fn.field = function (name, value) {
  781. if (typeof name !== "string")
  782. return false;
  783. var element = $(this).find("[name='" + name + "']");
  784. if (typeof value === "undefined" && element.length >= 1) {
  785. switch (element.attr("type")) {
  786. case "checkbox":
  787. var result = new Array();
  788. element.each(function (i, val) {
  789. if ($(this).is(":checked")) {
  790. result.push($(this).val());
  791. }
  792. });
  793. return result;
  794. break;
  795. case "radio":
  796. var result;
  797. element.each(function (i, val) {
  798. if ($(this).is(":checked")) {
  799. result = $(this).val();
  800. }
  801. });
  802. return result;
  803. break;
  804. default:
  805. return element.val();
  806. break;
  807. }
  808. } else {
  809. switch (element.attr("type")) {
  810. case "checkbox":
  811. case "radio":
  812. value = $.isArray(value) ? value : [value];
  813. element.each(function (i) {
  814. $(this).prop({
  815. checked: $.inArray($(this).val(), value) > -1
  816. });
  817. });
  818. break;
  819. case undefined:
  820. default:
  821. element.val(value);
  822. break;
  823. }
  824. return element;
  825. }
  826. };
  827. }(jQuery));