forked from a64f7bb4-7358-4778-9fbe-3b882c34cc1d/v1
129 lines
3.6 KiB
JavaScript
129 lines
3.6 KiB
JavaScript
((Drupal, once) => {
|
|
Drupal.behaviors.tableSelect = {
|
|
attach: (context) => {
|
|
once('tableSelect', 'th.select-all', context).forEach((el) => {
|
|
if (el.closest('table')) {
|
|
Drupal.tableSelect(el.closest('table'));
|
|
}
|
|
});
|
|
},
|
|
};
|
|
|
|
Drupal.tableSelect = (table) => {
|
|
if (table.querySelector('td input[type="checkbox"]') === null) {
|
|
return;
|
|
}
|
|
|
|
let checkboxes = 0;
|
|
let lastChecked = 0;
|
|
const strings = {
|
|
selectAll: Drupal.t('Select all rows in this table'),
|
|
selectNone: Drupal.t('Deselect all rows in this table')
|
|
};
|
|
const updateSelectAll = (state) => {
|
|
table
|
|
.querySelectorAll('th.select-all input[type="checkbox"]')
|
|
.forEach(checkbox => {
|
|
const stateChanged = checkbox.checked !== state;
|
|
checkbox.setAttribute(
|
|
'title',
|
|
state ? strings.selectNone : strings.selectAll
|
|
);
|
|
|
|
if (stateChanged) {
|
|
checkbox.checked = state;
|
|
checkbox.dispatchEvent(new Event('change'));
|
|
}
|
|
});
|
|
};
|
|
|
|
const setClass = 'is-sticky';
|
|
const stickyHeader = table
|
|
.closest('form')
|
|
.querySelector('[data-drupal-selector*="edit-header"]');
|
|
|
|
const updateSticky = (state) => {
|
|
if (stickyHeader) {
|
|
if (state === true) {
|
|
stickyHeader.classList.add(setClass);
|
|
}
|
|
else {
|
|
stickyHeader.classList.remove(setClass);
|
|
}
|
|
}
|
|
};
|
|
|
|
const checkedCheckboxes = (checkboxes) => {
|
|
const checkedCheckboxes = Array.from(checkboxes).filter(checkbox => checkbox.matches(':checked'));
|
|
updateSelectAll(checkboxes.length === checkedCheckboxes.length);
|
|
updateSticky(!!checkedCheckboxes.length);
|
|
};
|
|
|
|
table.querySelectorAll('th.select-all').forEach(el => {
|
|
el.innerHTML = Drupal.theme('checkbox') + el.innerHTML;
|
|
el.querySelector('.form-checkbox').setAttribute('title', strings.selectAll);
|
|
el.addEventListener('click', event => {
|
|
if (event.target.matches('input[type="checkbox"]')) {
|
|
checkboxes.forEach(checkbox => {
|
|
const stateChanged = checkbox.checked !== event.target.checked;
|
|
|
|
if (stateChanged) {
|
|
checkbox.checked = event.target.checked;
|
|
checkbox.dispatchEvent(new Event('change'));
|
|
}
|
|
|
|
checkbox.closest('tr').classList.toggle('selected', checkbox.checked);
|
|
});
|
|
|
|
updateSelectAll(event.target.checked);
|
|
updateSticky(event.target.checked);
|
|
}
|
|
});
|
|
});
|
|
|
|
checkboxes = table.querySelectorAll('td input[type="checkbox"]:enabled');
|
|
checkboxes.forEach(el => {
|
|
el.addEventListener('click', e => {
|
|
e.target
|
|
.closest('tr')
|
|
.classList.toggle('selected', this.checked);
|
|
|
|
if (e.shiftKey && lastChecked && lastChecked !== e.target) {
|
|
Drupal.tableSelectRange(
|
|
e.target.closest('tr'),
|
|
lastChecked.closest('tr'),
|
|
e.target.checked
|
|
);
|
|
}
|
|
|
|
checkedCheckboxes(checkboxes);
|
|
lastChecked = e.target;
|
|
});
|
|
});
|
|
|
|
checkedCheckboxes(checkboxes);
|
|
};
|
|
|
|
Drupal.tableSelectRange = function (from, to, state) {
|
|
const mode = from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling';
|
|
|
|
for (let i = from[mode]; i; i = i[mode]) {
|
|
if (i.nodeType !== 1) {
|
|
continue;
|
|
}
|
|
|
|
i.classList.toggle('selected', state);
|
|
i.querySelector('input[type="checkbox"]').checked = state;
|
|
|
|
if (to.nodeType) {
|
|
if (i === to) {
|
|
break;
|
|
}
|
|
} else if ([i].filter(y => y === to).length) {
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
})(Drupal, once);
|