MDL-75289 mod_data: Make JS more resilient

This change makes the JS in for preset management more resilient.

Previously, if the button was not on the page then an error was thrown.

Instead this code changes the listener to listen to the document and
filters the clicked element based on the same selector. This is a much
safer approach as it will not error if the selector was not found on the
page.

In this case the behat test introduced elsewhere in this issue is
testing a scenario where the Save as preset button is not present
because there are no fields to store as a preset.
This commit is contained in:
Andrew Nicols 2022-11-03 09:57:18 +08:00
parent 61e8b806ec
commit 8f37e6ecff
9 changed files with 22 additions and 18 deletions

View File

@ -5,6 +5,6 @@ define("mod_data/importpresets",["exports","core_form/modalform","core/notificat
* @module mod_data/importpreset
* @copyright 2022 Laurent David <laurent.david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modalform=_interopRequireDefault(_modalform),_notification=_interopRequireDefault(_notification);const selectors_importPresetButton='[data-action="importpresets"]';_exports.init=()=>{const importPresetButton=document.querySelector(selectors_importPresetButton);importPresetButton.addEventListener("click",(event=>{event.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.get_string)("importpreset","mod_data")},formClass:"mod_data\\form\\import_presets",args:{cmid:importPresetButton.dataset.dataid},saveButtonText:(0,_str.get_string)("importandapply","mod_data")});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(event=>{event.detail.result?window.location.assign(event.detail.url):_notification.default.addNotification({type:"error",message:event.detail.errors.join("<br>")})})),modalForm.show()}))}}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modalform=_interopRequireDefault(_modalform),_notification=_interopRequireDefault(_notification);const selectors_importPresetButton='[data-action="importpresets"]';_exports.init=()=>{document.addEventListener("click",(event=>{const importPresetButton=event.target.closest(selectors_importPresetButton);if(!importPresetButton)return;event.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.get_string)("importpreset","mod_data")},formClass:"mod_data\\form\\import_presets",args:{cmid:importPresetButton.dataset.dataid},saveButtonText:(0,_str.get_string)("importandapply","mod_data")});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(event=>{event.detail.result?window.location.assign(event.detail.url):_notification.default.addNotification({type:"error",message:event.detail.errors.join("<br>")})})),modalForm.show()}))}}));
//# sourceMappingURL=importpresets.min.js.map

View File

