fradrive/frontend/src/utils/form/communication-recipients.js
2020-05-12 16:44:53 +02:00

89 lines
3.7 KiB
JavaScript

import { Utility } from '../../core/utility';
const MASS_INPUT_SELECTOR = '.massinput';
const RECIPIENT_CATEGORIES_SELECTOR = '.recipient-categories';
const RECIPIENT_CATEGORY_SELECTOR = '.recipient-category';
const RECIPIENT_CATEGORY_CHECKBOX_SELECTOR = '.recipient-category__checkbox';
const RECIPIENT_CATEGORY_OPTIONS_SELECTOR = '.recipient-category__options';
const RECIPIENT_CATEGORY_TOGGLE_ALL_SELECTOR = '.recipient-category__toggle-all [type="checkbox"]';
const RECIPIENT_CATEGORY_CHECKED_COUNTER_SELECTOR = '.recipient-category__checked-counter';
@Utility({
selector: RECIPIENT_CATEGORIES_SELECTOR,
})
export class CommunicationRecipients {
massInputElement;
constructor(element) {
if (!element) {
throw new Error('Communication Recipient utility cannot be setup without an element!');
}
this.massInputElement = element.closest(MASS_INPUT_SELECTOR);
this.setupRecipientCategories();
const recipientObserver = new MutationObserver(this.setupRecipientCategories.bind(this));
recipientObserver.observe(this.massInputElement, { childList: true });
}
setupRecipientCategories() {
Array.from(this.massInputElement.querySelectorAll(RECIPIENT_CATEGORY_SELECTOR)).forEach(setupRecipientCategory);
}
}
function setupRecipientCategory(recipientCategoryElement) {
const categoryCheckbox = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_CHECKBOX_SELECTOR);
const categoryOptions = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_OPTIONS_SELECTOR);
if (categoryOptions) {
const categoryCheckboxes = Array.from(categoryOptions.querySelectorAll('[type="checkbox"]'));
const toggleAllCheckbox = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_TOGGLE_ALL_SELECTOR);
// setup category checkbox to toggle all child checkboxes if changed
categoryCheckbox.addEventListener('change', () => {
categoryCheckboxes.filter(checkbox => !checkbox.disabled).forEach(checkbox => {
checkbox.checked = categoryCheckbox.checked;
});
updateCheckedCounter(recipientCategoryElement, categoryCheckboxes);
updateToggleAllCheckbox(toggleAllCheckbox, categoryCheckboxes);
});
// update counter and toggle checkbox initially
updateCheckedCounter(recipientCategoryElement, categoryCheckboxes);
updateToggleAllCheckbox(toggleAllCheckbox, categoryCheckboxes);
// register change listener for individual checkboxes
categoryCheckboxes.forEach(checkbox => {
checkbox.addEventListener('change', () => {
updateCheckedCounter(recipientCategoryElement, categoryCheckboxes);
updateToggleAllCheckbox(toggleAllCheckbox, categoryCheckboxes);
});
});
// register change listener for toggle all checkbox
if (toggleAllCheckbox) {
toggleAllCheckbox.addEventListener('change', () => {
categoryCheckboxes.filter(checkbox => !checkbox.disabled).forEach(checkbox => {
checkbox.checked = toggleAllCheckbox.checked;
});
updateCheckedCounter(recipientCategoryElement, categoryCheckboxes);
});
}
}
}
// update checked state of toggle all checkbox based on all other checkboxes
function updateToggleAllCheckbox(toggleAllCheckbox, categoryCheckboxes) {
const allChecked = categoryCheckboxes.reduce((acc, checkbox) => acc && checkbox.checked, true);
toggleAllCheckbox.checked = allChecked;
}
// update value of checked counter
function updateCheckedCounter(recipientCategoryElement, categoryCheckboxes) {
const checkedCounter = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_CHECKED_COUNTER_SELECTOR);
const checkedCheckboxes = categoryCheckboxes.reduce((acc, checkbox) => checkbox.checked ? acc + 1 : acc, 0);
checkedCounter.innerHTML = checkedCheckboxes + '/' + categoryCheckboxes.length;
}