adminlte.js 24 KB

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