MDL-74112 course: Support multiple mforms in format chooser

The format chooser JS assumes that it is the only mform on the page. If
it is not, and another mform appears before it, then the jump will not
work.

This change:
* updates the formatchooser to modern JS
* allows multiple forms to exist on the page
* stops using id fields
* always hide the format selection button
This commit is contained in:
Andrew Nicols 2022-03-08 11:18:08 +08:00
parent 9344149aba
commit 44a4e78075
10 changed files with 67 additions and 112 deletions

12
course/amd/build/formatchooser.min.js vendored Normal file
View File

@ -0,0 +1,12 @@
define("core_course/formatchooser",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
/**
* Course format selection handler.
*
* @module core_course/formatchooser
* @copyright 2022 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.0
*/
const Selectors_fields={selector:'[data-formatchooser-field="selector"]',updateButton:'[data-formatchooser-field="updateButton"]'};_exports.init=()=>{document.querySelector(Selectors_fields.selector).addEventListener("change",(e=>{const form=e.target.closest("form"),updateButton=form.querySelector(Selectors_fields.updateButton),fieldset=updateButton.closest("fieldset"),url=new URL(form.action);url.hash=fieldset.id,form.action=url.toString(),updateButton.click()}))}}));
//# sourceMappingURL=formatchooser.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"formatchooser.min.js","sources":["../src/formatchooser.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/ //\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 * Course format selection handler.\n *\n * @module core_course/formatchooser\n * @copyright 2022 Andrew Nicols <andrew@nicols.co.uk>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 4.0\n */\n\nconst Selectors = {\n fields: {\n selector: '[data-formatchooser-field=\"selector\"]',\n updateButton: '[data-formatchooser-field=\"updateButton\"]',\n },\n};\n\n/**\n * Initialise the format chooser.\n */\nexport const init = () => {\n document.querySelector(Selectors.fields.selector).addEventListener('change', e => {\n const form = e.target.closest('form');\n const updateButton = form.querySelector(Selectors.fields.updateButton);\n const fieldset = updateButton.closest('fieldset');\n\n const url = new URL(form.action);\n url.hash = fieldset.id;\n\n form.action = url.toString();\n updateButton.click();\n });\n};\n"],"names":["Selectors","selector","updateButton","document","querySelector","addEventListener","e","form","target","closest","fieldset","url","URL","action","hash","id","toString","click"],"mappings":";;;;;;;;;MAuBMA,iBACM,CACJC,SAAU,wCACVC,aAAc,2DAOF,KAChBC,SAASC,cAAcJ,iBAAiBC,UAAUI,iBAAiB,UAAUC,UACnEC,KAAOD,EAAEE,OAAOC,QAAQ,QACxBP,aAAeK,KAAKH,cAAcJ,iBAAiBE,cACnDQ,SAAWR,aAAaO,QAAQ,YAEhCE,IAAM,IAAIC,IAAIL,KAAKM,QACzBF,IAAIG,KAAOJ,SAASK,GAEpBR,KAAKM,OAASF,IAAIK,WAClBd,aAAae"}

View File

@ -0,0 +1,46 @@
// 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/>.
/**
* Course format selection handler.
*
* @module core_course/formatchooser
* @copyright 2022 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 4.0
*/
const Selectors = {
fields: {
selector: '[data-formatchooser-field="selector"]',
updateButton: '[data-formatchooser-field="updateButton"]',
},
};
/**
* Initialise the format chooser.
*/
export const init = () => {
document.querySelector(Selectors.fields.selector).addEventListener('change', e => {
const form = e.target.closest('form');
const updateButton = form.querySelector(Selectors.fields.updateButton);
const fieldset = updateButton.closest('fieldset');
const url = new URL(form.action);
url.hash = fieldset.id;
form.action = url.toString();
updateButton.click();
});
};

View File

@ -19,8 +19,7 @@ class course_edit_form extends moodleform {
global $CFG, $PAGE;
$mform = $this->_form;
$PAGE->requires->yui_module('moodle-course-formatchooser', 'M.course.init_formatchooser',
array(array('formid' => $mform->getAttribute('id'))));
$PAGE->requires->js_call_amd('core_course/formatchooser', 'init');
$course = $this->_customdata['course']; // this contains the data of this form
$category = $this->_customdata['category'];
@ -220,13 +219,18 @@ class course_edit_form extends moodleform {
}
}
$mform->addElement('select', 'format', get_string('format'), $formcourseformats);
$mform->addElement('select', 'format', get_string('format'), $formcourseformats, [
'data-formatchooser-field' => 'selector',
]);
$mform->addHelpButton('format', 'format');
$mform->setDefault('format', $courseconfig->format);
// Button to update format-specific options on format change (will be hidden by JavaScript).
$mform->registerNoSubmitButton('updatecourseformat');
$mform->addElement('submit', 'updatecourseformat', get_string('courseformatudpate'));
$mform->addElement('submit', 'updatecourseformat', get_string('courseformatudpate'), [
'data-formatchooser-field' => 'updateButton',
'class' => 'd-none',
]);
// Just a placeholder for the course format options.
$mform->addElement('hidden', 'addcourseformatoptionshere');