@ -1 +1 @@
{"version":3,"file":"importpresets.min.js","sources":["../src/importpresets.js"],"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 * Javascript module for importing presets.\n *\n * @module mod_data/importpreset\n * @copyright 2022 Laurent David <laurent.david@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\n\nconst selectors = {\n importPresetButton: '[data-action=\"importpresets\"]',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n const importPresetButton = document.querySelector(selectors.importPresetButton);\n\n importPresetButton.addEventListener('click', event => {\n event.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('importpreset', 'mod_data'),\n },\n formClass: 'mod_data\\\\form\\\\import_presets',\n args: {cmid: importPresetButton.dataset.dataid},\n saveButtonText: getString('importandapply', 'mod_data'),\n });\n\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n if (event.detail.result) {\n window.location.assign(event.detail.url);\n } else {\n Notification.addNotification({\n type: 'error',\n message: event.detail.errors.join('<br>')\n });\n }\n });\n modalForm.show();\n });\n};\n"],"names":["selectors","importPresetButton","document","querySelector","addEventListener","event","preventDefault","modalForm","ModalForm","modalConfig","title","formClass","args","cmid","dataset","dataid","saveButtonText","events","FORM_SUBMITTED","detail","result","window","location","assign","url","addNotification","type","message","errors","join","show"],"mappings":";;;;;;;0LA2BMA,6BACkB,8CAMJ,WACVC,mBAAqBC,SAASC,cAAcH,8BAElDC,mBAAmBG,iBAAiB,SAASC,QACzCA,MAAMC,uBAEAC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,mBAAU,eAAgB,aAErCC,UAAW,iCACXC,KAAM,CAACC,KAAMZ,mBAAmBa,QAAQC,QACxCC,gBAAgB,mBAAU,iBAAkB,cAGhDT,UAAUH,iBAAiBG,UAAUU,OAAOC,gBAAgBb,QACpDA,MAAMc,OAAOC,OACbC,OAAOC,SAASC,OAAOlB,MAAMc,OAAOK,2BAEvBC,gBAAgB,CACzBC,KAAM,QACNC,QAAStB,MAAMc,OAAOS,OAAOC,KAAK,aAI9CtB,UAAUuB"}
{"version":3,"file":"importpresets.min.js","sources":["../src/importpresets.js"],"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 * Javascript module for importing presets.\n *\n * @module mod_data/importpreset\n * @copyright 2022 Laurent David <laurent.david@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\n\nconst selectors = {\n importPresetButton: '[data-action=\"importpresets\"]',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n document.addEventListener('click', (event) => {\n const importPresetButton = event.target.closest(selectors.importPresetButton);\n\n if (!importPresetButton) {\n return;\n }\n\n event.preventDefault();\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('importpreset', 'mod_data'),\n },\n formClass: 'mod_data\\\\form\\\\import_presets',\n args: {cmid: importPresetButton.dataset.dataid},\n saveButtonText: getString('importandapply', 'mod_data'),\n });\n\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n if (event.detail.result) {\n window.location.assign(event.detail.url);\n } else {\n Notification.addNotification({\n type: 'error',\n message: event.detail.errors.join('<br>')\n });\n }\n });\n modalForm.show();\n });\n};\n"],"names":["selectors","document","addEventListener","event","importPresetButton","target","closest","preventDefault","modalForm","ModalForm","modalConfig","title","formClass","args","cmid","dataset","dataid","saveButtonText","events","FORM_SUBMITTED","detail","result","window","location","assign","url","addNotification","type","message","errors","join","show"],"mappings":";;;;;;;0LA2BMA,6BACkB,8CAMJ,KAChBC,SAASC,iBAAiB,SAAUC,cAC1BC,mBAAqBD,MAAME,OAAOC,QAAQN,kCAE3CI,0BAILD,MAAMI,uBACAC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,mBAAU,eAAgB,aAErCC,UAAW,iCACXC,KAAM,CAACC,KAAMV,mBAAmBW,QAAQC,QACxCC,gBAAgB,mBAAU,iBAAkB,cAGhDT,UAAUN,iBAAiBM,UAAUU,OAAOC,gBAAgBhB,QACpDA,MAAMiB,OAAOC,OACbC,OAAOC,SAASC,OAAOrB,MAAMiB,OAAOK,2BAEvBC,gBAAgB,CACzBC,KAAM,QACNC,QAASzB,MAAMiB,OAAOS,OAAOC,KAAK,aAI9CtB,UAAUuB"}

View File

@ -5,6 +5,6 @@ define("mod_data/saveaspreset",["exports","core_form/modalform","core/notificati
* @module mod_data/saveaspreset
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modalform=_interopRequireDefault(_modalform),_notification=_interopRequireDefault(_notification);const selectors_saveAsPresetButton='[data-action="saveaspreset"]';_exports.init=()=>{const saveAsPresetButton=document.querySelector(selectors_saveAsPresetButton);saveAsPresetButton.addEventListener("click",(event=>{event.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.get_string)("savedataaspreset","mod_data")},formClass:"mod_data\\form\\save_as_preset",args:{d:saveAsPresetButton.getAttribute("data-dataid")},saveButtonText:(0,_str.get_string)("save"),returnFocus:saveAsPresetButton});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(event=>{event.detail.result?window.location.reload():_notification.default.addNotification({type:"error",message:event.detail.errors.join("<br>")})})),modalForm.show()}))}}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_modalform=_interopRequireDefault(_modalform),_notification=_interopRequireDefault(_notification);const selectors_saveAsPresetButton='[data-action="saveaspreset"]';_exports.init=()=>{document.addEventListener("click",(event=>{const saveAsPresetButton=event.target.closest(selectors_saveAsPresetButton);if(!saveAsPresetButton)return;event.preventDefault();const modalForm=new _modalform.default({modalConfig:{title:(0,_str.get_string)("savedataaspreset","mod_data")},formClass:"mod_data\\form\\save_as_preset",args:{d:saveAsPresetButton.dataset.dataid},saveButtonText:(0,_str.get_string)("save"),returnFocus:saveAsPresetButton});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(event=>{event.detail.result?window.location.reload():_notification.default.addNotification({type:"error",message:event.detail.errors.join("<br>")})})),modalForm.show()}))}}));
//# sourceMappingURL=saveaspreset.min.js.map

