X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/d673bf61c221ca1aa1b72d636ee354e8ac933fd2..refs/pull/1444/head:/resources/assets/js/components/dropdown.js diff --git a/resources/assets/js/components/dropdown.js b/resources/assets/js/components/dropdown.js index dda42e868..3887e8432 100644 --- a/resources/assets/js/components/dropdown.js +++ b/resources/assets/js/components/dropdown.js @@ -6,24 +6,60 @@ class DropDown { constructor(elem) { this.container = elem; - this.menu = elem.querySelector('ul'); + this.menu = elem.querySelector('.dropdown-menu, [dropdown-menu]'); + this.moveMenu = elem.hasAttribute('dropdown-move-menu'); this.toggle = elem.querySelector('[dropdown-toggle]'); + this.body = document.body; this.setupListeners(); } - show() { + show(event) { + this.hideAll(); + this.menu.style.display = 'block'; this.menu.classList.add('anim', 'menuIn'); - this.container.addEventListener('mouseleave', this.hide.bind(this)); + + if (this.moveMenu) { + // Move to body to prevent being trapped within scrollable sections + this.rect = this.menu.getBoundingClientRect(); + this.body.appendChild(this.menu); + this.menu.style.position = 'fixed'; + this.menu.style.left = `${this.rect.left}px`; + this.menu.style.top = `${this.rect.top}px`; + this.menu.style.width = `${this.rect.width}px`; + } + + // Set listener to hide on mouse leave or window click + this.menu.addEventListener('mouseleave', this.hide.bind(this)); + window.addEventListener('click', event => { + if (!this.menu.contains(event.target)) { + this.hide(); + } + }); // Focus on first input if existing let input = this.menu.querySelector('input'); if (input !== null) input.focus(); + + event.stopPropagation(); + } + + hideAll() { + for (let dropdown of window.components.dropdown) { + dropdown.hide(); + } } hide() { this.menu.style.display = 'none'; this.menu.classList.remove('anim', 'menuIn'); + if (this.moveMenu) { + this.menu.style.position = ''; + this.menu.style.left = ''; + this.menu.style.top = ''; + this.menu.style.width = ''; + this.container.appendChild(this.menu); + } } setupListeners() {