1
0
mirror of https://github.com/moodle/moodle.git synced 2025-05-12 03:05:42 +02:00

MDL-66890 forumreport_summary: Added the ability to close filters

Previously, filters could only be closed by saving/submitting them.
Now, you are able to close and reopen them by opening another filter,
using the escape key, or clicking outside of the filter.
As per UX recommendations, filters retain any changes until the page
is reloaded (either via refresh or by saving a different filter).
This commit is contained in:
Michael Hawkins 2019-10-22 11:37:53 +08:00
parent 01aa126848
commit b2aa354d30
5 changed files with 84 additions and 30 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -28,6 +28,7 @@ import CustomEvents from 'core/custom_interaction_events';
import Selectors from 'forumreport_summary/selectors';
import Y from 'core/yui';
import Ajax from 'core/ajax';
import KeyCodes from 'core/key_codes';
export const init = (root) => {
let jqRoot = $(root);
@ -73,6 +74,11 @@ export const init = (root) => {
// Submit report via filter
const submitWithFilter = (containerelement) => {
// Disable the dates filter mform checker to prevent any changes triggering a warning to the user.
Y.use('moodle-core-formchangechecker', function() {
M.core_formchangechecker.reset_form_dirty_state();
});
// Close the container (eg popover).
$(containerelement).addClass('hidden');
@ -89,14 +95,14 @@ export const init = (root) => {
new Popper(referenceElement, popperContent, {placement: 'bottom'});
};
// Call when opening filter to ensure only one can be activated.
const canOpenFilter = (event) => {
if (document.querySelector('[data-openfilter="true"]')) {
return false;
}
// Close the relevant filter.
var closeOpenFilters = (openFilterButton, openFilter) => {
openFilter.classList.add('hidden');
openFilter.setAttribute('data-openfilter', 'false');
event.target.setAttribute('data-openfilter', "true");
return true;
openFilterButton.classList.add('btn-primary');
openFilterButton.classList.remove('btn-outline-primary');
openFilterButton.setAttribute('aria-expanded', false);
};
// Groups filter specific handlers.
@ -119,11 +125,7 @@ export const init = (root) => {
});
// Event handler for showing groups filter popover.
jqRoot.on(CustomEvents.events.activate, Selectors.filters.group.trigger, function(event) {
if (!canOpenFilter(event)) {
return false;
}
jqRoot.on(CustomEvents.events.activate, Selectors.filters.group.trigger, function() {
// Create popover.
let referenceElement = root.querySelector(Selectors.filters.group.trigger),
popperContent = root.querySelector(Selectors.filters.group.popover);
@ -132,6 +134,7 @@ export const init = (root) => {
// Show popover.
popperContent.classList.remove('hidden');
popperContent.setAttribute('data-openfilter', 'true');
// Change to outlined button.
referenceElement.classList.add('btn-outline-primary');
@ -139,21 +142,48 @@ export const init = (root) => {
// Let screen readers know that it's now expanded.
referenceElement.setAttribute('aria-expanded', true);
return true;
// Add listeners to handle closing filter.
const closeListener = e => {
if (e.target.id !== referenceElement.id && popperContent !== e.target.closest('[data-openfilter="true"]')) {
closeOpenFilters(referenceElement, popperContent);
document.removeEventListener('click', closeListener);
document.removeEventListener('keyup', escCloseListener);
}
};
document.addEventListener('click', closeListener);
const escCloseListener = e => {
if (e.keyCode === KeyCodes.escape) {
closeOpenFilters(referenceElement, popperContent);
document.removeEventListener('keyup', escCloseListener);
document.removeEventListener('click', closeListener);
}
};
document.addEventListener('keyup', escCloseListener);
});
// Event handler to click save groups filter.
jqRoot.on(CustomEvents.events.activate, Selectors.filters.group.save, function() {
// Copy the saved values into the form before submitting.
let popcheckboxes = root.querySelectorAll(Selectors.filters.group.checkbox);
popcheckboxes.forEach(function(popcheckbox) {
let filtersform = document.forms.filtersform,
saveid = popcheckbox.getAttribute('data-saveid');
filtersform.querySelector(`#${saveid}`).checked = popcheckbox.checked;
});
submitWithFilter('#filter-groups-popover');
});
// Dates filter specific handlers.
// Event handler for showing dates filter popover.
jqRoot.on(CustomEvents.events.activate, Selectors.filters.date.trigger, function(event) {
if (!canOpenFilter(event)) {
return false;
}
jqRoot.on(CustomEvents.events.activate, Selectors.filters.date.trigger, function() {
// Create popover.
let referenceElement = root.querySelector(Selectors.filters.date.trigger),
@ -163,6 +193,7 @@ export const init = (root) => {
// Show popover and move focus.
popperContent.classList.remove('hidden');
popperContent.setAttribute('data-openfilter', 'true');
popperContent.querySelector('[name="filterdatefrompopover[enabled]"]').focus();
// Change to outlined button.
@ -171,7 +202,27 @@ export const init = (root) => {
// Let screen readers know that it's now expanded.
referenceElement.setAttribute('aria-expanded', true);
return true;
// Add listener to handle closing filter.
const closeListener = e => {
if (e.target.id !== referenceElement.id && popperContent !== e.target.closest('[data-openfilter="true"]')) {
closeOpenFilters(referenceElement, popperContent);
document.removeEventListener('click', closeListener);
document.removeEventListener('keyup', escCloseListener);
}
};
document.addEventListener('click', closeListener);
const escCloseListener = e => {
if (e.keyCode === KeyCodes.escape) {
closeOpenFilters(referenceElement, popperContent);
document.removeEventListener('keyup', escCloseListener);
document.removeEventListener('click', closeListener);
}
};
document.addEventListener('keyup', escCloseListener);
});
// Event handler to save dates filter.
@ -182,11 +233,6 @@ export const init = (root) => {
const fromEnabled = datesPopover.querySelector('[name="filterdatefrompopover[enabled]"]').checked ? 1 : 0;
const toEnabled = datesPopover.querySelector('[name="filterdatetopopover[enabled]"]').checked ? 1 : 0;
// Disable the mform checker to prevent unsubmitted form warning to the user when closing the popover.
Y.use('moodle-core-formchangechecker', function() {
M.core_formchangechecker.reset_form_dirty_state();
});
if (!fromEnabled && !toEnabled) {
// Update the elements in the filter form.
filtersForm.elements['datefrom[timestamp]'].value = 0;

@ -25,7 +25,7 @@
}
}}
<div id="filter-dates-popover" class="popover filter-dates-popover mt-3 hidden">
<div id="filter-dates-popover" class="popover filter-dates-popover mt-3 hidden" data-openfilter="false">
<h3 class="popover-header">{{# str}} filter:datesname, forumreport_summary {{/ str}}</h3>
<div class="popover-body" data-region="filter-dates">
{{{filterdatesform}}}

@ -44,15 +44,23 @@
{{filtergroupsname}}
</button>
{{! Groups filter values to submit }}
<div class="hidden">
{{#filtergroups}}
<input id="filtergroups{{groupid}}" class="form-check-input" type="checkbox" name="filtergroups[]"
value="{{groupid}}" {{#checked}} checked="checked" {{/checked}}>
{{/filtergroups}}
</div>
{{! Groups filter popover }}
<div id="filter-groups-popover" class="popover m-t-1 hidden">
<div id="filter-groups-popover" class="popover m-t-1 hidden" data-openfilter="false">
<h3 class="popover-header">{{# str}} filter:groupsname, forumreport_summary {{/ str}}</h3>
<div class="popover-body" data-region="filter-groups">
<div class="form-check filter-scrollable">
{{#filtergroups}}
<input id="filtergroups{{groupid}}" class="form-check-input" type="checkbox" name="filtergroups[]"
value="{{groupid}}" {{#checked}} checked="checked" {{/checked}}>
<label class="form-check-label pt-1" for="filtergroups{{groupid}}">{{groupname}}</label>
<input id="popperfiltergroups{{groupid}}" class="form-check-input" type="checkbox" name="popperfiltergroups[]"
data-saveid="filtergroups{{groupid}}" value="{{groupid}}" {{#checked}} checked="checked" {{/checked}}>
<label class="form-check-label pt-1" for="popperfiltergroups{{groupid}}">{{groupname}}</label>
<br>
{{/filtergroups}}
</div>