MDL-72321 core: Allow datafilters to specify a subset of join types

A datafilter can now specify a subset of jointypes that it supports from
the default list of all, any or none. By default all options will be
available, but an individual filter can ovveride this to include just
those options that make sense for the filter. If only one option is
allowed, the select list will be hidden to simplify the UI.
This commit is contained in:
Mark Johnson
2023-08-31 15:00:37 +01:00
parent ef8c11328b
commit 7091a3210c
7 changed files with 59 additions and 3 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+41
View File
@@ -200,6 +200,13 @@ export default class {
const typeField = filterRow.querySelector(Selectors.filter.fields.type);
typeField.value = filterType;
typeField.disabled = 'disabled';
// Update the join list.
this.updateJoinList(JSON.parse(filterDataNode.dataset.joinList), filterRow);
const joinField = filterRow.querySelector(Selectors.filter.fields.join);
joinField.disabled = false;
if (!isNaN(filterJoin)) {
joinField.value = filterJoin;
}
// Update the list of available filter types.
this.updateFiltersOptions();
@@ -448,4 +455,38 @@ export default class {
return legendStrings;
}
/**
* Update the list of join types for a filter.
*
* This will update the list of join types based on the allowed types defined for a filter.
* If only one type is allowed, the list will be hidden.
*
* @param {Array} filterJoinList Array of join types, a subset of the regularJoinList array in this function.
* @param {Element} filterRow The row being updated.
*/
updateJoinList(filterJoinList, filterRow) {
const regularJoinList = [0, 1, 2];
// If a join list was specified for this filter, find the default join list and disable the options that are not allowed
// for this filter.
if (filterJoinList.length !== 0) {
const joinField = filterRow.querySelector(Selectors.filter.fields.join);
// Check each option from the default list, and disable the option in this filter row if it is not allowed
// for this filter.
regularJoinList.forEach((join) => {
if (!filterJoinList.includes(join)) {
joinField.options[join].classList.add('hidden');
joinField.options[join].disabled = true;
}
});
// Now remove the disabled options, and hide the select list of there is only one option left.
joinField.options.forEach((element, index) => {
if (element.disabled) {
joinField.options[index] = null;
}
});
if (joinField.options.length === 1) {
joinField.hidden = true;
}
}
}
}
+11
View File
@@ -31,6 +31,15 @@ use templatable;
*/
abstract class datafilter implements renderable, templatable {
/** @var int None of the following match */
public const JOINTYPE_NONE = 0;
/** @var int Any of the following match */
public const JOINTYPE_ANY = 1;
/** @var int All of the following match */
public const JOINTYPE_ALL = 2;
/** @var context $context The context where the filters are being rendered. */
protected $context;
@@ -84,6 +93,7 @@ abstract class datafilter implements renderable, templatable {
bool $allowempty = false,
?stdClass $filteroptions = null,
bool $required = false,
array $joinlist = [self::JOINTYPE_NONE, self::JOINTYPE_ANY, self::JOINTYPE_ALL]
): ?stdClass {
if (!$allowempty && empty($values)) {
@@ -100,6 +110,7 @@ abstract class datafilter implements renderable, templatable {
'values' => $values,
'filteroptions' => $filteroptions,
'required' => $required,
'joinlist' => json_encode($joinlist)
];
}
}
+1 -1
View File
@@ -39,7 +39,7 @@
<div class="border-radius my-2 p-2 bg-white border d-flex flex-column flex-md-row align-items-md-start mr-0 ml-0 row">
<div class="d-flex flex-column flex-md-row align-items-md-center my-1">
<label for="core-filter_row-jointype-{{uniqid}}" class="mr-md-2 mb-md-0">{{#str}}match{{/str}}</label>
<select class="custom-select mb-1 mb-md-0 mr-md-2" data-filterfield="join" id="core-filter_row-jointype-{{uniqid}}">
<select class="custom-select mb-1 mb-md-0 mr-md-2" data-filterfield="join" id="core-filter_row-jointype-{{uniqid}}" disabled>
<option value="0">{{#str}}none{{/str}}</option>
<option selected=selected value="1">{{#str}}any{{/str}}</option>
<option value="2">{{#str}}all{{/str}}</option>
@@ -53,6 +53,7 @@
}}data-field-title="{{title}}" {{!
}}data-allow-custom="{{allowcustom}}" {{!
}}data-required="{{required}}" {{!
}}data-join-list="{{joinlist}}" {{!
}}class="hidden" {{!
}}{{#filtertypeclass}}data-filter-type-class="{{filtertypeclass}}" {{/filtertypeclass}}{{!
}}>
+3
View File
@@ -95,6 +95,9 @@ being forced open in all behat tests.
the list of filters.
* addFilterRow() in core/datafilter now accepts a filterdata object to add a row with a pre-defined filter.
* New "binary" datafilter type added for creating filters with a single yes/no option.
* New "joinlist" parameter added to core\output\datafilter::get_filter_object(). This takes an array of datafilter::JOINTYPE_*
constants to define which types of join the filter supports. By default this will include all three of "Any", "All" and "None",
but a subset can be specified instead.
=== 4.2 ===