adminlte.js 24 KB

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