Treeview.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * --------------------------------------------
  3. * AdminLTE Treeview.js
  4. * License MIT
  5. * --------------------------------------------
  6. */
  7. import $ from 'jquery'
  8. /**
  9. * Constants
  10. * ====================================================
  11. */
  12. const NAME = 'Treeview'
  13. const DATA_KEY = 'lte.treeview'
  14. const EVENT_KEY = `.${DATA_KEY}`
  15. const JQUERY_NO_CONFLICT = $.fn[NAME]
  16. const Event = {
  17. EXPANDED: `expanded${EVENT_KEY}`,
  18. COLLAPSED: `collapsed${EVENT_KEY}`,
  19. LOAD_DATA_API: `load${EVENT_KEY}`
  20. }
  21. const Selector = {
  22. LI: '.nav-item',
  23. LINK: '.nav-link',
  24. TREEVIEW_MENU: '.nav-treeview',
  25. OPEN: '.menu-open',
  26. DATA_WIDGET: '[data-widget="treeview"]'
  27. }
  28. const ClassName = {
  29. OPEN: 'menu-open',
  30. IS_OPENING: 'menu-is-opening',
  31. SIDEBAR_COLLAPSED: 'sidebar-collapse'
  32. }
  33. const Default = {
  34. trigger: `${Selector.DATA_WIDGET} ${Selector.LINK}`,
  35. animationSpeed: 300,
  36. accordion: true,
  37. expandSidebar: false,
  38. sidebarButtonSelector: '[data-widget="pushmenu"]'
  39. }
  40. /**
  41. * Class Definition
  42. * ====================================================
  43. */
  44. class Treeview {
  45. constructor(element, config) {
  46. this._config = config
  47. this._element = element
  48. }
  49. // Public
  50. init() {
  51. $(`${Selector.LI}${Selector.OPEN} ${Selector.TREEVIEW_MENU}`).css('display', 'block')
  52. this._setupListeners()
  53. }
  54. expand(treeviewMenu, parentLi) {
  55. const expandedEvent = $.Event(Event.EXPANDED)
  56. if (this._config.accordion) {
  57. const openMenuLi = parentLi.siblings(Selector.OPEN).first()
  58. const openTreeview = openMenuLi.find(Selector.TREEVIEW_MENU).first()
  59. this.collapse(openTreeview, openMenuLi)
  60. }
  61. parentLi.addClass(ClassName.IS_OPENING)
  62. treeviewMenu.stop().slideDown(this._config.animationSpeed, () => {
  63. parentLi.addClass(ClassName.OPEN)
  64. $(this._element).trigger(expandedEvent)
  65. })
  66. if (this._config.expandSidebar) {
  67. this._expandSidebar()
  68. }
  69. }
  70. collapse(treeviewMenu, parentLi) {
  71. const collapsedEvent = $.Event(Event.COLLAPSED)
  72. parentLi.removeClass(`${ClassName.IS_OPENING} ${ClassName.OPEN}`)
  73. treeviewMenu.stop().slideUp(this._config.animationSpeed, () => {
  74. $(this._element).trigger(collapsedEvent)
  75. treeviewMenu.find(`${Selector.OPEN} > ${Selector.TREEVIEW_MENU}`).slideUp()
  76. treeviewMenu.find(Selector.OPEN).removeClass(ClassName.OPEN)
  77. })
  78. }
  79. toggle(event) {
  80. const $relativeTarget = $(event.currentTarget)
  81. const $parent = $relativeTarget.parent()
  82. let treeviewMenu = $parent.find('> ' + Selector.TREEVIEW_MENU)
  83. if (!treeviewMenu.is(Selector.TREEVIEW_MENU)) {
  84. if (!$parent.is(Selector.LI)) {
  85. treeviewMenu = $parent.parent().find('> ' + Selector.TREEVIEW_MENU)
  86. }
  87. if (!treeviewMenu.is(Selector.TREEVIEW_MENU)) {
  88. return
  89. }
  90. }
  91. event.preventDefault()
  92. const parentLi = $relativeTarget.parents(Selector.LI).first()
  93. const isOpen = parentLi.hasClass(ClassName.OPEN)
  94. if (isOpen) {
  95. this.collapse($(treeviewMenu), parentLi)
  96. } else {
  97. this.expand($(treeviewMenu), parentLi)
  98. }
  99. }
  100. // Private
  101. _setupListeners() {
  102. $(document).on('click', this._config.trigger, event => {
  103. this.toggle(event)
  104. })
  105. }
  106. _expandSidebar() {
  107. if ($('body').hasClass(ClassName.SIDEBAR_COLLAPSED)) {
  108. $(this._config.sidebarButtonSelector).PushMenu('expand')
  109. }
  110. }
  111. // Static
  112. static _jQueryInterface(config) {
  113. return this.each(function () {
  114. let data = $(this).data(DATA_KEY)
  115. const _options = $.extend({}, Default, $(this).data())
  116. if (!data) {
  117. data = new Treeview($(this), _options)
  118. $(this).data(DATA_KEY, data)
  119. }
  120. if (config === 'init') {
  121. data[config]()
  122. }
  123. })
  124. }
  125. }
  126. /**
  127. * Data API
  128. * ====================================================
  129. */
  130. $(window).on(Event.LOAD_DATA_API, () => {
  131. $(Selector.DATA_WIDGET).each(function () {
  132. Treeview._jQueryInterface.call($(this), 'init')
  133. })
  134. })
  135. /**
  136. * jQuery API
  137. * ====================================================
  138. */
  139. $.fn[NAME] = Treeview._jQueryInterface
  140. $.fn[NAME].Constructor = Treeview
  141. $.fn[NAME].noConflict = function () {
  142. $.fn[NAME] = JQUERY_NO_CONFLICT
  143. return Treeview._jQueryInterface
  144. }
  145. export default Treeview