View File

@ -1 +1 @@
{"version":3,"file":"saveaspreset.min.js","sources":["../src/saveaspreset.js"],"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 * Javascript module for saving a database as a preset.\n *\n * @module mod_data/saveaspreset\n * @copyright 2021 Mihail Geshoski <mihail@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\n\nconst selectors = {\n saveAsPresetButton: '[data-action=\"saveaspreset\"]',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n const saveAsPresetButton = document.querySelector(selectors.saveAsPresetButton);\n\n saveAsPresetButton.addEventListener('click', event => {\n event.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('savedataaspreset', 'mod_data'),\n },\n formClass: 'mod_data\\\\form\\\\save_as_preset',\n args: {d: saveAsPresetButton.getAttribute('data-dataid')},\n saveButtonText: getString('save'),\n returnFocus: saveAsPresetButton,\n });\n\n // Show a toast notification when the form is submitted.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n if (event.detail.result) {\n window.location.reload();\n } else {\n Notification.addNotification({\n type: 'error',\n message: event.detail.errors.join('<br>')\n });\n }\n });\n\n modalForm.show();\n });\n};\n"],"names":["selectors","saveAsPresetButton","document","querySelector","addEventListener","event","preventDefault","modalForm","ModalForm","modalConfig","title","formClass","args","d","getAttribute","saveButtonText","returnFocus","events","FORM_SUBMITTED","detail","result","window","location","reload","addNotification","type","message","errors","join","show"],"mappings":";;;;;;;0LA2BMA,6BACkB,6CAMJ,WACVC,mBAAqBC,SAASC,cAAcH,8BAElDC,mBAAmBG,iBAAiB,SAASC,QACzCA,MAAMC,uBAEAC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,mBAAU,mBAAoB,aAEzCC,UAAW,iCACXC,KAAM,CAACC,EAAGZ,mBAAmBa,aAAa,gBAC1CC,gBAAgB,mBAAU,QAC1BC,YAAaf,qBAIjBM,UAAUH,iBAAiBG,UAAUU,OAAOC,gBAAgBb,QACpDA,MAAMc,OAAOC,OACbC,OAAOC,SAASC,+BAEHC,gBAAgB,CACzBC,KAAM,QACNC,QAAUrB,MAAMc,OAAOQ,OAAOC,KAAK,aAK/CrB,UAAUsB"}
{"version":3,"file":"saveaspreset.min.js","sources":["../src/saveaspreset.js"],"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 * Javascript module for saving a database as a preset.\n *\n * @module mod_data/saveaspreset\n * @copyright 2021 Mihail Geshoski <mihail@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\n\nconst selectors = {\n saveAsPresetButton: '[data-action=\"saveaspreset\"]',\n};\n\n/**\n * Initialize module.\n */\nexport const init = () => {\n\n document.addEventListener('click', (event) => {\n const saveAsPresetButton = event.target.closest(selectors.saveAsPresetButton);\n\n if (!saveAsPresetButton) {\n return;\n }\n\n event.preventDefault();\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('savedataaspreset', 'mod_data'),\n },\n formClass: 'mod_data\\\\form\\\\save_as_preset',\n args: {d: saveAsPresetButton.dataset.dataid},\n saveButtonText: getString('save'),\n returnFocus: saveAsPresetButton,\n });\n\n // Show a toast notification when the form is submitted.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n if (event.detail.result) {\n window.location.reload();\n } else {\n Notification.addNotification({\n type: 'error',\n message: event.detail.errors.join('<br>')\n });\n }\n });\n\n modalForm.show();\n });\n};\n"],"names":["selectors","document","addEventListener","event","saveAsPresetButton","target","closest","preventDefault","modalForm","ModalForm","modalConfig","title","formClass","args","d","dataset","dataid","saveButtonText","returnFocus","events","FORM_SUBMITTED","detail","result","window","location","reload","addNotification","type","message","errors","join","show"],"mappings":";;;;;;;0LA2BMA,6BACkB,6CAMJ,KAEhBC,SAASC,iBAAiB,SAAUC,cAC1BC,mBAAqBD,MAAME,OAAOC,QAAQN,kCAE3CI,0BAILD,MAAMI,uBACAC,UAAY,IAAIC,mBAAU,CAC5BC,YAAa,CACTC,OAAO,mBAAU,mBAAoB,aAEzCC,UAAW,iCACXC,KAAM,CAACC,EAAGV,mBAAmBW,QAAQC,QACrCC,gBAAgB,mBAAU,QAC1BC,YAAad,qBAIjBI,UAAUN,iBAAiBM,UAAUW,OAAOC,gBAAgBjB,QACpDA,MAAMkB,OAAOC,OACbC,OAAOC,SAASC,+BAEHC,gBAAgB,CACzBC,KAAM,QACNC,QAAUzB,MAAMkB,OAAOQ,OAAOC,KAAK,aAK/CtB,UAAUuB"}