View File

@ -1,31 +0,0 @@
YUI.add('moodle-course-formatchooser', function (Y, NAME) {
var FORMATCHOOSER = function() {
FORMATCHOOSER.superclass.constructor.apply(this, arguments);
};
Y.extend(FORMATCHOOSER, Y.Base, {
initializer: function(params) {
if (params && params.formid) {
var updatebut = Y.one('#' + params.formid + ' #id_updatecourseformat');
var formatselect = Y.one('#' + params.formid + ' #id_format');
var ancestor = updatebut.ancestor('fieldset');
var action = Y.one('form.mform').get('action');
if (updatebut && formatselect) {
updatebut.setStyle('display', 'none');
formatselect.on('change', function() {
Y.one('form.mform').set('action', action + '#' + ancestor.get('id'));
updatebut.simulate('click');
});
}
}
}
});
M.course = M.course || {};
M.course.init_formatchooser = function(params) {
return new FORMATCHOOSER(params);
};
}, '@VERSION@', {"requires": ["base", "node", "node-event-simulate"]});

View File

@ -1 +0,0 @@
YUI.add("moodle-course-formatchooser",function(t,o){var e=function(){e.superclass.constructor.apply(this,arguments)};t.extend(e,t.Base,{initializer:function(o){var e,n,r;o&&o.formid&&(e=t.one("#"+o.formid+" #id_updatecourseformat"),o=t.one("#"+o.formid+" #id_format"),n=e.ancestor("fieldset"),r=t.one("form.mform").get("action"),e&&o&&(e.setStyle("display","none"),o.on("change",function(){t.one("form.mform").set("action",r+"#"+n.get("id")),e.simulate("click")})))}}),M.course=M.course||{},M.course.init_formatchooser=function(o){return new e(o)}},"@VERSION@",{requires:["base","node","node-event-simulate"]});

View File

@ -1,31 +0,0 @@
YUI.add('moodle-course-formatchooser', function (Y, NAME) {
var FORMATCHOOSER = function() {
FORMATCHOOSER.superclass.constructor.apply(this, arguments);
};
Y.extend(FORMATCHOOSER, Y.Base, {
initializer: function(params) {
if (params && params.formid) {
var updatebut = Y.one('#' + params.formid + ' #id_updatecourseformat');
var formatselect = Y.one('#' + params.formid + ' #id_format');
var ancestor = updatebut.ancestor('fieldset');
var action = Y.one('form.mform').get('action');
if (updatebut && formatselect) {
updatebut.setStyle('display', 'none');
formatselect.on('change', function() {
Y.one('form.mform').set('action', action + '#' + ancestor.get('id'));
updatebut.simulate('click');
});
}
}
}
});
M.course = M.course || {};
M.course.init_formatchooser = function(params) {
return new FORMATCHOOSER(params);
};
}, '@VERSION@', {"requires": ["base", "node", "node-event-simulate"]});

View File

@ -1,10 +0,0 @@
{
"name": "moodle-course-formatchooser",
"builds": {
"moodle-course-formatchooser": {
"jsfiles": [
"formatchooser.js"
]
}
}
}

View File

@ -1,26 +0,0 @@
var FORMATCHOOSER = function() {
FORMATCHOOSER.superclass.constructor.apply(this, arguments);
};
Y.extend(FORMATCHOOSER, Y.Base, {
initializer: function(params) {
if (params && params.formid) {
var updatebut = Y.one('#' + params.formid + ' #id_updatecourseformat');
var formatselect = Y.one('#' + params.formid + ' #id_format');
var ancestor = updatebut.ancestor('fieldset');
var action = Y.one('form.mform').get('action');
if (updatebut && formatselect) {
updatebut.setStyle('display', 'none');
formatselect.on('change', function() {
Y.one('form.mform').set('action', action + '#' + ancestor.get('id'));
updatebut.simulate('click');
});
}
}
}
});
M.course = M.course || {};
M.course.init_formatchooser = function(params) {
return new FORMATCHOOSER(params);
};

View File

@ -1,9 +0,0 @@
{
"moodle-course-formatchooser": {
"requires": [
"base",
"node",
"node-event-simulate"
]
}
}