adminlte.js 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  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 Colorlib
  8. * @support <https://github.com/ColorlibHQ/AdminLTE/issues>
  9. * @version 2.4.12
  10. * @repository git://github.com/ColorlibHQ/AdminLTE.git
  11. * @license MIT <http://opensource.org/licenses/MIT>
  12. */
  13. // Make sure jQuery has been loaded
  14. if (typeof jQuery === 'undefined') {
  15. throw new Error('AdminLTE requires jQuery')
  16. }
  17. /* BoxRefresh()
  18. * =========
  19. * Adds AJAX content control to a box.
  20. *
  21. * @Usage: $('#my-box').boxRefresh(options)
  22. * or add [data-widget="box-refresh"] to the box element
  23. * Pass any option as data-option="value"
  24. */
  25. +function ($) {
  26. 'use strict';
  27. var DataKey = 'lte.boxrefresh';
  28. var Default = {
  29. source : '',
  30. params : {},
  31. trigger : '.refresh-btn',
  32. content : '.box-body',
  33. loadInContent : true,
  34. responseType : '',
  35. overlayTemplate: '<div class="overlay"><div class="fa fa-refresh fa-spin"></div></div>',
  36. onLoadStart : function () {
  37. },
  38. onLoadDone : function (response) {
  39. return response;
  40. }
  41. };
  42. var Selector = {
  43. data: '[data-widget="box-refresh"]'
  44. };
  45. // BoxRefresh Class Definition
  46. // =========================
  47. var BoxRefresh = function (element, options) {
  48. this.element = element;
  49. this.options = options;
  50. this.$overlay = $(options.overlayTemplate);
  51. if (options.source === '') {
  52. throw new Error('Source url was not defined. Please specify a url in your BoxRefresh source option.');
  53. }
  54. this._setUpListeners();
  55. this.load();
  56. };
  57. BoxRefresh.prototype.load = function () {
  58. this._addOverlay();
  59. this.options.onLoadStart.call($(this));
  60. $.get(this.options.source, this.options.params, function (response) {
  61. if (this.options.loadInContent) {
  62. $(this.element).find(this.options.content).html(response);
  63. }
  64. this.options.onLoadDone.call($(this), response);
  65. this._removeOverlay();
  66. }.bind(this), this.options.responseType !== '' && this.options.responseType);
  67. };
  68. // Private
  69. BoxRefresh.prototype._setUpListeners = function () {
  70. $(this.element).on('click', this.options.trigger, function (event) {
  71. if (event) event.preventDefault();
  72. this.load();
  73. }.bind(this));
  74. };
  75. BoxRefresh.prototype._addOverlay = function () {
  76. $(this.element).append(this.$overlay);
  77. };
  78. BoxRefresh.prototype._removeOverlay = function () {
  79. $(this.$overlay).remove();
  80. };
  81. // Plugin Definition
  82. // =================
  83. function Plugin(option) {
  84. return this.each(function () {
  85. var $this = $(this);
  86. var data = $this.data(DataKey);
  87. if (!data) {
  88. var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option);
  89. $this.data(DataKey, (data = new BoxRefresh($this, options)));
  90. }
  91. if (typeof data == 'string') {
  92. if (typeof data[option] == 'undefined') {
  93. throw new Error('No method named ' + option);
  94. }
  95. data[option]();
  96. }
  97. });
  98. }
  99. var old = $.fn.boxRefresh;
  100. $.fn.boxRefresh = Plugin;
  101. $.fn.boxRefresh.Constructor = BoxRefresh;
  102. // No Conflict Mode
  103. // ================
  104. $.fn.boxRefresh.noConflict = function () {
  105. $.fn.boxRefresh = old;
  106. return this;
  107. };
  108. // BoxRefresh Data API
  109. // =================
  110. $(window).on('load', function () {
  111. $(Selector.data).each(function () {
  112. Plugin.call($(this));
  113. });
  114. });
  115. }(jQuery);
  116. /* BoxWidget()
  117. * ======
  118. * Adds box widget functions to boxes.
  119. *
  120. * @Usage: $('.my-box').boxWidget(options)
  121. * This plugin auto activates on any element using the `.box` class
  122. * Pass any option as data-option="value"
  123. */
  124. +function ($) {
  125. 'use strict';
  126. var DataKey = 'lte.boxwidget';
  127. var Default = {
  128. animationSpeed : 500,
  129. collapseTrigger: '[data-widget="collapse"]',
  130. removeTrigger : '[data-widget="remove"]',
  131. collapseIcon : 'fa-minus',
  132. expandIcon : 'fa-plus',
  133. removeIcon : 'fa-times'
  134. };
  135. var Selector = {
  136. data : '.box',
  137. collapsed: '.collapsed-box',
  138. header : '.box-header',
  139. body : '.box-body',
  140. footer : '.box-footer',
  141. tools : '.box-tools'
  142. };
  143. var ClassName = {
  144. collapsed: 'collapsed-box'
  145. };
  146. var Event = {
  147. collapsing: 'collapsing.boxwidget',
  148. collapsed: 'collapsed.boxwidget',
  149. expanding: 'expanding.boxwidget',
  150. expanded: 'expanded.boxwidget',
  151. removing: 'removing.boxwidget',
  152. removed: 'removed.boxwidget'
  153. };
  154. // BoxWidget Class Definition
  155. // =====================
  156. var BoxWidget = function (element, options) {
  157. this.element = element;
  158. this.options = options;
  159. this._setUpListeners();
  160. };
  161. BoxWidget.prototype.toggle = function () {
  162. var isOpen = !$(this.element).is(Selector.collapsed);
  163. if (isOpen) {
  164. this.collapse();
  165. } else {
  166. this.expand();
  167. }
  168. };
  169. BoxWidget.prototype.expand = function () {
  170. var expandedEvent = $.Event(Event.expanded);
  171. var expandingEvent = $.Event(Event.expanding);
  172. var collapseIcon = this.options.collapseIcon;
  173. var expandIcon = this.options.expandIcon;
  174. $(this.element).removeClass(ClassName.collapsed);
  175. $(this.element)
  176. .children(Selector.header + ', ' + Selector.body + ', ' + Selector.footer)
  177. .children(Selector.tools)
  178. .find('.' + expandIcon)
  179. .removeClass(expandIcon)
  180. .addClass(collapseIcon);
  181. $(this.element).children(Selector.body + ', ' + Selector.footer)
  182. .slideDown(this.options.animationSpeed, function () {
  183. $(this.element).trigger(expandedEvent);
  184. }.bind(this))
  185. .trigger(expandingEvent);
  186. };
  187. BoxWidget.prototype.collapse = function () {
  188. var collapsedEvent = $.Event(Event.collapsed);
  189. var collapsingEvent = $.Event(Event.collapsing);
  190. var collapseIcon = this.options.collapseIcon;
  191. var expandIcon = this.options.expandIcon;
  192. $(this.element)
  193. .children(Selector.header + ', ' + Selector.body + ', ' + Selector.footer)
  194. .children(Selector.tools)
  195. .find('.' + collapseIcon)
  196. .removeClass(collapseIcon)
  197. .addClass(expandIcon);
  198. $(this.element).children(Selector.body + ', ' + Selector.footer)
  199. .slideUp(this.options.animationSpeed, function () {
  200. $(this.element).addClass(ClassName.collapsed);
  201. $(this.element).trigger(collapsedEvent);
  202. }.bind(this))
  203. .trigger(collapsingEvent);
  204. };
  205. BoxWidget.prototype.remove = function () {
  206. var removedEvent = $.Event(Event.removed);
  207. var removingEvent = $.Event(Event.removing);
  208. $(this.element).slideUp(this.options.animationSpeed, function () {
  209. $(this.element).trigger(removedEvent);
  210. $(this.element).remove();
  211. }.bind(this))
  212. .trigger(removingEvent);
  213. };
  214. // Private
  215. BoxWidget.prototype._setUpListeners = function () {
  216. var that = this;
  217. $(this.element).on('click', this.options.collapseTrigger, function (event) {
  218. if (event) event.preventDefault();
  219. that.toggle($(this));
  220. return false;
  221. });
  222. $(this.element).on('click', this.options.removeTrigger, function (event) {
  223. if (event) event.preventDefault();
  224. that.remove($(this));
  225. return false;
  226. });
  227. };
  228. // Plugin Definition
  229. // =================
  230. function Plugin(option) {
  231. return this.each(function () {
  232. var $this = $(this);
  233. var data = $this.data(DataKey);
  234. if (!data) {
  235. var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option);
  236. $this.data(DataKey, (data = new BoxWidget($this, options)));
  237. }
  238. if (typeof option == 'string') {
  239. if (typeof data[option] == 'undefined') {
  240. throw new Error('No method named ' + option);
  241. }
  242. data[option]();
  243. }
  244. });
  245. }
  246. var old = $.fn.boxWidget;
  247. $.fn.boxWidget = Plugin;
  248. $.fn.boxWidget.Constructor = BoxWidget;
  249. // No Conflict Mode
  250. // ================
  251. $.fn.boxWidget.noConflict = function () {
  252. $.fn.boxWidget = old;
  253. return this;
  254. };
  255. // BoxWidget Data API
  256. // ==================
  257. $(window).on('load', function () {
  258. $(Selector.data).each(function () {
  259. Plugin.call($(this));
  260. });
  261. });
  262. }(jQuery);
  263. /* ControlSidebar()
  264. * ===============
  265. * Toggles the state of the control sidebar
  266. *
  267. * @Usage: $('#control-sidebar-trigger').controlSidebar(options)
  268. * or add [data-toggle="control-sidebar"] to the trigger
  269. * Pass any option as data-option="value"
  270. */
  271. +function ($) {
  272. 'use strict';
  273. var DataKey = 'lte.controlsidebar';
  274. var Default = {
  275. slide: true
  276. };
  277. var Selector = {
  278. sidebar: '.control-sidebar',
  279. data : '[data-toggle="control-sidebar"]',
  280. open : '.control-sidebar-open',
  281. bg : '.control-sidebar-bg',
  282. wrapper: '.wrapper',
  283. content: '.content-wrapper',
  284. boxed : '.layout-boxed'
  285. };
  286. var ClassName = {
  287. open : 'control-sidebar-open',
  288. fixed: 'fixed'
  289. };
  290. var Event = {
  291. collapsed: 'collapsed.controlsidebar',
  292. expanded : 'expanded.controlsidebar'
  293. };
  294. // ControlSidebar Class Definition
  295. // ===============================
  296. var ControlSidebar = function (element, options) {
  297. this.element = element;
  298. this.options = options;
  299. this.hasBindedResize = false;
  300. this.init();
  301. };
  302. ControlSidebar.prototype.init = function () {
  303. // Add click listener if the element hasn't been
  304. // initialized using the data API
  305. if (!$(this.element).is(Selector.data)) {
  306. $(this).on('click', this.toggle);
  307. }
  308. this.fix();
  309. $(window).resize(function () {
  310. this.fix();
  311. }.bind(this));
  312. };
  313. ControlSidebar.prototype.toggle = function (event) {
  314. if (event) event.preventDefault();
  315. this.fix();
  316. if (!$(Selector.sidebar).is(Selector.open) && !$('body').is(Selector.open)) {
  317. this.expand();
  318. } else {
  319. this.collapse();
  320. }
  321. };
  322. ControlSidebar.prototype.expand = function () {
  323. $(Selector.sidebar).show();
  324. if (!this.options.slide) {
  325. $('body').addClass(ClassName.open);
  326. } else {
  327. $(Selector.sidebar).addClass(ClassName.open);
  328. }
  329. $(this.element).trigger($.Event(Event.expanded));
  330. };
  331. ControlSidebar.prototype.collapse = function () {
  332. $('body, ' + Selector.sidebar).removeClass(ClassName.open);
  333. $(Selector.sidebar).fadeOut();
  334. $(this.element).trigger($.Event(Event.collapsed));
  335. };
  336. ControlSidebar.prototype.fix = function () {
  337. if ($('body').is(Selector.boxed)) {
  338. this._fixForBoxed($(Selector.bg));
  339. }
  340. };
  341. // Private
  342. ControlSidebar.prototype._fixForBoxed = function (bg) {
  343. bg.css({
  344. position: 'absolute',
  345. height : $(Selector.wrapper).height()
  346. });
  347. };
  348. // Plugin Definition
  349. // =================
  350. function Plugin(option) {
  351. return this.each(function () {
  352. var $this = $(this);
  353. var data = $this.data(DataKey);
  354. if (!data) {
  355. var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option);
  356. $this.data(DataKey, (data = new ControlSidebar($this, options)));
  357. }
  358. if (typeof option == 'string') data.toggle();
  359. });
  360. }
  361. var old = $.fn.controlSidebar;
  362. $.fn.controlSidebar = Plugin;
  363. $.fn.controlSidebar.Constructor = ControlSidebar;
  364. // No Conflict Mode
  365. // ================
  366. $.fn.controlSidebar.noConflict = function () {
  367. $.fn.controlSidebar = old;
  368. return this;
  369. };
  370. // ControlSidebar Data API
  371. // =======================
  372. $(document).on('click', Selector.data, function (event) {
  373. if (event) event.preventDefault();
  374. Plugin.call($(this), 'toggle');
  375. });
  376. }(jQuery);
  377. /* DirectChat()
  378. * ===============
  379. * Toggles the state of the control sidebar
  380. *
  381. * @Usage: $('#my-chat-box').directChat()
  382. * or add [data-widget="direct-chat"] to the trigger
  383. */
  384. +function ($) {
  385. 'use strict';
  386. var DataKey = 'lte.directchat';
  387. var Selector = {
  388. data: '[data-widget="chat-pane-toggle"]',
  389. box : '.direct-chat'
  390. };
  391. var ClassName = {
  392. open: 'direct-chat-contacts-open'
  393. };
  394. // DirectChat Class Definition
  395. // ===========================
  396. var DirectChat = function (element) {
  397. this.element = element;
  398. };
  399. DirectChat.prototype.toggle = function ($trigger) {
  400. $trigger.parents(Selector.box).first().toggleClass(ClassName.open);
  401. };
  402. // Plugin Definition
  403. // =================
  404. function Plugin(option) {
  405. return this.each(function () {
  406. var $this = $(this);
  407. var data = $this.data(DataKey);
  408. if (!data) {
  409. $this.data(DataKey, (data = new DirectChat($this)));
  410. }
  411. if (typeof option == 'string') data.toggle($this);
  412. });
  413. }
  414. var old = $.fn.directChat;
  415. $.fn.directChat = Plugin;
  416. $.fn.directChat.Constructor = DirectChat;
  417. // No Conflict Mode
  418. // ================
  419. $.fn.directChat.noConflict = function () {
  420. $.fn.directChat = old;
  421. return this;
  422. };
  423. // DirectChat Data API
  424. // ===================
  425. $(document).on('click', Selector.data, function (event) {
  426. if (event) event.preventDefault();
  427. Plugin.call($(this), 'toggle');
  428. });
  429. }(jQuery);
  430. /* PushMenu()
  431. * ==========
  432. * Adds the push menu functionality to the sidebar.
  433. *
  434. * @usage: $('.btn').pushMenu(options)
  435. * or add [data-toggle="push-menu"] to any button
  436. * Pass any option as data-option="value"
  437. */
  438. +function ($) {
  439. 'use strict';
  440. var DataKey = 'lte.pushmenu';
  441. var Default = {
  442. collapseScreenSize : 767,
  443. expandOnHover : false,
  444. expandTransitionDelay: 200
  445. };
  446. var Selector = {
  447. collapsed : '.sidebar-collapse',
  448. open : '.sidebar-open',
  449. mainSidebar : '.main-sidebar',
  450. contentWrapper: '.content-wrapper',
  451. searchInput : '.sidebar-form .form-control',
  452. button : '[data-toggle="push-menu"]',
  453. mini : '.sidebar-mini',
  454. expanded : '.sidebar-expanded-on-hover',
  455. layoutFixed : '.fixed'
  456. };
  457. var ClassName = {
  458. collapsed : 'sidebar-collapse',
  459. open : 'sidebar-open',
  460. mini : 'sidebar-mini',
  461. expanded : 'sidebar-expanded-on-hover',
  462. expandFeature: 'sidebar-mini-expand-feature',
  463. layoutFixed : 'fixed'
  464. };
  465. var Event = {
  466. expanded : 'expanded.pushMenu',
  467. collapsed: 'collapsed.pushMenu'
  468. };
  469. // PushMenu Class Definition
  470. // =========================
  471. var PushMenu = function (options) {
  472. this.options = options;
  473. this.init();
  474. };
  475. PushMenu.prototype.init = function () {
  476. if (this.options.expandOnHover
  477. || ($('body').is(Selector.mini + Selector.layoutFixed))) {
  478. this.expandOnHover();
  479. $('body').addClass(ClassName.expandFeature);
  480. }
  481. $(Selector.contentWrapper).click(function () {
  482. // Enable hide menu when clicking on the content-wrapper on small screens
  483. if ($(window).width() <= this.options.collapseScreenSize && $('body').hasClass(ClassName.open)) {
  484. this.close();
  485. }
  486. }.bind(this));
  487. // __Fix for android devices
  488. $(Selector.searchInput).click(function (e) {
  489. e.stopPropagation();
  490. });
  491. };
  492. PushMenu.prototype.toggle = function () {
  493. var windowWidth = $(window).width();
  494. var isOpen = !$('body').hasClass(ClassName.collapsed);
  495. if (windowWidth <= this.options.collapseScreenSize) {
  496. isOpen = $('body').hasClass(ClassName.open);
  497. }
  498. if (!isOpen) {
  499. this.open();
  500. } else {
  501. this.close();
  502. }
  503. };
  504. PushMenu.prototype.open = function () {
  505. var windowWidth = $(window).width();
  506. if (windowWidth > this.options.collapseScreenSize) {
  507. $('body').removeClass(ClassName.collapsed)
  508. .trigger($.Event(Event.expanded));
  509. }
  510. else {
  511. $('body').addClass(ClassName.open)
  512. .trigger($.Event(Event.expanded));
  513. }
  514. };
  515. PushMenu.prototype.close = function () {
  516. var windowWidth = $(window).width();
  517. if (windowWidth > this.options.collapseScreenSize) {
  518. $('body').addClass(ClassName.collapsed)
  519. .trigger($.Event(Event.collapsed));
  520. } else {
  521. $('body').removeClass(ClassName.open + ' ' + ClassName.collapsed)
  522. .trigger($.Event(Event.collapsed));
  523. }
  524. };
  525. PushMenu.prototype.expandOnHover = function () {
  526. $(Selector.mainSidebar).hover(function () {
  527. if ($('body').is(Selector.mini + Selector.collapsed)
  528. && $(window).width() > this.options.collapseScreenSize) {
  529. this.expand();
  530. }
  531. }.bind(this), function () {
  532. if ($('body').is(Selector.expanded)) {
  533. this.collapse();
  534. }
  535. }.bind(this));
  536. };
  537. PushMenu.prototype.expand = function () {
  538. setTimeout(function () {
  539. $('body').removeClass(ClassName.collapsed)
  540. .addClass(ClassName.expanded);
  541. }, this.options.expandTransitionDelay);
  542. };
  543. PushMenu.prototype.collapse = function () {
  544. setTimeout(function () {
  545. $('body').removeClass(ClassName.expanded)
  546. .addClass(ClassName.collapsed);
  547. }, this.options.expandTransitionDelay);
  548. };
  549. // PushMenu Plugin Definition
  550. // ==========================
  551. function Plugin(option) {
  552. return this.each(function () {
  553. var $this = $(this);
  554. var data = $this.data(DataKey);
  555. if (!data) {
  556. var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option);
  557. $this.data(DataKey, (data = new PushMenu(options)));
  558. }
  559. if (option === 'toggle') data.toggle();
  560. });
  561. }
  562. var old = $.fn.pushMenu;
  563. $.fn.pushMenu = Plugin;
  564. $.fn.pushMenu.Constructor = PushMenu;
  565. // No Conflict Mode
  566. // ================
  567. $.fn.pushMenu.noConflict = function () {
  568. $.fn.pushMenu = old;
  569. return this;
  570. };
  571. // Data API
  572. // ========
  573. $(document).on('click', Selector.button, function (e) {
  574. e.preventDefault();
  575. Plugin.call($(this), 'toggle');
  576. });
  577. $(window).on('load', function () {
  578. Plugin.call($(Selector.button));
  579. });
  580. }(jQuery);
  581. /* TodoList()
  582. * =========
  583. * Converts a list into a todoList.
  584. *
  585. * @Usage: $('.my-list').todoList(options)
  586. * or add [data-widget="todo-list"] to the ul element
  587. * Pass any option as data-option="value"
  588. */
  589. +function ($) {
  590. 'use strict';
  591. var DataKey = 'lte.todolist';
  592. var Default = {
  593. onCheck : function (item) {
  594. return item;
  595. },
  596. onUnCheck: function (item) {
  597. return item;
  598. }
  599. };
  600. var Selector = {
  601. data: '[data-widget="todo-list"]'
  602. };
  603. var ClassName = {
  604. done: 'done'
  605. };
  606. // TodoList Class Definition
  607. // =========================
  608. var TodoList = function (element, options) {
  609. this.element = element;
  610. this.options = options;
  611. this._setUpListeners();
  612. };
  613. TodoList.prototype.toggle = function (item) {
  614. item.parents(Selector.li).first().toggleClass(ClassName.done);
  615. if (!item.prop('checked')) {
  616. this.unCheck(item);
  617. return;
  618. }
  619. this.check(item);
  620. };
  621. TodoList.prototype.check = function (item) {
  622. this.options.onCheck.call(item);
  623. };
  624. TodoList.prototype.unCheck = function (item) {
  625. this.options.onUnCheck.call(item);
  626. };
  627. // Private
  628. TodoList.prototype._setUpListeners = function () {
  629. var that = this;
  630. $(this.element).on('change ifChanged', 'input:checkbox', function () {
  631. that.toggle($(this));
  632. });
  633. };
  634. // Plugin Definition
  635. // =================
  636. function Plugin(option) {
  637. return this.each(function () {
  638. var $this = $(this);
  639. var data = $this.data(DataKey);
  640. if (!data) {
  641. var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option);
  642. $this.data(DataKey, (data = new TodoList($this, options)));
  643. }
  644. if (typeof data == 'string') {
  645. if (typeof data[option] == 'undefined') {
  646. throw new Error('No method named ' + option);
  647. }
  648. data[option]();
  649. }
  650. });
  651. }
  652. var old = $.fn.todoList;
  653. $.fn.todoList = Plugin;
  654. $.fn.todoList.Constructor = TodoList;
  655. // No Conflict Mode
  656. // ================
  657. $.fn.todoList.noConflict = function () {
  658. $.fn.todoList = old;
  659. return this;
  660. };
  661. // TodoList Data API
  662. // =================
  663. $(window).on('load', function () {
  664. $(Selector.data).each(function () {
  665. Plugin.call($(this));
  666. });
  667. });
  668. }(jQuery);
  669. /* Tree()
  670. * ======
  671. * Converts a nested list into a multilevel
  672. * tree view menu.
  673. *
  674. * @Usage: $('.my-menu').tree(options)
  675. * or add [data-widget="tree"] to the ul element
  676. * Pass any option as data-option="value"
  677. */
  678. +function ($) {
  679. 'use strict';
  680. var DataKey = 'lte.tree';
  681. var Default = {
  682. animationSpeed: 500,
  683. accordion : true,
  684. followLink : false,
  685. trigger : '.treeview a'
  686. };
  687. var Selector = {
  688. tree : '.tree',
  689. treeview : '.treeview',
  690. treeviewMenu: '.treeview-menu',
  691. open : '.menu-open, .active',
  692. li : 'li',
  693. data : '[data-widget="tree"]',
  694. active : '.active'
  695. };
  696. var ClassName = {
  697. open: 'menu-open',
  698. tree: 'tree'
  699. };
  700. var Event = {
  701. collapsed: 'collapsed.tree',
  702. expanded : 'expanded.tree'
  703. };
  704. // Tree Class Definition
  705. // =====================
  706. var Tree = function (element, options) {
  707. this.element = element;
  708. this.options = options;
  709. $(this.element).addClass(ClassName.tree);
  710. $(Selector.treeview + Selector.active, this.element).addClass(ClassName.open);
  711. this._setUpListeners();
  712. };
  713. Tree.prototype.toggle = function (link, event) {
  714. var treeviewMenu = link.next(Selector.treeviewMenu);
  715. var parentLi = link.parent();
  716. var isOpen = parentLi.hasClass(ClassName.open);
  717. if (!parentLi.is(Selector.treeview)) {
  718. return;
  719. }
  720. if (!this.options.followLink || link.attr('href') === '#') {
  721. event.preventDefault();
  722. }
  723. if (isOpen) {
  724. this.collapse(treeviewMenu, parentLi);
  725. } else {
  726. this.expand(treeviewMenu, parentLi);
  727. }
  728. };
  729. Tree.prototype.expand = function (tree, parent) {
  730. var expandedEvent = $.Event(Event.expanded);
  731. if (this.options.accordion) {
  732. var openMenuLi = parent.siblings(Selector.open);
  733. var openTree = openMenuLi.children(Selector.treeviewMenu);
  734. this.collapse(openTree, openMenuLi);
  735. }
  736. parent.addClass(ClassName.open);
  737. tree.slideDown(this.options.animationSpeed, function () {
  738. $(this.element).trigger(expandedEvent);
  739. }.bind(this));
  740. };
  741. Tree.prototype.collapse = function (tree, parentLi) {
  742. var collapsedEvent = $.Event(Event.collapsed);
  743. //tree.find(Selector.open).removeClass(ClassName.open);
  744. parentLi.removeClass(ClassName.open);
  745. tree.slideUp(this.options.animationSpeed, function () {
  746. //tree.find(Selector.open + ' > ' + Selector.treeview).slideUp();
  747. $(this.element).trigger(collapsedEvent);
  748. }.bind(this));
  749. };
  750. // Private
  751. Tree.prototype._setUpListeners = function () {
  752. var that = this;
  753. $(this.element).on('click', this.options.trigger, function (event) {
  754. that.toggle($(this), event);
  755. });
  756. };
  757. // Plugin Definition
  758. // =================
  759. function Plugin(option) {
  760. return this.each(function () {
  761. var $this = $(this);
  762. var data = $this.data(DataKey);
  763. if (!data) {
  764. var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option);
  765. $this.data(DataKey, new Tree($this, options));
  766. }
  767. });
  768. }
  769. var old = $.fn.tree;
  770. $.fn.tree = Plugin;
  771. $.fn.tree.Constructor = Tree;
  772. // No Conflict Mode
  773. // ================
  774. $.fn.tree.noConflict = function () {
  775. $.fn.tree = old;
  776. return this;
  777. };
  778. // Tree Data API
  779. // =============
  780. $(window).on('load', function () {
  781. $(Selector.data).each(function () {
  782. Plugin.call($(this));
  783. });
  784. });
  785. }(jQuery);
  786. /* Layout()
  787. * ========
  788. * Implements AdminLTE layout.
  789. * Fixes the layout height in case min-height fails.
  790. *
  791. * @usage activated automatically upon window load.
  792. * Configure any options by passing data-option="value"
  793. * to the body tag.
  794. */
  795. +function ($) {
  796. 'use strict';
  797. var DataKey = 'lte.layout';
  798. var Default = {
  799. slimscroll : true,
  800. resetHeight: true
  801. };
  802. var Selector = {
  803. wrapper : '.wrapper',
  804. contentWrapper: '.content-wrapper',
  805. layoutBoxed : '.layout-boxed',
  806. mainFooter : '.main-footer',
  807. mainHeader : '.main-header',
  808. sidebar : '.sidebar',
  809. controlSidebar: '.control-sidebar',
  810. fixed : '.fixed',
  811. sidebarMenu : '.sidebar-menu',
  812. logo : '.main-header .logo'
  813. };
  814. var ClassName = {
  815. fixed : 'fixed',
  816. holdTransition: 'hold-transition'
  817. };
  818. var Layout = function (options) {
  819. this.options = options;
  820. this.bindedResize = false;
  821. this.activate();
  822. };
  823. Layout.prototype.activate = function () {
  824. this.fix();
  825. this.fixSidebar();
  826. $('body').removeClass(ClassName.holdTransition);
  827. if (this.options.resetHeight) {
  828. $('body, html, ' + Selector.wrapper).css({
  829. 'height' : 'auto',
  830. 'min-height': '100%'
  831. });
  832. }
  833. if (!this.bindedResize) {
  834. $(window).resize(function () {
  835. this.fix();
  836. this.fixSidebar();
  837. $(Selector.logo + ', ' + Selector.sidebar).one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function () {
  838. this.fix();
  839. this.fixSidebar();
  840. }.bind(this));
  841. }.bind(this));
  842. this.bindedResize = true;
  843. }
  844. $(Selector.sidebarMenu).on('expanded.tree', function () {
  845. this.fix();
  846. this.fixSidebar();
  847. }.bind(this));
  848. $(Selector.sidebarMenu).on('collapsed.tree', function () {
  849. this.fix();
  850. this.fixSidebar();
  851. }.bind(this));
  852. };
  853. Layout.prototype.fix = function () {
  854. // Remove overflow from .wrapper if layout-boxed exists
  855. $(Selector.layoutBoxed + ' > ' + Selector.wrapper).css('overflow', 'hidden');
  856. // Get window height and the wrapper height
  857. var footerHeight = $(Selector.mainFooter).outerHeight() || 0;
  858. var headerHeight = $(Selector.mainHeader).outerHeight() || 0;
  859. var neg = headerHeight + footerHeight;
  860. var windowHeight = $(window).height();
  861. var sidebarHeight = $(Selector.sidebar).height() || 0;
  862. // Set the min-height of the content and sidebar based on
  863. // the height of the document.
  864. if ($('body').hasClass(ClassName.fixed)) {
  865. $(Selector.contentWrapper).css('min-height', windowHeight - footerHeight);
  866. } else {
  867. var postSetHeight;
  868. if (windowHeight >= sidebarHeight + headerHeight) {
  869. $(Selector.contentWrapper).css('min-height', windowHeight - neg);
  870. postSetHeight = windowHeight - neg;
  871. } else {
  872. $(Selector.contentWrapper).css('min-height', sidebarHeight);
  873. postSetHeight = sidebarHeight;
  874. }
  875. // Fix for the control sidebar height
  876. var $controlSidebar = $(Selector.controlSidebar);
  877. if (typeof $controlSidebar !== 'undefined') {
  878. if ($controlSidebar.height() > postSetHeight)
  879. $(Selector.contentWrapper).css('min-height', $controlSidebar.height());
  880. }
  881. }
  882. };
  883. Layout.prototype.fixSidebar = function () {
  884. // Make sure the body tag has the .fixed class
  885. if (!$('body').hasClass(ClassName.fixed)) {
  886. if (typeof $.fn.slimScroll !== 'undefined') {
  887. $(Selector.sidebar).slimScroll({ destroy: true }).height('auto');
  888. }
  889. return;
  890. }
  891. // Enable slimscroll for fixed layout
  892. if (this.options.slimscroll) {
  893. if (typeof $.fn.slimScroll !== 'undefined') {
  894. // Destroy if it exists
  895. // $(Selector.sidebar).slimScroll({ destroy: true }).height('auto')
  896. // Add slimscroll
  897. $(Selector.sidebar).slimScroll({
  898. height: ($(window).height() - $(Selector.mainHeader).height()) + 'px'
  899. });
  900. }
  901. }
  902. };
  903. // Plugin Definition
  904. // =================
  905. function Plugin(option) {
  906. return this.each(function () {
  907. var $this = $(this);
  908. var data = $this.data(DataKey);
  909. if (!data) {
  910. var options = $.extend({}, Default, $this.data(), typeof option === 'object' && option);
  911. $this.data(DataKey, (data = new Layout(options)));
  912. }
  913. if (typeof option === 'string') {
  914. if (typeof data[option] === 'undefined') {
  915. throw new Error('No method named ' + option);
  916. }
  917. data[option]();
  918. }
  919. });
  920. }
  921. var old = $.fn.layout;
  922. $.fn.layout = Plugin;
  923. $.fn.layout.Constuctor = Layout;
  924. // No conflict mode
  925. // ================
  926. $.fn.layout.noConflict = function () {
  927. $.fn.layout = old;
  928. return this;
  929. };
  930. // Layout DATA-API
  931. // ===============
  932. $(window).on('load', function () {
  933. Plugin.call($('body'));
  934. });
  935. }(jQuery);