From 3fc8ac9e72452c30d8867389e51709f201b309bb Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 28 Dec 2018 19:16:26 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Dropdown=20z-index=20prob?= =?UTF-8?q?lem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Z-index of dropdown does not work because it's parent has a transform property. To avoid this, we float the dropdown using fixed co-ordinates and then update the x, y positions. --- src/columnmanager.js | 88 +++++++++++++++++++++++++++++--------------- src/datatable.js | 2 + src/style.css | 7 +--- 3 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/columnmanager.js b/src/columnmanager.js index 570a8f7..b6051c9 100644 --- a/src/columnmanager.js +++ b/src/columnmanager.js @@ -63,51 +63,72 @@ export default class ColumnManager { } bindDropdown() { - let $activeDropdown; - let activeClass = 'dt-dropdown--active'; let toggleClass = '.dt-dropdown__toggle'; + let dropdownClass = '.dt-dropdown__list'; - $.on(this.header, 'click', toggleClass, (e, $button) => { - const $dropdown = $.closest('.dt-dropdown', $button); + // attach the dropdown list to container + this.instance.dropdownContainer.innerHTML = this.getDropdownListHTML(); + this.$dropdownList = this.instance.dropdownContainer.firstElementChild; - if (!$dropdown.classList.contains(activeClass)) { - deactivateDropdown(); - $dropdown.classList.add(activeClass); - $activeDropdown = $dropdown; - } else { - deactivateDropdown(); - } + $.on(this.header, 'click', toggleClass, e => { + this.openDropdown(e); }); const deactivateDropdownOnBodyClick = (e) => { - const selector = [toggleClass, toggleClass + ' *'].join(','); + const selector = [ + toggleClass, toggleClass + ' *', + dropdownClass, dropdownClass + ' *' + ].join(','); if (e.target.matches(selector)) return; deactivateDropdown(); }; $.on(document.body, 'click', deactivateDropdownOnBodyClick); + document.addEventListener('scroll', deactivateDropdown, true); + this.instance.on('onDestroy', () => { $.off(document.body, 'click', deactivateDropdownOnBodyClick); + $.off(document, 'scroll', deactivateDropdown); }); - const dropdownItems = this.options.headerDropdown; - - $.on(this.header, 'click', '.dt-dropdown__list-item', (e, $item) => { - const $col = $.closest('.dt-cell', $item); - const { - index - } = $.data($item); - const { - colIndex - } = $.data($col); + $.on(this.$dropdownList, 'click', '.dt-dropdown__list-item', (e, $item) => { + if (!this._dropdownActiveColIndex) return; + const dropdownItems = this.options.headerDropdown; + const { index } = $.data($item); + const colIndex = this._dropdownActiveColIndex; let callback = dropdownItems[index].action; callback && callback.call(this.instance, this.getColumn(colIndex)); + this.hideDropdown(); }); + const _this = this; function deactivateDropdown(e) { - $activeDropdown && $activeDropdown.classList.remove(activeClass); - $activeDropdown = null; + _this.hideDropdown(); } + + this.hideDropdown(); + } + + openDropdown(e) { + if (!this._dropdownWidth) { + $.style(this.$dropdownList, { display: '' }); + this._dropdownWidth = $.style(this.$dropdownList, 'width'); + } + $.style(this.$dropdownList, { + display: '', + left: (e.clientX - this._dropdownWidth + 4) + 'px', + top: (e.clientY + 4) + 'px' + }); + const $cell = $.closest('.dt-cell', e.target); + const { colIndex } = $.data($cell); + this._dropdownActiveColIndex = colIndex; + } + + hideDropdown() { + $.style(this.$dropdownList, { + display: 'none' + }); + this._dropdownActiveColIndex = null; } bindResizeColumn() { @@ -370,17 +391,24 @@ export default class ColumnManager { } getDropdownHTML() { - const { dropdownButton, headerDropdown: dropdownItems } = this.options; + const { dropdownButton } = this.options; return `
${dropdownButton}
-
- ${dropdownItems.map((d, i) => ` -
${d.label}
- `).join('')} -
`; } + + getDropdownListHTML() { + const { headerDropdown: dropdownItems } = this.options; + + return ` +
+ ${dropdownItems.map((d, i) => ` +
${d.label}
+ `).join('')} +
+ `; + } } diff --git a/src/datatable.js b/src/datatable.js index 1862f3c..7234860 100644 --- a/src/datatable.js +++ b/src/datatable.js @@ -78,6 +78,7 @@ class DataTable {
+
`; @@ -89,6 +90,7 @@ class DataTable { this.freezeContainer = $('.dt-freeze', this.wrapper); this.toastMessage = $('.dt-toast', this.wrapper); this.pasteTarget = $('.dt-paste-target', this.wrapper); + this.dropdownContainer = $('.dt-dropdown-container', this.wrapper); } refresh(data, columns) { diff --git a/src/style.css b/src/style.css index 316f08f..ef1555d 100644 --- a/src/style.css +++ b/src/style.css @@ -191,13 +191,10 @@ } &__list { - display: none; - - position: absolute; + position: fixed; min-width: 8rem; - top: 100%; - right: 0; z-index: 1; + cursor: pointer; background-color: var(--dt-cell-bg); border-radius: var(--dt-border-radius); padding: var(--dt-spacer-2) 0;