AdminLTE/build/js/ControlSidebar.js
REJack eeeee1fbbf
enhanced ControlSidebar
- moved control sidebar related functions from Layout.js to ControlSidebar.js
- added own scrollbar options
- added ability to set control sidebar height while scrolling
- fixed overlapping with fixed footer/navbar
2019-08-30 11:45:07 +02:00

291 lines
9.1 KiB
JavaScript

/**
* --------------------------------------------
* AdminLTE ControlSidebar.js
* License MIT
* --------------------------------------------
*/
const ControlSidebar = (($) => {
/**
* Constants
* ====================================================
*/
const NAME = 'ControlSidebar'
const DATA_KEY = 'lte.controlsidebar'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const DATA_API_KEY = '.data-api'
const Event = {
COLLAPSED: `collapsed${EVENT_KEY}`,
EXPANDED: `expanded${EVENT_KEY}`,
}
const Selector = {
CONTROL_SIDEBAR: '.control-sidebar',
CONTROL_SIDEBAR_CONTENT: '.control-sidebar-content',
DATA_TOGGLE: '[data-widget="control-sidebar"]',
CONTENT: '.content-wrapper',
HEADER: '.main-header',
FOOTER: '.main-footer',
}
const ClassName = {
CONTROL_SIDEBAR_ANIMATE: 'control-sidebar-animate',
CONTROL_SIDEBAR_OPEN: 'control-sidebar-open',
CONTROL_SIDEBAR_SLIDE: 'control-sidebar-slide-open',
LAYOUT_FIXED: 'layout-fixed',
NAVBAR_FIXED: 'layout-navbar-fixed',
NAVBAR_SM_FIXED: 'layout-sm-navbar-fixed',
NAVBAR_MD_FIXED: 'layout-md-navbar-fixed',
NAVBAR_LG_FIXED: 'layout-lg-navbar-fixed',
NAVBAR_XL_FIXED: 'layout-xl-navbar-fixed',
FOOTER_FIXED: 'layout-footer-fixed',
FOOTER_SM_FIXED: 'layout-sm-footer-fixed',
FOOTER_MD_FIXED: 'layout-md-footer-fixed',
FOOTER_LG_FIXED: 'layout-lg-footer-fixed',
FOOTER_XL_FIXED: 'layout-xl-footer-fixed',
}
const Default = {
controlsidebarSlide: true,
scrollbarTheme : 'os-theme-light',
scrollbarAutoHide: 'l',
}
/**
* Class Definition
* ====================================================
*/
class ControlSidebar {
constructor(element, config) {
this._element = element
this._config = config
this._init()
}
// Public
show() {
// Show the control sidebar
if (this._config.controlsidebarSlide) {
$('html').addClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
$('body').removeClass(ClassName.CONTROL_SIDEBAR_SLIDE).delay(300).queue(function(){
$(Selector.CONTROL_SIDEBAR).hide()
$('html').removeClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
})
} else {
$('body').removeClass(ClassName.CONTROL_SIDEBAR_OPEN)
}
const expandedEvent = $.Event(Event.EXPANDED)
$(this._element).trigger(expandedEvent)
}
collapse() {
// Collapse the control sidebar
if (this._config.controlsidebarSlide) {
$('html').addClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
$(Selector.CONTROL_SIDEBAR).show().delay(10).queue(function(){
$('body').addClass(ClassName.CONTROL_SIDEBAR_SLIDE).delay(300).queue(function(){
$('html').removeClass(ClassName.CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
})
$(this).dequeue()
})
} else {
$('body').addClass(ClassName.CONTROL_SIDEBAR_OPEN)
}
const collapsedEvent = $.Event(Event.COLLAPSED)
$(this._element).trigger(collapsedEvent)
}
toggle() {
const shouldOpen = $('body').hasClass(ClassName.CONTROL_SIDEBAR_OPEN) || $('body')
.hasClass(ClassName.CONTROL_SIDEBAR_SLIDE)
if (shouldOpen) {
// Open the control sidebar
this.show()
} else {
// Close the control sidebar
this.collapse()
}
}
// Private
_init() {
this._fixHeight()
this._fixScrollHeight()
$(window).resize(() => {
this._fixHeight()
this._fixScrollHeight()
})
$(window).scroll(() => {
if ($('body').hasClass(ClassName.CONTROL_SIDEBAR_OPEN) || $('body').hasClass(ClassName.CONTROL_SIDEBAR_SLIDE)) {
this._fixScrollHeight()
}
})
}
_fixScrollHeight() {
const heights = {
scroll: $(document).height(),
window: $(window).height(),
header: $(Selector.HEADER).outerHeight(),
footer: $(Selector.FOOTER).outerHeight(),
}
const positions = {
bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll),
top: $(window).scrollTop(),
}
let navbarFixed = false;
let footerFixed = false;
if ($('body').hasClass(ClassName.LAYOUT_FIXED)) {
if (
$('body').hasClass(ClassName.NAVBAR_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_SM_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_MD_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_LG_FIXED)
|| $('body').hasClass(ClassName.NAVBAR_XL_FIXED)
) {
if ($(Selector.HEADER).css("position") === "fixed") {
navbarFixed = true;
}
}
if (
$('body').hasClass(ClassName.FOOTER_FIXED)
|| $('body').hasClass(ClassName.FOOTER_SM_FIXED)
|| $('body').hasClass(ClassName.FOOTER_MD_FIXED)
|| $('body').hasClass(ClassName.FOOTER_LG_FIXED)
|| $('body').hasClass(ClassName.FOOTER_XL_FIXED)
) {
if ($(Selector.FOOTER).css("position") === "fixed") {
footerFixed = true;
}
}
if (positions.top === 0 && positions.bottom === 0) {
$(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer);
$(Selector.CONTROL_SIDEBAR).css('top', heights.header);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.header + heights.footer))
} else if (positions.bottom <= heights.footer) {
if (footerFixed === false) {
$(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer - positions.bottom);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.footer - positions.bottom))
} else {
$(Selector.CONTROL_SIDEBAR).css('bottom', heights.footer);
}
} else if (positions.top <= heights.header) {
if (navbarFixed === false) {
$(Selector.CONTROL_SIDEBAR).css('top', heights.header - positions.top);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window - (heights.header - positions.top))
} else {
$(Selector.CONTROL_SIDEBAR).css('top', heights.header);
}
} else {
if (navbarFixed === false) {
$(Selector.CONTROL_SIDEBAR).css('top', 0);
$(Selector.CONTROL_SIDEBAR + ', ' + Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', heights.window)
} else {
$(Selector.CONTROL_SIDEBAR).css('top', heights.header);
}
}
}
}
_fixHeight() {
const heights = {
window: $(window).height(),
header: $(Selector.HEADER).outerHeight(),
footer: $(Selector.FOOTER).outerHeight(),
}
if ($('body').hasClass(ClassName.LAYOUT_FIXED)) {
let sidebarHeight = heights.window - heights.header;
if (
$('body').hasClass(ClassName.FOOTER_FIXED)
|| $('body').hasClass(ClassName.FOOTER_SM_FIXED)
|| $('body').hasClass(ClassName.FOOTER_MD_FIXED)
|| $('body').hasClass(ClassName.FOOTER_LG_FIXED)
|| $('body').hasClass(ClassName.FOOTER_XL_FIXED)
) {
if ($(Selector.FOOTER).css("position") === "fixed") {
sidebarHeight = heights.window - heights.header - heights.footer;
}
}
$(Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).css('height', sidebarHeight)
if (typeof $.fn.overlayScrollbars !== 'undefined') {
$(Selector.CONTROL_SIDEBAR + ' ' + Selector.CONTROL_SIDEBAR_CONTENT).overlayScrollbars({
className : this._config.scrollbarTheme,
sizeAutoCapable : true,
scrollbars : {
autoHide: this._config.scrollbarAutoHide,
clickScrolling : true
}
})
}
}
}
// Static
static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
if (!data) {
data = new ControlSidebar(this, $(this).data())
$(this).data(DATA_KEY, data)
}
if (data[operation] === 'undefined') {
throw new Error(`${operation} is not a function`)
}
data[operation]()
})
}
}
/**
*
* Data Api implementation
* ====================================================
*/
$(document).on('click', Selector.DATA_TOGGLE, function (event) {
event.preventDefault()
ControlSidebar._jQueryInterface.call($(this), 'toggle')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = ControlSidebar._jQueryInterface
$.fn[NAME].Constructor = ControlSidebar
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return ControlSidebar._jQueryInterface
}
return ControlSidebar
})(jQuery)
export default ControlSidebar