MDL-79224 core: Make Binary datafilter redisplay selected value

The Binary datafilter was returning a single value where all parts of
the API expect an array of values. This was working in most places by
fluke as this value was a single-character string, so doing $value[0]
returned the value. However, it was not working when deciding which
option to mark as selected when re-displaying the filter.

This change makes the filter return an array containing a single integer
value to match the rest of the API, then internally selects that single
value for comparison when deciding if an option should be selected.
This commit is contained in:
Mark Johnson
2023-10-02 11:50:44 +01:00
parent 43d5aec47e
commit 6401ca4959
5 changed files with 41 additions and 9 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
define("core/datafilter/filtertypes/binary",["exports","core/datafilter/filtertype","core/datafilter/selectors","core/templates","core/str"],(function(_exports,_filtertype,_selectors,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_filtertype=_interopRequireDefault(_filtertype),_selectors=_interopRequireDefault(_selectors),_templates=_interopRequireDefault(_templates);class _default extends _filtertype.default{constructor(){super(...arguments),_defineProperty(this,"optionOne",void 0),_defineProperty(this,"optionTwo",void 0)}async addValueSelector(initialValues){return[this.optionOne,this.optionTwo]=await this.getTextValues(),this.displayBinarySelection(initialValues)}getTextValues(){return(0,_str.get_strings)([{key:"no"},{key:"yes"}])}async displayBinarySelection(){let initialValues=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const specificFilterSet=this.rootNode.querySelector(_selectors.default.filter.byName(this.filterType)),sourceDataNode=this.getSourceDataForFilter(),context={filtertype:this.filterType,title:sourceDataNode.getAttribute("data-field-title"),required:sourceDataNode.dataset.required,options:[{text:this.optionOne,value:0,selected:0===initialValues[0]},{text:this.optionTwo,value:1,selected:1===initialValues[0]}]};return _templates.default.render("core/datafilter/filtertypes/binary_selector",context).then(((binaryUi,js)=>_templates.default.replaceNodeContents(specificFilterSet.querySelector(_selectors.default.filter.regions.values),binaryUi,js)))}get values(){return this.filterRoot.querySelector('[data-filterfield="'.concat(this.name,'"]')).value}}return _exports.default=_default,_exports.default}));
define("core/datafilter/filtertypes/binary",["exports","core/datafilter/filtertype","core/datafilter/selectors","core/templates","core/str"],(function(_exports,_filtertype,_selectors,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_filtertype=_interopRequireDefault(_filtertype),_selectors=_interopRequireDefault(_selectors),_templates=_interopRequireDefault(_templates);class _default extends _filtertype.default{constructor(){super(...arguments),_defineProperty(this,"optionOne",void 0),_defineProperty(this,"optionTwo",void 0)}async addValueSelector(initialValues){return[this.optionOne,this.optionTwo]=await this.getTextValues(),this.displayBinarySelection(initialValues[0])}getTextValues(){return(0,_str.get_strings)([{key:"no"},{key:"yes"}])}async displayBinarySelection(){let initialValue=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;const specificFilterSet=this.rootNode.querySelector(_selectors.default.filter.byName(this.filterType)),sourceDataNode=this.getSourceDataForFilter(),context={filtertype:this.filterType,title:sourceDataNode.getAttribute("data-field-title"),required:sourceDataNode.dataset.required,options:[{text:this.optionOne,value:0,selected:0===initialValue},{text:this.optionTwo,value:1,selected:1===initialValue}]};return _templates.default.render("core/datafilter/filtertypes/binary_selector",context).then(((binaryUi,js)=>_templates.default.replaceNodeContents(specificFilterSet.querySelector(_selectors.default.filter.regions.values),binaryUi,js)))}get values(){return[parseInt(this.filterRoot.querySelector('[data-filterfield="'.concat(this.name,'"]')).value)]}}return _exports.default=_default,_exports.default}));
//# sourceMappingURL=binary.min.js.map
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -53,7 +53,7 @@ export default class extends Filter {
*/
async addValueSelector(initialValues) {
[this.optionOne, this.optionTwo] = await this.getTextValues();
return this.displayBinarySelection(initialValues);
return this.displayBinarySelection(initialValues[0]);
}
/**
@@ -70,9 +70,9 @@ export default class extends Filter {
/**
* Renders yes/no select input with proper selection.
*
* @param {Array} initialValues The default value for the filter.
* @param {Number} initialValue The default value for the filter.
*/
async displayBinarySelection(initialValues = []) {
async displayBinarySelection(initialValue = 0) {
// We specify a specific filterset in case there are multiple filtering condition - avoiding glitches.
const specificFilterSet = this.rootNode.querySelector(Selectors.filter.byName(this.filterType));
const sourceDataNode = this.getSourceDataForFilter();
@@ -84,12 +84,12 @@ export default class extends Filter {
{
text: this.optionOne,
value: 0,
selected: initialValues[0] === 0,
selected: initialValue === 0,
},
{
text: this.optionTwo,
value: 1,
selected: initialValues[0] === 1,
selected: initialValue === 1,
},
]
};
@@ -105,7 +105,7 @@ export default class extends Filter {
* @returns {Array}
*/
get values() {
return this.filterRoot.querySelector(`[data-filterfield="${this.name}"]`).value;
return [parseInt(this.filterRoot.querySelector(`[data-filterfield="${this.name}"]`).value)];
}
}
@@ -38,7 +38,13 @@
}}
<div class="d-flex flex-column flex-md-row align-items-md-center" data-required="{{required}}">
<label for="core-filter_row-binary-{{uniqid}}" class="sr-only">{{title}}</label>
<select class="custom-select mb-1 mb-md-0 mr-md-2" name="{{filtertype}}" data-filterfield="{{filtertype}}" id="core-filter_row-binary-{{uniqid}}">
<select {{!
}}class="custom-select mb-1 mb-md-0 mr-md-2" {{!
}}name="{{filtertype}}" {{!
}}data-filterfield="{{filtertype}}" {{!
}}data-field-title="{{title}}" {{!
}}id="core-filter_row-binary-{{uniqid}}"{{!
}}>
{{#options}}
<option{{#selected}} selected{{/selected}} value="{{value}}">{{text}}</option>
{{/options}}
@@ -38,3 +38,29 @@ Feature: The questions in the question bank can be filtered by combine various c
And I should not see "question 2 name" in the "categoryquestions" "table"
And I should not see "question 3 name" in the "categoryquestions" "table"
And I should not see "question 4 name" in the "categoryquestions" "table"
@javascript
Scenario: Filters persist when the page is reloaded
Given the following "questions" exist:
| questioncategory | qtype | name | user | questiontext | status |
| Test questions 1 | essay | hidden question name | teacher1 | Hidden text | hidden |
And the following "core_question > Tags" exist:
| question | tag |
| hidden question name | foo |
And I apply question bank filter "Category" with value "Test questions 1"
And I apply question bank filter "Tag" with value "foo"
And I apply question bank filter "Show hidden questions" with value "Yes"
And I should see "question 1 name" in the "categoryquestions" "table"
And I should see "hidden question name" in the "categoryquestions" "table"
And I should not see "question 2 name" in the "categoryquestions" "table"
And I should not see "question 3 name" in the "categoryquestions" "table"
And I should not see "question 4 name" in the "categoryquestions" "table"
When I reload the page
Then I should see "Test questions 1 (2)" in the "Filter 1" "fieldset"
And the field "Show hidden questions" matches value "Yes"
And I should see "foo" in the "Filter 3" "fieldset"
And I should see "question 1 name" in the "categoryquestions" "table"
And I should see "hidden question name" in the "categoryquestions" "table"
And I should not see "question 2 name" in the "categoryquestions" "table"
And I should not see "question 3 name" in the "categoryquestions" "table"
And I should not see "question 4 name" in the "categoryquestions" "table"