add toggle all checkbox and checked counter to recipientLayout

This commit is contained in:
Felix Hamann 2019-04-25 15:18:29 +02:00
parent 8fd16c3545
commit 016566d06e
4 changed files with 90 additions and 16 deletions

View File

@ -775,6 +775,7 @@ CommSuccess n@Int: Nachricht wurde an #{tshow n} Empfänger versandt
CommCourseHeading: Kursmitteilung CommCourseHeading: Kursmitteilung
RecipientCustom: Weitere Empfänger RecipientCustom: Weitere Empfänger
RecipientToggleAll: Alle/Keine
RGCourseParticipants: Kursteilnehmer RGCourseParticipants: Kursteilnehmer
RGCourseLecturers: Kursverwalter RGCourseLecturers: Kursverwalter

View File

@ -3,18 +3,20 @@ $if not (null activeCategories)
<div .recipient-categories> <div .recipient-categories>
$forall category <- activeCategories $forall category <- activeCategories
<div .recipient-category> <div .recipient-category>
<input type=checkbox id=#{checkedIdent category} :elem category checkedCategories:checked> <input type=checkbox id=#{checkedIdent category} .recipient-category__checkbox :elem category checkedCategories:checked>
<label .recipient-category__label for=#{checkedIdent category}> <label .recipient-category__label for=#{checkedIdent category}>
_{category} _{category}
$if hasContent category $if hasContent category
<fieldset .recipient-category__fieldset uw-interactive-fieldset .interactive-fieldset__target data-conditional-input=#{checkedIdent category}> <fieldset .recipient-category__fieldset uw-interactive-fieldset .interactive-fieldset__target data-conditional-input=#{checkedIdent category}>
$if not (null (categoryIndices category)) $if not (null (categoryIndices category))
$# TODO: unique id for this all/none checkbox <div .recipient-category__checked-counter>
<input type=checkbox id=tbd .recipient-category__toggle-all> <div .recipient-category__toggle-all>
<label for=tbd>Label <input type=checkbox id=#{checkedIdent category}-toggle-all>
$forall optIx <- categoryIndices category <label for=#{checkedIdent category}-toggle-all .recipient-category__option-label>_{MsgRecipientToggleAll}
^{cellWdgts ! optIx} <div .recipient-category__options>
$forall optIx <- categoryIndices category
^{cellWdgts ! optIx}
$maybe addWdgt <- addWdgts !? (1, (EnumPosition category, 0)) $maybe addWdgt <- addWdgts !? (1, (EnumPosition category, 0))
^{addWdgt} ^{addWdgt}

View File

