ControlSidebar.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /**
  2. * --------------------------------------------
  3. * AdminLTE ControlSidebar.js
  4. * License MIT
  5. * --------------------------------------------
  6. */
  7. const ControlSidebar = (($) => {
  8. /**
  9. * Constants
  10. * ====================================================
  11. */
  12. const NAME = 'ControlSidebar'
  13. const DATA_KEY = 'lte.controlsidebar'
  14. const EVENT_KEY = `.${DATA_KEY}`
  15. const JQUERY_NO_CONFLICT = $.fn[NAME]
  16. const DATA_API_KEY = '.data-api'
  17. const Event = {
  18. COLLAPSED: `collapsed${EVENT_KEY}`,
  19. EXPANDED: `expanded${EVENT_KEY}`,
  20. }
  21. const Selector = {
  22. CONTROL_SIDEBAR: '.control-sidebar',
  23. CONTROL_SIDEBAR_CONTENT: '.control-sidebar-content',
  24. DATA_TOGGLE: '[data-widget="control-sidebar"]',
  25. CONTENT: '.content-wrapper',
  26. HEADER: '.main-header',
  27. FOOTER: '.main-footer',
  28. }
  29. const ClassName = {
  30. CONTROL_SIDEBAR_ANIMATE: 'control-sidebar-animate',
  31. CONTROL_SIDEBAR_OPEN: 'control-sidebar-open',
  32. CONTROL_SIDEBAR_SLIDE: 'control-sidebar-slide-open',
  33. LAYOUT_FIXED: 'layout-fixed',
  34. NAVBAR_FIXED: 'layout-navbar-fixed',
  35. NAVBAR_SM_FIXED: 'layout-sm-navbar-fixed',
  36. NAVBAR_MD_FIXED: 'layout-md-navbar-fixed',
  37. NAVBAR_LG_FIXED: 'layout-lg-navbar-fixed',
  38. NAVBAR_XL_FIXED: 'layout-xl-navbar-fixed',
  39. FOOTER_FIXED: 'layout-footer-fixed',
  40. FOOTER_SM_FIXED: 'layout-sm-footer-fixed',
  41. FOOTER_MD_FIXED: 'layout-md-footer-fixed',
  42. FOOTER_LG_FIXED: 'layout-lg-footer-fixed',
  43. FOOTER_XL_FIXED: 'layout-xl-footer-fixed',
  44. }
  45. const Default = {
  46. controlsidebarSlide: true,
  47. scrollbarTheme : 'os-theme-light',
  48. scrollbarAutoHide: 'l',
  49. }
  50. /**
  51. * Class Definition
  52. * ====================================================
  53. */
  54. class ControlSidebar {
  55. constructor(element, config) {
  56. this._element = element
  57. this._config = config
  58. this._init()
  59. }
  60. // Public
  61. collapse() {
  62. // Show the control sidebar
  63. if (this._config.controlsidebarSlide) {
  64. $('html').addClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
  65. $('body').removeClass(ClassName.CONTROL_SIDEBAR_SLIDE).delay(300).queue(function(){
  66. $(Selector.CONTROL_SIDEBAR).hide()
  67. $('html').removeClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
  68. $(this).dequeue()
  69. })
  70. } else {
  71. $('body').removeClass(ClassName.CONTROL_SIDEBAR_OPEN)
  72. }
  73. const collapsedEvent = $.Event(Event.COLLAPSED)
  74. $(this._element).trigger(collapsedEvent)
  75. }
  76. show() {
  77. // Collapse the control sidebar
  78. if (this._config.controlsidebarSlide) {
  79. $('html').addClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
  80. $(Selector.CONTROL_SIDEBAR).show().delay(10).queue(function(){
  81. $('body').addClass(ClassName.CONTROL_SIDEBAR_SLIDE).delay(300).queue(function(){
  82. $('html').removeClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
  83. $(this).dequeue()
  84. })
  85. $(this).dequeue()
  86. })
  87. } else {
  88. $('body').addClass(ClassName.CONTROL_SIDEBAR_OPEN)
  89. }
  90. const expandedEvent = $.Event(Event.EXPANDED)
  91. $(this._element).trigger(expandedEvent)
  92. }
  93. toggle() {
  94. const shouldClose = $('body').hasClass(ClassName.CONTROL_SIDEBAR_OPEN) || $('body')
  95. .hasClass(ClassName.CONTROL_SIDEBAR_SLIDE)
  96. if (shouldClose) {
  97. // Close the control sidebar
  98. this.collapse()
  99. } else {
  100. // Open the control sidebar
  101. this.show()
  102. }
  103. }
  104. // Private
  105. _init() {
  106. this._fixHeight()
  107. this._fixScrollHeight()
  108. $(window).resize(() => {
  109. this._fixHeight()
  110. this._fixScrollHeight()
  111. })
  112. $(window).scroll(() => {
  113. if ($('body').hasClass(ClassName.CONTROL_SIDEBAR_OPEN) || $('body').hasClass(ClassName.CONTROL_SIDEBAR_SLIDE)) {
  114. this._fixScrollHeight()
  115. }
  116. })
  117. }
  118. _fixScrollHeight() {
  119. const heights = {
  120. scroll: $(document).height(),
  121. window: $(window).height(),
  122. header: $(Selector.HEADER).outerHeight(),
  123. footer: $(Selector.FOOTER).outerHeight(),
  124. }
  125. const positions = {
  126. bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll),
  127. top: $(window).scrollTop(),
  128. }
  129. let navbarFixed = false;
  130. let footerFixed = false;
  131. if ($('body').hasClass(ClassName.LAYOUT_FIXED)) {
  132. if (
  133. $('body').hasClass(ClassName.NAVBAR_FIXED)
  134. || $('body').hasClass(ClassName.NAVBAR_SM_FIXED)
  135. || $('body').hasClass(ClassName.NAVBAR_MD_FIXED)
  136. || $('body').hasClass(ClassName.NAVBAR_LG_FIXED)
  137. || $('body').hasClass(ClassName.NAVBAR_XL_FIXED)
  138. ) {
  139. if ($(Selector.HEADER).css("position") === "fixed") {
  140. navbarFixed = true;
  141. }
  142. }
  143. if (
  144. $('body').hasClass(ClassName.FOOTER_FIXED)
  145. || $('body').hasClass(ClassName.FOOTER_SM_FIXED)
  146. || $('body').hasClass(ClassName.FOOTER_MD_FIXED)
  147. || $('body').hasClass(ClassName.FOOTER_LG_FIXED)
  148. || $('body').hasClass(ClassName.FOOTER_XL_FIXED)
  149. ) {
  150. if ($(Selector.FOOTER).css("position") === "fixed") {
  151. footerFixed = true;
  152. }
  153. }
  154. if (positions.top === 0 && positions.bottom === 0) {
  155. $(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer);
  156. $(Selector.CONTROL_SIDEBAR).css('top', heights.header);
  157. $(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.header + heights.footer))
  158. } else if (positions.bottom <= heights.footer) {
  159. if (footerFixed === false) {
  160. $(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer - positions.bottom);
  161. $(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.footer - positions.bottom))
  162. } else {
  163. $(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer);
  164. }
  165. } else if (positions.top <= heights.header) {
  166. if (navbarFixed === false) {
  167. $(Selector.CONTROL_SIDEBAR).css('top', heights.header - positions.top);
  168. $(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.header - positions.top))
  169. } else {
  170. $(Selector.CONTROL_SIDEBAR).css('top', heights.header);
  171. }
  172. } else {
  173. if (navbarFixed === false) {
  174. $(Selector.CONTROL_SIDEBAR).css('top', 0);
  175. $(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window)
  176. } else {
  177. $(Selector.CONTROL_SIDEBAR).css('top', heights.header);
  178. }
  179. }
  180. }
  181. }
  182. _fixHeight() {
  183. const heights = {
  184. window: $(window).height(),
  185. header: $(Selector.HEADER).outerHeight(),
  186. footer: $(Selector.FOOTER).outerHeight(),
  187. }
  188. if ($('body').hasClass(ClassName.LAYOUT_FIXED)) {
  189. let sidebarHeight = heights.window - heights.header;
  190. if (
  191. $('body').hasClass(ClassName.FOOTER_FIXED)
  192. || $('body').hasClass(ClassName.FOOTER_SM_FIXED)
  193. || $('body').hasClass(ClassName.FOOTER_MD_FIXED)
  194. || $('body').hasClass(ClassName.FOOTER_LG_FIXED)
  195. || $('body').hasClass(ClassName.FOOTER_XL_FIXED)
  196. ) {
  197. if ($(Selector.FOOTER).css("position") === "fixed") {
  198. sidebarHeight = heights.window - heights.header - heights.footer;
  199. }
  200. }
  201. $(Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', sidebarHeight)
  202. if (typeof $.fn.overlayScrollbars !== 'undefined') {
  203. $(Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).overlayScrollbars({
  204. className : this._config.scrollbarTheme,
  205. sizeAutoCapable : true,
  206. scrollbars : {
  207. autoHide: this._config.scrollbarAutoHide,
  208. clickScrolling : true
  209. }
  210. })
  211. }
  212. }
  213. }
  214. // Static
  215. static _jQueryInterface(operation) {
  216. return this.each(function () {
  217. let data = $(this).data(DATA_KEY)
  218. const _options = $.extend({}, Default, $(this).data())
  219. if (!data) {
  220. data = new ControlSidebar(this, _options)
  221. $(this).data(DATA_KEY, data)
  222. }
  223. if (data[operation] === 'undefined') {
  224. throw new Error(`${operation} is not a function`)
  225. }
  226. data[operation]()
  227. })
  228. }
  229. }
  230. /**
  231. *
  232. * Data Api implementation
  233. * ====================================================
  234. */
  235. $(document).on('click', Selector.DATA_TOGGLE, function (event) {
  236. event.preventDefault()
  237. ControlSidebar._jQueryInterface.call($(this), 'toggle')
  238. })
  239. /**
  240. * jQuery API
  241. * ====================================================
  242. */
  243. $.fn[NAME] = ControlSidebar._jQueryInterface
  244. $.fn[NAME].Constructor = ControlSidebar
  245. $.fn[NAME].noConflict = function () {
  246. $.fn[NAME] = JQUERY_NO_CONFLICT
  247. return ControlSidebar._jQueryInterface
  248. }
  249. return ControlSidebar
  250. })(jQuery)
  251. export default ControlSidebar