adminlte.js 24 KB

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