@ -1,34 +1,87 @@
// TODO: js utility to check all/none of the checkboxes in a recipient category at once
(function() { (function() {
var MASS_INPUT_SELECTOR = '.massinput';
var RECIPIENT_CATEGORIES_SELECTOR = '.recipient-categories'; var RECIPIENT_CATEGORIES_SELECTOR = '.recipient-categories';
var RECIPIENT_CATEGORY_SELECTOR = '.recipient-category'; var RECIPIENT_CATEGORY_SELECTOR = '.recipient-category';
var RECIPIENT_CATEGORY_FIELDSET_SELECTOR = '.recipient-category__fieldset'; var RECIPIENT_CATEGORY_CHECKBOX_SELECTOR = '.recipient-category__checkbox ';
var RECIPIENT_CATEGORY_TOGGLE_ALL_SELECTOR = '.recipient-category__toggle-all'; var RECIPIENT_CATEGORY_OPTIONS_SELECTOR = '.recipient-category__options';
var RECIPIENT_CATEGORY_TOGGLE_ALL_SELECTOR = '.recipient-category__toggle-all [type="checkbox"]';
var RECIPIENT_CATEGORY_CHECKED_COUNTER_SELECTOR = '.recipient-category__checked-counter';
var massInputElement;
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
var recipientCategoriesElement = document.querySelector(RECIPIENT_CATEGORIES_SELECTOR); var recipientCategoriesElement = document.querySelector(RECIPIENT_CATEGORIES_SELECTOR);
var recipientCategoryElements = Array.from(recipientCategoriesElement.querySelectorAll(RECIPIENT_CATEGORY_SELECTOR)); massInputElement = recipientCategoriesElement.closest(MASS_INPUT_SELECTOR);
setupRecipientCategories();
var recipientObserver = new MutationObserver(setupRecipientCategories);
recipientObserver.observe(massInputElement, { childList: true });
});
function setupRecipientCategories() {
var recipientCategoryElements = Array.from(massInputElement.querySelectorAll(RECIPIENT_CATEGORY_SELECTOR));
recipientCategoryElements.forEach(function(element) { recipientCategoryElements.forEach(function(element) {
setupRecipientCategory(element); setupRecipientCategory(element);
}); });
}); }
function setupRecipientCategory(recipientCategoryElement) { function setupRecipientCategory(recipientCategoryElement) {
var fieldset = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_FIELDSET_SELECTOR); var categoryCheckbox = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_CHECKBOX_SELECTOR);
var categoryCheckboxes = Array.from(fieldset.querySelectorAll('[type="checkbox"]')); var categoryOptions = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_OPTIONS_SELECTOR);
if (categoryOptions) {
if (categoryCheckboxes) { var categoryCheckboxes = Array.from(categoryOptions.querySelectorAll('[type="checkbox"]'));
var toggleAllCheckbox = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_TOGGLE_ALL_SELECTOR); var toggleAllCheckbox = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_TOGGLE_ALL_SELECTOR);
// setup category checkbox to toggle all child checkboxes if changed
categoryCheckbox.addEventListener('change', function() {
categoryCheckboxes.forEach(function(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(function(checkbox) {
checkbox.addEventListener('change', function() {
updateCheckedCounter(recipientCategoryElement, categoryCheckboxes);
updateToggleAllCheckbox(toggleAllCheckbox, categoryCheckboxes);
});
});
// register change listener for toggle all checkbox
if (toggleAllCheckbox) { if (toggleAllCheckbox) {
toggleAllCheckbox.addEventListener('change', function() { toggleAllCheckbox.addEventListener('change', function() {
console.log('TBD: setting up toggle all checkbox'); categoryCheckboxes.forEach(function(checkbox) {
checkbox.checked = toggleAllCheckbox.checked;
});
updateCheckedCounter(recipientCategoryElement, categoryCheckboxes);
}); });
} }
} }
} }
// update checked state of toggle all checkbox based on all other checkboxes
function updateToggleAllCheckbox(toggleAllCheckbox, categoryCheckboxes) {
var allChecked = categoryCheckboxes.reduce(function(acc, checkbox) {
return acc && checkbox.checked;
}, true);
toggleAllCheckbox.checked = allChecked;
}
// update value of checked counter
function updateCheckedCounter(recipientCategoryElement, categoryCheckboxes) {
var checkedCounter = recipientCategoryElement.querySelector(RECIPIENT_CATEGORY_CHECKED_COUNTER_SELECTOR);
var checkedCheckboxes = categoryCheckboxes.reduce(function(acc, checkbox) { return checkbox.checked ? acc + 1 : acc; }, 0);
checkedCounter.innerHTML = checkedCheckboxes + '/' + categoryCheckboxes.length;
}
})(); })();

View File

@ -32,6 +32,7 @@
padding-left: 16px; padding-left: 16px;
max-height: 200px; max-height: 200px;
overflow-y: auto; overflow-y: auto;
position: relative;
} }
.recipient-category__option-add { .recipient-category__option-add {
@ -42,3 +43,20 @@
padding: 10px 0; padding: 10px 0;
} }
} }
.recipient-category__options + .recipient-category__option-add {
margin-top: 10px;
}
.recipient-category__toggle-all {
display: flex;
border-bottom: 1px solid #bcbcbc;
padding-bottom: 8px;
margin-bottom: 8px;
}
.recipient-category__checked-counter {
position: absolute;
right: 0;
top: 0;
}