Treeview.js 4.5 KB

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