mirror of
https://github.com/moodle/moodle.git
synced 2025-03-13 20:26:32 +01:00
MDL-70032 qtype_multichoice: Fix answer labelling
* Discard the use of the label element in order to be able to render multiple choice answers as they are and have these act as the radio button/checkbox' label through the aria-labelledby attribute. * New JS module qtype_multichoice/answers that listens for click events on the answer text container and selects the appropriate answer radio button/checkbox.
This commit is contained in:
parent
99680d1be4
commit
a1d81dc6d9
2
question/type/multichoice/amd/build/answers.min.js
vendored
Normal file
2
question/type/multichoice/amd/build/answers.min.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
define ("qtype_multichoice/answers",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b={ANSWER_LABEL:"[data-region=answer-label]"};a.default={init:function init(a){var c=document.getElementById(a),d=c.querySelectorAll(b.ANSWER_LABEL);d.forEach(function(a){a.addEventListener("click",function(a){var b=a.currentTarget.id,d=c.querySelector("[aria-labelledby=\"".concat(b,"\"]"));d.click()})})}};return a.default});
|
||||
//# sourceMappingURL=answers.min.js.map
|
1
question/type/multichoice/amd/build/answers.min.js.map
Normal file
1
question/type/multichoice/amd/build/answers.min.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../src/answers.js"],"names":["SELECTORS","ANSWER_LABEL","init","rootId","root","document","getElementById","answerLabels","querySelectorAll","forEach","answerLabel","addEventListener","e","labelId","currentTarget","id","linkedOption","querySelector","click"],"mappings":"8IA6BMA,CAAAA,CAAS,CAAG,CACdC,YAAY,CAAE,4BADA,C,WAyBH,CACXC,IAAI,CAjBK,QAAPA,CAAAA,IAAO,CAACC,CAAD,CAAY,IACfC,CAAAA,CAAI,CAAGC,QAAQ,CAACC,cAAT,CAAwBH,CAAxB,CADQ,CAIfI,CAAY,CAAGH,CAAI,CAACI,gBAAL,CAAsBR,CAAS,CAACC,YAAhC,CAJA,CAKrBM,CAAY,CAACE,OAAb,CAAqB,SAACC,CAAD,CAAiB,CAClCA,CAAW,CAACC,gBAAZ,CAA6B,OAA7B,CAAsC,SAACC,CAAD,CAAO,IACnCC,CAAAA,CAAO,CAAGD,CAAC,CAACE,aAAF,CAAgBC,EADS,CAGnCC,CAAY,CAAGZ,CAAI,CAACa,aAAL,8BAAwCJ,CAAxC,QAHoB,CAKzCG,CAAY,CAACE,KAAb,EACH,CAND,CAOH,CARD,CASH,CAEc,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Handles events related to the multiple-choice question type answers.\n *\n * @module qtype_multichoice/answers\n * @package qtype_multichoice\n * @copyright 2020 Jun Pataleta <jun@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Selectors for this module.\n *\n * @type {{ANSWER_LABEL: string}}\n */\nconst SELECTORS = {\n ANSWER_LABEL: '[data-region=answer-label]',\n};\n\n/**\n * Init method.\n *\n * @param {string} rootId The ID of the question container.\n */\nconst init = (rootId) => {\n const root = document.getElementById(rootId);\n\n // Add click event handlers for the divs containing the answer since these cannot be enclosed in a label element.\n const answerLabels = root.querySelectorAll(SELECTORS.ANSWER_LABEL);\n answerLabels.forEach((answerLabel) => {\n answerLabel.addEventListener('click', (e) => {\n const labelId = e.currentTarget.id;\n // Fetch the answer this label is assigned to.\n const linkedOption = root.querySelector(`[aria-labelledby=\"${labelId}\"]`);\n // Trigger the click event.\n linkedOption.click();\n });\n });\n};\n\nexport default {\n init: init\n};\n"],"file":"answers.min.js"}
|
57
question/type/multichoice/amd/src/answers.js
Normal file
57
question/type/multichoice/amd/src/answers.js
Normal file
@ -0,0 +1,57 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Handles events related to the multiple-choice question type answers.
|
||||
*
|
||||
* @module qtype_multichoice/answers
|
||||
* @package qtype_multichoice
|
||||
* @copyright 2020 Jun Pataleta <jun@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Selectors for this module.
|
||||
*
|
||||
* @type {{ANSWER_LABEL: string}}
|
||||
*/
|
||||
const SELECTORS = {
|
||||
ANSWER_LABEL: '[data-region=answer-label]',
|
||||
};
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*
|
||||
* @param {string} rootId The ID of the question container.
|
||||
*/
|
||||
const init = (rootId) => {
|
||||
const root = document.getElementById(rootId);
|
||||
|
||||
// Add click event handlers for the divs containing the answer since these cannot be enclosed in a label element.
|
||||
const answerLabels = root.querySelectorAll(SELECTORS.ANSWER_LABEL);
|
||||
answerLabels.forEach((answerLabel) => {
|
||||
answerLabel.addEventListener('click', (e) => {
|
||||
const labelId = e.currentTarget.id;
|
||||
// Fetch the answer this label is assigned to.
|
||||
const linkedOption = root.querySelector(`[aria-labelledby="${labelId}"]`);
|
||||
// Trigger the click event.
|
||||
linkedOption.click();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
init: init
|
||||
};
|
@ -88,6 +88,7 @@ abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedb
|
||||
$inputattributes['name'] = $this->get_input_name($qa, $value);
|
||||
$inputattributes['value'] = $this->get_input_value($value);
|
||||
$inputattributes['id'] = $this->get_input_id($qa, $value);
|
||||
$inputattributes['aria-labelledby'] = $inputattributes['id'] . '_label';
|
||||
$isselected = $question->is_choice_selected($response, $value);
|
||||
if ($isselected) {
|
||||
$inputattributes['checked'] = 'checked';
|
||||
@ -102,15 +103,16 @@ abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedb
|
||||
'value' => 0,
|
||||
));
|
||||
}
|
||||
|
||||
$questionnumber = html_writer::span($this->number_in_style($value, $question->answernumbering), 'answernumber');
|
||||
$answertext = $question->format_text($ans->answer, $ans->answerformat, $qa, 'question', 'answer', $ansid);
|
||||
$questionanswer = html_writer::div($answertext, 'flex-fill ml-1');
|
||||
|
||||
$radiobuttons[] = $hidden . html_writer::empty_tag('input', $inputattributes) .
|
||||
html_writer::tag('label',
|
||||
html_writer::span($this->number_in_style($value, $question->answernumbering), 'answernumber') .
|
||||
html_writer::tag('div',
|
||||
$question->format_text(
|
||||
$ans->answer, $ans->answerformat,
|
||||
$qa, 'question', 'answer', $ansid),
|
||||
array('class' => 'flex-fill ml-1')),
|
||||
array('for' => $inputattributes['id'], 'class' => 'd-flex w-100'));
|
||||
html_writer::div($questionnumber . $questionanswer, 'd-flex w-100', [
|
||||
'id' => $inputattributes['id'] . '_label',
|
||||
'data-region' => 'answer-label',
|
||||
]);
|
||||
|
||||
// Param $options->suppresschoicefeedback is a hack specific to the
|
||||
// oumultiresponse question type. It would be good to refactor to
|
||||
@ -151,6 +153,9 @@ abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedb
|
||||
}
|
||||
$result .= html_writer::end_tag('div'); // Answer.
|
||||
|
||||
// Load JS module for the question answers.
|
||||
$this->page->requires->js_call_amd('qtype_multichoice/answers', 'init',
|
||||
[$qa->get_outer_question_div_unique_id()]);
|
||||
$result .= $this->after_choices($qa, $options);
|
||||
|
||||
$result .= html_writer::end_tag('div'); // Ablock.
|
||||
|
Loading…
x
Reference in New Issue
Block a user