This repository has been archived on 2024-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
fradrive-old/frontend/src/utils/check-all/check-all.js
2021-09-17 17:59:42 +02:00

171 lines
4.7 KiB
JavaScript

const DEBUG_MODE = /localhost/.test(window.location.href) ? 0 : 0;
import { Utility } from '../../core/utility';
import { TableIndices } from '../../lib/table/table';
const CHECKBOX_SELECTOR = '[type="checkbox"]';
const CHECK_ALL_INITIALIZED_CLASS = 'check-all--initialized';
@Utility({
selector: 'table:not([uw-no-check-all])',
})
export class CheckAll {
_element;
_columns = new Array();
_checkAllColumns = new Array();
_tableIndices;
_lastCheckedCell = null;
constructor(element, app) {
if (!element) {
throw new Error('Check All utility cannot be setup without an element!');
}
this._element = element;
if (this._element.classList.contains(CHECK_ALL_INITIALIZED_CLASS)) {
return false;
}
this._tableIndices = new TableIndices(this._element);
this._gatherColumns();
if (DEBUG_MODE > 0)
console.log(this._columns);
//Todo: 1 forEach loop
let checkboxColumns = this._findCheckboxColumns();
checkboxColumns.forEach(columnId => this._checkAllColumns.push(new CheckAllColumn(this._element, app, this._columns[columnId])));
checkboxColumns.forEach(columnId => {
let currentColumn = this._columns[columnId];
currentColumn.forEach(el => el.addEventListener('click', (ev) => {
if(ev.shiftKey && this.lastCheckedCell !== null) {
let lastClickedIndex = this._tableIndices.rowIndex(this._lastCheckedCell);
let currentCellIndex = this._tableIndices.rowIndex(el);
if(currentCellIndex > lastClickedIndex)
this._checkMultipleCells(lastClickedIndex, currentCellIndex, columnId);
else
this._checkMultipleCells(currentCellIndex, lastClickedIndex, columnId);
} else {
this._lastCheckedCell = el;
}
}));
});
// mark initialized
this._element.classList.add(CHECK_ALL_INITIALIZED_CLASS);
}
_checkMultipleCells(firstRowIndex, lastRowIndex, columnId) {
for(let i=firstRowIndex; i<=lastRowIndex; i++) {
let cell = this._columns[columnId][i];
if (cell.tagName !== 'TH') {
cell.querySelector(CHECKBOX_SELECTOR).checked = true;
}
}
}
_gatherColumns() {
for (const rowIndex of Array(this._tableIndices.maxRow + 1).keys()) {
for (const colIndex of Array(this._tableIndices.maxCol + 1).keys()) {
if (DEBUG_MODE > 1)
console.log(rowIndex, colIndex);
const cell = this._tableIndices.getCell(rowIndex, colIndex);
if (!cell)
continue;
if (!this._columns[colIndex])
this._columns[colIndex] = new Array();
this._columns[colIndex][rowIndex] = cell;
}
}
}
_findCheckboxColumns() {
let checkboxColumnIds = new Array();
this._columns.forEach((col, i) => {
if (this._isCheckboxColumn(col)) {
checkboxColumnIds.push(i);
}
});
return checkboxColumnIds;
}
_isCheckboxColumn(col) {
return col.every(cell => cell.tagName == 'TH' || cell.querySelector(CHECKBOX_SELECTOR))
&& col.some(cell => cell.querySelector(CHECKBOX_SELECTOR));
}
}
class CheckAllColumn {
_app;
_table;
_column;
_checkAllCheckbox;
_checkboxId = 'check-all-checkbox-' + Math.floor(Math.random() * 100000);
constructor(table, app, column) {
this._column = column;
this._table = table;
this._app = app;
const th = this._column.filter(element => element.tagName == 'TH')[0];
if (!th)
return false;
this._checkAllCheckbox = document.createElement('input');
this._checkAllCheckbox.setAttribute('type', 'checkbox');
this._checkAllCheckbox.setAttribute('id', this._checkboxId);
th.insertBefore(this._checkAllCheckbox, th.firstChild);
// set up new checkbox
this._app.utilRegistry.initAll(th);
this._checkAllCheckbox.addEventListener('input', this._onCheckAllCheckboxInput.bind(this));
this._setupCheckboxListeners();
}
_onCheckAllCheckboxInput() {
this._toggleAll(this._checkAllCheckbox.checked);
}
_setupCheckboxListeners() {
this._column
.flatMap(cell => cell.tagName == 'TH' ? new Array() : Array.from(cell.querySelectorAll(CHECKBOX_SELECTOR)))
.forEach(checkbox =>
checkbox.addEventListener('input', this._updateCheckAllCheckboxState.bind(this))
);
}
_updateCheckAllCheckboxState() {
const allChecked = this._column.every(cell =>
cell.tagName == 'TH' || cell.querySelector(CHECKBOX_SELECTOR).checked
);
this._checkAllCheckbox.checked = allChecked;
}
_toggleAll(checked) {
this._column.forEach(cell => {
if (cell.tagName == 'TH')
return;
cell.querySelector(CHECKBOX_SELECTOR).checked = checked;
});
}
}