feat(hide-columns): first stub of hide-column util with manual styling

This commit is contained in:
Sarah Vaupel 2019-11-26 16:49:15 +01:00 committed by Gregor Kleen
parent 1023240136
commit 111821dcad
2 changed files with 151 additions and 0 deletions

View File

@ -0,0 +1,149 @@
import { Utility } from '../../core/utility';
import { StorageManager } from '../../lib/storage-manager/storage-manager';
const HIDE_COLUMNS_CONTAINER_IDENT = 'uw-hide-columns';
const TABLE_HEADER_IDENT = 'hide-column-header';
const TABLE_UTILS_ATTR = 'table-utils';
const TABLE_UTILS_CONTAINER_SELECTOR = `[${TABLE_UTILS_ATTR}]`;
const HIDER_TEXT_ATTR = 'header-text';
const HIDE_BUTTON_FADE_DELAY = 3000;
@Utility({
selector: `[${HIDE_COLUMNS_CONTAINER_IDENT}] table`,
})
export class HideColumns {
_storageManager = new StorageManager('uw-hide-columns');
_element;
_tableUtilContainer;
constructor(element) {
if (!element) {
throw new Error('Hide Columns utility cannot be setup without an element!');
}
// do not provide hide-column ability in tables inside modals or async forms with response
if (element.closest('[uw-modal], .async-form__response')) {
return false;
}
this._element = element;
const hideColumnsContainer = this._element.closest(`[${HIDE_COLUMNS_CONTAINER_IDENT}]`);
if (!hideColumnsContainer) {
throw new Error('Hide Columns utility needs to be setup on a table inside a hide columns container!');
}
// get or create table utils container
this._tableUtilContainer = hideColumnsContainer.querySelector(TABLE_UTILS_CONTAINER_SELECTOR);
if (!this._tableUtilContainer) {
this._tableUtilContainer = document.createElement('div');
this._tableUtilContainer.setAttribute(TABLE_UTILS_ATTR, '');
const tableContainer = this._element.closest(`[${HIDE_COLUMNS_CONTAINER_IDENT}] > *`);
hideColumnsContainer.insertBefore(this._tableUtilContainer, tableContainer);
}
this._element.querySelectorAll('th').forEach(th => {
const storageKey = this.getStorageKey(th);
const previouslyHidden = this._storageManager.load(storageKey);
this.setupHideButton(th, previouslyHidden);
});
}
setupHideButton(th, prevHidden) {
console.log('setupHideButton', th, prevHidden);
const hider = document.createElement('button');
hider.setAttribute(HIDER_TEXT_ATTR, th.innerText);
hider.addEventListener('click', (event) => {
console.log('click', th.cellIndex, hider, th.innerText);
event.preventDefault();
this.toggleColumnVisibility(th, hider);
});
// TODO fade in / fade out animation in css
th.addEventListener('mouseover', () => {
hider.style.display = '';
});
th.addEventListener('mouseout', () => {
setTimeout(() => {
if (hider.style.position === 'absolute') hider.style.display = 'none';
}, HIDE_BUTTON_FADE_DELAY);
});
this.updateColumnDisplay(th.cellIndex, prevHidden);
this.updateHider(hider, prevHidden);
this._tableUtilContainer.appendChild(hider);
}
// TODO better name
toggleColumnVisibility(th, hider) {
const storageKey = this.getStorageKey(th);
const hidden = !this._storageManager.load(storageKey);
// hide/unhide column
this.updateColumnDisplay(th.cellIndex, hidden);
// tweak hider button
this.updateHider(hider, hidden);
// persist new hidden setting for column
this._storageManager.save(storageKey, hidden);
}
// TODO better name
updateColumnDisplay(columnIndex, hidden) {
this._element.getElementsByTagName('tr').forEach(row => {
if (row.cells[columnIndex]) {
row.cells[columnIndex].style.display = hidden ? 'none' : '';
}
});
}
// TODO better name
updateHider(hider, hidden) {
// TODO set css classes instead
if (hidden) {
hider.innerHTML = hider.getAttribute(HIDER_TEXT_ATTR);
hider.style.position = 'relative';
} else {
hider.innerHTML = 'hide';
hider.style.position = 'absolute';
hider.style.display = 'none';
}
}
getStorageKey(th) {
// get handler name
const handlerIdent = document.querySelector('[uw-handler]').getAttribute('uw-handler');
// get hide-columns container ident (if not present, use table index in document as fallback)
let tIdent = th.getAttribute(TABLE_HEADER_IDENT);
if (!tIdent) {
const tablesInDocument = document.getElementsByTagName('TABLE');
for (let i = 0; i < tablesInDocument.length; i++) {
if (tablesInDocument[i] === this._element) {
tIdent = i;
break;
}
}
}
// check for unique table header ident from backend (if not present, use cell index as fallback)
let thIdent = th.getAttribute(TABLE_HEADER_IDENT);
if (!thIdent) {
thIdent = th.cellIndex;
}
return `${handlerIdent}-${tIdent}-${thIdent}`;
}
}

View File

@ -11,6 +11,7 @@ import { Modal } from './modal/modal';
import { Tooltip } from './tooltips/tooltips';
import { CourseTeaser } from './course-teaser/course-teaser';
import { NavbarUtils } from './navbar/navbar';
import { HideColumns } from './hide-columns/hide-columns';
export const Utils = [
Alerts,
@ -27,4 +28,5 @@ export const Utils = [
Tooltip,
CourseTeaser,
...NavbarUtils,
HideColumns,
];