Dropdown.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * --------------------------------------------
  3. * AdminLTE Dropdown.js
  4. * License MIT
  5. * --------------------------------------------
  6. */
  7. import $ from 'jquery'
  8. /**
  9. * Constants
  10. * ====================================================
  11. */
  12. const NAME = 'Dropdown'
  13. const DATA_KEY = 'lte.dropdown'
  14. const JQUERY_NO_CONFLICT = $.fn[NAME]
  15. const SELECTOR_NAVBAR = '.navbar'
  16. const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'
  17. const SELECTOR_DROPDOWN_MENU_ACTIVE = '.dropdown-menu.show'
  18. const SELECTOR_DROPDOWN_TOGGLE = '[data-toggle="dropdown"]'
  19. const CLASS_NAME_DROPDOWN_RIGHT = 'dropdown-menu-right'
  20. const CLASS_NAME_DROPDOWN_SUBMENU = 'dropdown-submenu'
  21. // TODO: this is unused; should be removed along with the extend?
  22. const Default = {}
  23. /**
  24. * Class Definition
  25. * ====================================================
  26. */
  27. class Dropdown {
  28. constructor(element, config) {
  29. this._config = config
  30. this._element = element
  31. }
  32. // Public
  33. toggleSubmenu() {
  34. this._element.siblings().show().toggleClass('show')
  35. if (!this._element.next().hasClass('show')) {
  36. this._element.parents(SELECTOR_DROPDOWN_MENU).first().find('.show').removeClass('show').hide()
  37. }
  38. this._element.parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', () => {
  39. $('.dropdown-submenu .show').removeClass('show').hide()
  40. })
  41. }
  42. fixPosition() {
  43. const $element = $(SELECTOR_DROPDOWN_MENU_ACTIVE)
  44. if ($element.length === 0) {
  45. return
  46. }
  47. if ($element.hasClass(CLASS_NAME_DROPDOWN_RIGHT)) {
  48. $element.css({
  49. left: 'inherit',
  50. right: 0
  51. })
  52. } else {
  53. $element.css({
  54. left: 0,
  55. right: 'inherit'
  56. })
  57. }
  58. const offset = $element.offset()
  59. const width = $element.width()
  60. const visiblePart = $(window).width() - offset.left
  61. if (offset.left < 0) {
  62. $element.css({
  63. left: 'inherit',
  64. right: offset.left - 5
  65. })
  66. } else if (visiblePart < width) {
  67. $element.css({
  68. left: 'inherit',
  69. right: 0
  70. })
  71. }
  72. }
  73. // Static
  74. static _jQueryInterface(config) {
  75. return this.each(function () {
  76. let data = $(this).data(DATA_KEY)
  77. const _config = $.extend({}, Default, typeof config === 'object' ? config : $(this).data())
  78. if (!data) {
  79. data = new Dropdown($(this), _config)
  80. $(this).data(DATA_KEY, data)
  81. } else if (typeof config === 'string') {
  82. if (typeof data[config] === 'undefined') {
  83. throw new TypeError(`No method named "${config}"`)
  84. }
  85. data[config]()
  86. }
  87. })
  88. }
  89. }
  90. /**
  91. * Data API
  92. * ====================================================
  93. */
  94. $(`${SELECTOR_DROPDOWN_MENU} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', function (event) {
  95. event.preventDefault()
  96. event.stopPropagation()
  97. Dropdown._jQueryInterface.call($(this), 'toggleSubmenu')
  98. })
  99. $(`${SELECTOR_NAVBAR} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', event => {
  100. event.preventDefault()
  101. if ($(event.target).parent().hasClass(CLASS_NAME_DROPDOWN_SUBMENU)) {
  102. return
  103. }
  104. setTimeout(function () {
  105. Dropdown._jQueryInterface.call($(this), 'fixPosition')
  106. }, 1)
  107. })
  108. /**
  109. * jQuery API
  110. * ====================================================
  111. */
  112. $.fn[NAME] = Dropdown._jQueryInterface
  113. $.fn[NAME].Constructor = Dropdown
  114. $.fn[NAME].noConflict = function () {
  115. $.fn[NAME] = JQUERY_NO_CONFLICT
  116. return Dropdown._jQueryInterface
  117. }
  118. export default Dropdown