File diff suppressed because one or more lines are too long

View File

@ -33,11 +33,14 @@ const selectors = {
* Initialize module
*/
export const init = () => {
const importPresetButton = document.querySelector(selectors.importPresetButton);
document.addEventListener('click', (event) => {
const importPresetButton = event.target.closest(selectors.importPresetButton);
if (!importPresetButton) {
return;
}
importPresetButton.addEventListener('click', event => {
event.preventDefault();
const modalForm = new ModalForm({
modalConfig: {
title: getString('importpreset', 'mod_data'),

View File

@ -30,20 +30,24 @@ const selectors = {
};
/**
* Initialize module
* Initialize module.
*/
export const init = () => {
const saveAsPresetButton = document.querySelector(selectors.saveAsPresetButton);
saveAsPresetButton.addEventListener('click', event => {
document.addEventListener('click', (event) => {
const saveAsPresetButton = event.target.closest(selectors.saveAsPresetButton);
if (!saveAsPresetButton) {
return;
}
event.preventDefault();
const modalForm = new ModalForm({
modalConfig: {
title: getString('savedataaspreset', 'mod_data'),
},
formClass: 'mod_data\\form\\save_as_preset',
args: {d: saveAsPresetButton.getAttribute('data-dataid')},
args: {d: saveAsPresetButton.dataset.dataid},
saveButtonText: getString('save'),
returnFocus: saveAsPresetButton,
});

View File

@ -48,7 +48,7 @@ const selectors = {
/**
* Register event listeners for the module.
*
* @param {int} instanceId The database ID
* @param {Number} instanceId The database ID
* @param {string} mode The template mode
*/
const registerEventListeners = (instanceId, mode) => {

View File

@ -74,11 +74,8 @@
</div>
<hr/>
{{#js}}
require(['mod_data/saveaspreset'], function(saveAsPreset) {
require(['mod_data/saveaspreset', 'mod_data/importpresets'], (saveAsPreset, importPresets) => {
saveAsPreset.init();
});
require(['mod_data/importpresets'], function(importPresetsModal) {
importPresetsModal.init();
});
{{/js}}