From 451614016ecbc9f347cc2aca34494d8c109d55b5 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Tue, 3 Oct 2023 23:36:53 +0200 Subject: [PATCH 1/2] MDL-79531 mod_quiz: Fix exception when adding random questions Moves the data-filtercondition property to an element that always exists regardless of whether the selected category from the filter has questions or not. This will effectively solve the exception that is being thrown due to the non-existing element and also enable creation of random questions in a category that does not have any questions yet. Also, the data-filtercondition attribute is no longer used when creating a random question in a new category as this value is not relevant in this case. Instead, a default filter condition is generated in the webservice for the random question based on the newly created category. --- .../build/modal_add_random_question.min.js | 2 +- .../modal_add_random_question.min.js.map | 2 +- mod/quiz/amd/src/modal_add_random_question.js | 5 ++-- .../classes/external/add_random_questions.php | 23 +++++++++++++++---- mod/quiz/upgrade.txt | 4 +++- question/classes/local/bank/view.php | 9 ++++---- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/mod/quiz/amd/build/modal_add_random_question.min.js b/mod/quiz/amd/build/modal_add_random_question.min.js index 276b86a32da..cf5a36ab7e6 100644 --- a/mod/quiz/amd/build/modal_add_random_question.min.js +++ b/mod/quiz/amd/build/modal_add_random_question.min.js @@ -1,3 +1,3 @@ -define("mod_quiz/modal_add_random_question",["exports","jquery","./add_question_modal","core/notification","core/fragment","core/templates","core_form/changechecker","core/ajax","core/pending"],(function(_exports,_jquery,_add_question_modal,Notification,Fragment,Templates,FormChangeChecker,_ajax,_pending){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}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,_jquery=_interopRequireDefault(_jquery),_add_question_modal=_interopRequireDefault(_add_question_modal),Notification=_interopRequireWildcard(Notification),Fragment=_interopRequireWildcard(Fragment),Templates=_interopRequireWildcard(Templates),FormChangeChecker=_interopRequireWildcard(FormChangeChecker),_pending=_interopRequireDefault(_pending);const SELECTORS={EXISTING_CATEGORY_CONTAINER:'[data-region="existing-category-container"]',EXISTING_CATEGORY_TAB:"#id_existingcategoryheader",NEW_CATEGORY_CONTAINER:'[data-region="new-category-container"]',NEW_CATEGORY_TAB:"#id_newcategoryheader",TAB_CONTENT:'[data-region="tab-content"]',ADD_ON_PAGE_FORM_ELEMENT:'[name="addonpage"]',ADD_RANDOM_BUTTON:'input[type="submit"][name="addrandom"]',ADD_NEW_CATEGORY_BUTTON:'input[type="submit"][name="newcategory"]',SUBMIT_BUTTON_ELEMENT:'input[type="submit"][name="addrandom"], input[type="submit"][name="newcategory"]',FORM_HEADER:"legend",SELECT_NUMBER_TO_ADD:"#menurandomcount",NEW_CATEGORY_ELEMENT:"#categoryname",PARENT_CATEGORY_ELEMENT:"#parentcategory",FILTER_CONDITION_ELEMENT:"[data-filtercondition]",FORM_ELEMENT:"#add_random_question_form",MESSAGE_INPUT:'[name="message"]'};class ModalAddRandomQuestion extends _add_question_modal.default{static init(contextId,category,returnUrl,cmid){let showNewCategory=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];document.addEventListener("click",(e=>{const trigger=e.target.closest('.menu [data-action="addarandomquestion"]');trigger&&(e.preventDefault(),ModalAddRandomQuestion.create({contextId:contextId,category:category,returnUrl:returnUrl,cmid:cmid,title:trigger.dataset.header,addOnPage:trigger.dataset.addonpage,templateContext:{hidden:showNewCategory}}))}))}constructor(root){super(root),this.category=null,this.returnUrl=null,this.cmid=null,this.loadedForm=!1}configure(modalConfig){this.setCategory(modalConfig.category),this.setReturnUrl(modalConfig.returnUrl),this.setCMID(modalConfig.cmid),super.configure(modalConfig)}setAddOnPageId(id){super.setAddOnPageId(id),this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id)}setCategory(category){this.category=category}getCategory(){return this.category}setReturnUrl(url){this.returnUrl=url}getReturnUrl(){return this.returnUrl}setCMID(id){this.cmid=id}getCMID(){return this.cmid}moveContentIntoTab(tabContent,tabElement){tabContent.find(SELECTORS.FORM_HEADER).addClass("hidden"),tabContent.wrap(tabElement)}moveTabsIntoTabContent(form){const tabContent=this.getBody().find(SELECTORS.TAB_CONTENT).empty();form.find('[role="tabpanel"]').wrapAll(tabContent)}moveCancelButtonToTabs(form){const cancelButton=form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass("ml-1"),tabFooters=form.find('[data-region="footer"]');cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove(),cancelButton.clone().appendTo(tabFooters)}loadForm(){const cmid=this.getCMID(),cat=this.getCategory(),addonpage=this.getAddOnPageId(),returnurl=this.getReturnUrl();return Fragment.loadFragment("mod_quiz","add_random_question_form",this.getContextId(),{addonpage:addonpage,cat:cat,returnurl:returnurl,cmid:cmid}).then(((html,js)=>{const form=(0,_jquery.default)(html),existingCategoryTabContent=form.find(SELECTORS.EXISTING_CATEGORY_TAB),existingCategoryTab=this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER),newCategoryTabContent=form.find(SELECTORS.NEW_CATEGORY_TAB),newCategoryTab=this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);this.moveContentIntoTab(existingCategoryTabContent,existingCategoryTab),this.moveContentIntoTab(newCategoryTabContent,newCategoryTab),this.moveTabsIntoTabContent(form),Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT),form,js)})).then((()=>{FormChangeChecker.disableAllChecks(),this.getBody()[0].addEventListener("click",(e=>{var _document$querySelect;if(!e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT))return;e.preventDefault();const randomcount=document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value,filtercondition=null===(_document$querySelect=document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset)||void 0===_document$querySelect?void 0:_document$querySelect.filtercondition;if(e.target.closest(SELECTORS.ADD_RANDOM_BUTTON))return void this.addQuestions(cmid,addonpage,randomcount,filtercondition,"","");e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON)&&this.addQuestions(cmid,addonpage,randomcount,filtercondition,document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value)}))})).catch(Notification.exception)}async addQuestions(cmid,addonpage,randomcount,filtercondition,newcategory,parentcategory){new _pending.default("mod-quiz/modal_add_random_questions");const call={methodname:"mod_quiz_add_random_questions",args:{cmid:cmid,addonpage:addonpage,randomcount:randomcount,filtercondition:filtercondition,newcategory:newcategory,parentcategory:parentcategory}};try{const response=await(0,_ajax.call)([call])[0],form=document.querySelector(SELECTORS.FORM_ELEMENT);form.querySelector(SELECTORS.MESSAGE_INPUT).value=response.message,form.submit()}catch(e){Notification.exception(e)}}show(){super.show(this),this.loadedForm||(this.loadForm(window.location.search),this.loadedForm=!0)}}return _exports.default=ModalAddRandomQuestion,_defineProperty(ModalAddRandomQuestion,"TYPE","mod_quiz-quiz-add-random-question"),_defineProperty(ModalAddRandomQuestion,"TEMPLATE","mod_quiz/modal_add_random_question"),ModalAddRandomQuestion.registerModalType(),_exports.default})); +define("mod_quiz/modal_add_random_question",["exports","jquery","./add_question_modal","core/notification","core/fragment","core/templates","core_form/changechecker","core/ajax","core/pending"],(function(_exports,_jquery,_add_question_modal,Notification,Fragment,Templates,FormChangeChecker,_ajax,_pending){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}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,_jquery=_interopRequireDefault(_jquery),_add_question_modal=_interopRequireDefault(_add_question_modal),Notification=_interopRequireWildcard(Notification),Fragment=_interopRequireWildcard(Fragment),Templates=_interopRequireWildcard(Templates),FormChangeChecker=_interopRequireWildcard(FormChangeChecker),_pending=_interopRequireDefault(_pending);const SELECTORS={EXISTING_CATEGORY_CONTAINER:'[data-region="existing-category-container"]',EXISTING_CATEGORY_TAB:"#id_existingcategoryheader",NEW_CATEGORY_CONTAINER:'[data-region="new-category-container"]',NEW_CATEGORY_TAB:"#id_newcategoryheader",TAB_CONTENT:'[data-region="tab-content"]',ADD_ON_PAGE_FORM_ELEMENT:'[name="addonpage"]',ADD_RANDOM_BUTTON:'input[type="submit"][name="addrandom"]',ADD_NEW_CATEGORY_BUTTON:'input[type="submit"][name="newcategory"]',SUBMIT_BUTTON_ELEMENT:'input[type="submit"][name="addrandom"], input[type="submit"][name="newcategory"]',FORM_HEADER:"legend",SELECT_NUMBER_TO_ADD:"#menurandomcount",NEW_CATEGORY_ELEMENT:"#categoryname",PARENT_CATEGORY_ELEMENT:"#parentcategory",FILTER_CONDITION_ELEMENT:"[data-filtercondition]",FORM_ELEMENT:"#add_random_question_form",MESSAGE_INPUT:'[name="message"]'};class ModalAddRandomQuestion extends _add_question_modal.default{static init(contextId,category,returnUrl,cmid){let showNewCategory=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];document.addEventListener("click",(e=>{const trigger=e.target.closest('.menu [data-action="addarandomquestion"]');trigger&&(e.preventDefault(),ModalAddRandomQuestion.create({contextId:contextId,category:category,returnUrl:returnUrl,cmid:cmid,title:trigger.dataset.header,addOnPage:trigger.dataset.addonpage,templateContext:{hidden:showNewCategory}}))}))}constructor(root){super(root),this.category=null,this.returnUrl=null,this.cmid=null,this.loadedForm=!1}configure(modalConfig){this.setCategory(modalConfig.category),this.setReturnUrl(modalConfig.returnUrl),this.setCMID(modalConfig.cmid),super.configure(modalConfig)}setAddOnPageId(id){super.setAddOnPageId(id),this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id)}setCategory(category){this.category=category}getCategory(){return this.category}setReturnUrl(url){this.returnUrl=url}getReturnUrl(){return this.returnUrl}setCMID(id){this.cmid=id}getCMID(){return this.cmid}moveContentIntoTab(tabContent,tabElement){tabContent.find(SELECTORS.FORM_HEADER).addClass("hidden"),tabContent.wrap(tabElement)}moveTabsIntoTabContent(form){const tabContent=this.getBody().find(SELECTORS.TAB_CONTENT).empty();form.find('[role="tabpanel"]').wrapAll(tabContent)}moveCancelButtonToTabs(form){const cancelButton=form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass("ml-1"),tabFooters=form.find('[data-region="footer"]');cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove(),cancelButton.clone().appendTo(tabFooters)}loadForm(){const cmid=this.getCMID(),cat=this.getCategory(),addonpage=this.getAddOnPageId(),returnurl=this.getReturnUrl();return Fragment.loadFragment("mod_quiz","add_random_question_form",this.getContextId(),{addonpage:addonpage,cat:cat,returnurl:returnurl,cmid:cmid}).then(((html,js)=>{const form=(0,_jquery.default)(html),existingCategoryTabContent=form.find(SELECTORS.EXISTING_CATEGORY_TAB),existingCategoryTab=this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER),newCategoryTabContent=form.find(SELECTORS.NEW_CATEGORY_TAB),newCategoryTab=this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);this.moveContentIntoTab(existingCategoryTabContent,existingCategoryTab),this.moveContentIntoTab(newCategoryTabContent,newCategoryTab),this.moveTabsIntoTabContent(form),Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT),form,js)})).then((()=>{FormChangeChecker.disableAllChecks(),this.getBody()[0].addEventListener("click",(e=>{if(!e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT))return;e.preventDefault();const randomcount=document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value;if(e.target.closest(SELECTORS.ADD_RANDOM_BUTTON)){var _document$querySelect;const filtercondition=null===(_document$querySelect=document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset)||void 0===_document$querySelect?void 0:_document$querySelect.filtercondition;return void this.addQuestions(cmid,addonpage,randomcount,filtercondition,"","")}e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON)&&this.addQuestions(cmid,addonpage,randomcount,"",document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value)}))})).catch(Notification.exception)}async addQuestions(cmid,addonpage,randomcount,filtercondition,newcategory,parentcategory){new _pending.default("mod-quiz/modal_add_random_questions");const call={methodname:"mod_quiz_add_random_questions",args:{cmid:cmid,addonpage:addonpage,randomcount:randomcount,filtercondition:filtercondition,newcategory:newcategory,parentcategory:parentcategory}};try{const response=await(0,_ajax.call)([call])[0],form=document.querySelector(SELECTORS.FORM_ELEMENT);form.querySelector(SELECTORS.MESSAGE_INPUT).value=response.message,form.submit()}catch(e){Notification.exception(e)}}show(){super.show(this),this.loadedForm||(this.loadForm(window.location.search),this.loadedForm=!0)}}return _exports.default=ModalAddRandomQuestion,_defineProperty(ModalAddRandomQuestion,"TYPE","mod_quiz-quiz-add-random-question"),_defineProperty(ModalAddRandomQuestion,"TEMPLATE","mod_quiz/modal_add_random_question"),ModalAddRandomQuestion.registerModalType(),_exports.default})); //# sourceMappingURL=modal_add_random_question.min.js.map \ No newline at end of file diff --git a/mod/quiz/amd/build/modal_add_random_question.min.js.map b/mod/quiz/amd/build/modal_add_random_question.min.js.map index 3c07c771bd7..6a6fcb140e3 100644 --- a/mod/quiz/amd/build/modal_add_random_question.min.js.map +++ b/mod/quiz/amd/build/modal_add_random_question.min.js.map @@ -1 +1 @@ -{"version":3,"file":"modal_add_random_question.min.js","sources":["../src/modal_add_random_question.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 .\n\n/**\n * Contain the logic for the add random question modal.\n *\n * @module mod_quiz/modal_add_random_question\n * @copyright 2018 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Modal from './add_question_modal';\nimport * as Notification from 'core/notification';\nimport * as Fragment from 'core/fragment';\nimport * as Templates from 'core/templates';\nimport * as FormChangeChecker from 'core_form/changechecker';\nimport {call as fetchMany} from 'core/ajax';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n EXISTING_CATEGORY_CONTAINER: '[data-region=\"existing-category-container\"]',\n EXISTING_CATEGORY_TAB: '#id_existingcategoryheader',\n NEW_CATEGORY_CONTAINER: '[data-region=\"new-category-container\"]',\n NEW_CATEGORY_TAB: '#id_newcategoryheader',\n TAB_CONTENT: '[data-region=\"tab-content\"]',\n ADD_ON_PAGE_FORM_ELEMENT: '[name=\"addonpage\"]',\n ADD_RANDOM_BUTTON: 'input[type=\"submit\"][name=\"addrandom\"]',\n ADD_NEW_CATEGORY_BUTTON: 'input[type=\"submit\"][name=\"newcategory\"]',\n SUBMIT_BUTTON_ELEMENT: 'input[type=\"submit\"][name=\"addrandom\"], input[type=\"submit\"][name=\"newcategory\"]',\n FORM_HEADER: 'legend',\n SELECT_NUMBER_TO_ADD: '#menurandomcount',\n NEW_CATEGORY_ELEMENT: '#categoryname',\n PARENT_CATEGORY_ELEMENT: '#parentcategory',\n FILTER_CONDITION_ELEMENT: '[data-filtercondition]',\n FORM_ELEMENT: '#add_random_question_form',\n MESSAGE_INPUT: '[name=\"message\"]',\n};\n\nexport default class ModalAddRandomQuestion extends Modal {\n static TYPE = 'mod_quiz-quiz-add-random-question';\n static TEMPLATE = 'mod_quiz/modal_add_random_question';\n\n /**\n * Create the add random question modal.\n *\n * @param {Number} contextId Current context id.\n * @param {string} category Category id and category context id comma separated.\n * @param {string} returnUrl URL to return to after form submission.\n * @param {Number} cmid Current course module id.\n * @param {boolean} showNewCategory Display the New category tab when selecting random questions.\n */\n static init(contextId, category, returnUrl, cmid, showNewCategory = true) {\n const selector = '.menu [data-action=\"addarandomquestion\"]';\n document.addEventListener('click', (e) => {\n const trigger = e.target.closest(selector);\n if (!trigger) {\n return;\n }\n e.preventDefault();\n\n ModalAddRandomQuestion.create({\n contextId,\n category,\n returnUrl,\n cmid,\n\n title: trigger.dataset.header,\n addOnPage: trigger.dataset.addonpage,\n\n templateContext: {\n hidden: showNewCategory,\n },\n });\n });\n }\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n constructor(root) {\n super(root);\n this.category = null;\n this.returnUrl = null;\n this.cmid = null;\n this.loadedForm = false;\n }\n\n configure(modalConfig) {\n this.setCategory(modalConfig.category);\n this.setReturnUrl(modalConfig.returnUrl);\n this.setCMID(modalConfig.cmid);\n\n super.configure(modalConfig);\n }\n\n /**\n * Set the id of the page that the question should be added to\n * when the user clicks the add to quiz link.\n *\n * @method setAddOnPageId\n * @param {int} id\n */\n setAddOnPageId(id) {\n super.setAddOnPageId(id);\n this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id);\n }\n\n /**\n * Set the category for this form. The category is a comma separated\n * category id and category context id.\n *\n * @method setCategory\n * @param {string} category\n */\n setCategory(category) {\n this.category = category;\n }\n\n /**\n * Returns the saved category.\n *\n * @method getCategory\n * @return {string}\n */\n getCategory() {\n return this.category;\n }\n\n /**\n * Set the return URL for the form.\n *\n * @method setReturnUrl\n * @param {string} url\n */\n setReturnUrl(url) {\n this.returnUrl = url;\n }\n\n /**\n * Returns the return URL for the form.\n *\n * @method getReturnUrl\n * @return {string}\n */\n getReturnUrl() {\n return this.returnUrl;\n }\n\n /**\n * Set the course module id for the form.\n *\n * @method setCMID\n * @param {Number} id\n */\n setCMID(id) {\n this.cmid = id;\n }\n\n /**\n * Returns the course module id for the form.\n *\n * @method getCMID\n * @return {Number}\n */\n getCMID() {\n return this.cmid;\n }\n\n /**\n * Moves a given form element inside (a child of) a given tab element.\n *\n * Hides the 'legend' (e.g. header) element of the form element because the\n * tab has the name.\n *\n * Moves the submit button into a footer element at the bottom of the form\n * element for styling purposes.\n *\n * @method moveContentIntoTab\n * @param {jquery} tabContent The form element to move into the tab.\n * @param {jquey} tabElement The tab element for the form element to move into.\n */\n moveContentIntoTab(tabContent, tabElement) {\n // Hide the header because the tabs show us which part of the form we're\n // looking at.\n tabContent.find(SELECTORS.FORM_HEADER).addClass('hidden');\n // Move the element inside a tab.\n tabContent.wrap(tabElement);\n }\n\n /**\n * Empty the tab content container and move all tabs from the form into the\n * tab container element.\n *\n * @method moveTabsIntoTabContent\n * @param {jquery} form The form element.\n */\n moveTabsIntoTabContent(form) {\n // Empty it to remove the loading icon.\n const tabContent = this.getBody().find(SELECTORS.TAB_CONTENT).empty();\n // Make sure all tabs are inside the tab content element.\n form.find('[role=\"tabpanel\"]').wrapAll(tabContent);\n }\n\n /**\n * Make sure all of the tabs have a cancel button in their fotter to sit along\n * side the submit button.\n *\n * @method moveCancelButtonToTabs\n * @param {jquey} form The form element.\n */\n moveCancelButtonToTabs(form) {\n const cancelButton = form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass('ml-1');\n const tabFooters = form.find('[data-region=\"footer\"]');\n // Remove the buttons container element.\n cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove();\n cancelButton.clone().appendTo(tabFooters);\n }\n\n /**\n * Load the add random question form in a fragement and perform some transformation\n * on the HTML to convert it into tabs for rendering in the modal.\n *\n * @method loadForm\n * @return {promise} Resolved with form HTML and JS.\n */\n loadForm() {\n const cmid = this.getCMID();\n const cat = this.getCategory();\n const addonpage = this.getAddOnPageId();\n const returnurl = this.getReturnUrl();\n\n return Fragment.loadFragment(\n 'mod_quiz',\n 'add_random_question_form',\n this.getContextId(),\n {\n addonpage,\n cat,\n returnurl,\n cmid,\n }\n )\n .then((html, js) =>{\n const form = $(html);\n const existingCategoryTabContent = form.find(SELECTORS.EXISTING_CATEGORY_TAB);\n const existingCategoryTab = this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER);\n const newCategoryTabContent = form.find(SELECTORS.NEW_CATEGORY_TAB);\n const newCategoryTab = this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);\n\n // Transform the form into tabs for better rendering in the modal.\n this.moveContentIntoTab(existingCategoryTabContent, existingCategoryTab);\n this.moveContentIntoTab(newCategoryTabContent, newCategoryTab);\n this.moveTabsIntoTabContent(form);\n\n Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT), form, js);\n return;\n })\n .then(() => {\n // Make sure the form change checker is disabled otherwise it'll stop the user from navigating away from the\n // page once the modal is hidden.\n FormChangeChecker.disableAllChecks();\n\n // Add question to quiz.\n this.getBody()[0].addEventListener('click', (e) => {\n const button = e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT);\n if (!button) {\n return;\n }\n e.preventDefault();\n\n const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value;\n const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition;\n\n // Add Random questions if the add random button was clicked.\n const addRandomButton = e.target.closest(SELECTORS.ADD_RANDOM_BUTTON);\n if (addRandomButton) {\n this.addQuestions(cmid, addonpage, randomcount, filtercondition, '', '');\n return;\n }\n // Add new category if the add category button was clicked.\n const addCategoryButton = e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON);\n if (addCategoryButton) {\n this.addQuestions(\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,\n document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value\n );\n return;\n }\n });\n })\n .catch(Notification.exception);\n }\n\n /**\n * Call web service function to add random questions\n *\n * @param {number} cmid course module id\n * @param {number} addonpage the page where random questions will be added to\n * @param {number} randomcount Number of random questions\n * @param {string} filtercondition Filter condition\n * @param {string} newcategory add new category\n * @param {string} parentcategory parent category of new category\n */\n async addQuestions(\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory\n ) {\n // We do not need to resolve this Pending because the form submission will result in a page redirect.\n new Pending('mod-quiz/modal_add_random_questions');\n const call = {\n methodname: 'mod_quiz_add_random_questions',\n args: {\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory,\n }\n };\n try {\n const response = await fetchMany([call])[0];\n const form = document.querySelector(SELECTORS.FORM_ELEMENT);\n const messageInput = form.querySelector(SELECTORS.MESSAGE_INPUT);\n messageInput.value = response.message;\n form.submit();\n } catch (e) {\n Notification.exception(e);\n }\n }\n\n /**\n * Override the modal show function to load the form when this modal is first\n * shown.\n *\n * @method show\n */\n show() {\n super.show(this);\n\n if (!this.loadedForm) {\n this.loadForm(window.location.search);\n this.loadedForm = true;\n }\n }\n}\n\nModalAddRandomQuestion.registerModalType();\n"],"names":["SELECTORS","EXISTING_CATEGORY_CONTAINER","EXISTING_CATEGORY_TAB","NEW_CATEGORY_CONTAINER","NEW_CATEGORY_TAB","TAB_CONTENT","ADD_ON_PAGE_FORM_ELEMENT","ADD_RANDOM_BUTTON","ADD_NEW_CATEGORY_BUTTON","SUBMIT_BUTTON_ELEMENT","FORM_HEADER","SELECT_NUMBER_TO_ADD","NEW_CATEGORY_ELEMENT","PARENT_CATEGORY_ELEMENT","FILTER_CONDITION_ELEMENT","FORM_ELEMENT","MESSAGE_INPUT","ModalAddRandomQuestion","Modal","contextId","category","returnUrl","cmid","showNewCategory","document","addEventListener","e","trigger","target","closest","preventDefault","create","title","dataset","header","addOnPage","addonpage","templateContext","hidden","constructor","root","loadedForm","configure","modalConfig","setCategory","setReturnUrl","setCMID","setAddOnPageId","id","getBody","find","val","getCategory","this","url","getReturnUrl","getCMID","moveContentIntoTab","tabContent","tabElement","addClass","wrap","moveTabsIntoTabContent","form","empty","wrapAll","moveCancelButtonToTabs","cancelButton","CANCEL_BUTTON_ELEMENT","tabFooters","BUTTON_CONTAINER","remove","clone","appendTo","loadForm","cat","getAddOnPageId","returnurl","Fragment","loadFragment","getContextId","then","html","js","existingCategoryTabContent","existingCategoryTab","newCategoryTabContent","newCategoryTab","Templates","replaceNode","FormChangeChecker","disableAllChecks","randomcount","querySelector","value","filtercondition","_document$querySelect","addQuestions","catch","Notification","exception","newcategory","parentcategory","Pending","call","methodname","args","response","message","submit","show","window","location","search","registerModalType"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"modal_add_random_question.min.js","sources":["../src/modal_add_random_question.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 .\n\n/**\n * Contain the logic for the add random question modal.\n *\n * @module mod_quiz/modal_add_random_question\n * @copyright 2018 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Modal from './add_question_modal';\nimport * as Notification from 'core/notification';\nimport * as Fragment from 'core/fragment';\nimport * as Templates from 'core/templates';\nimport * as FormChangeChecker from 'core_form/changechecker';\nimport {call as fetchMany} from 'core/ajax';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n EXISTING_CATEGORY_CONTAINER: '[data-region=\"existing-category-container\"]',\n EXISTING_CATEGORY_TAB: '#id_existingcategoryheader',\n NEW_CATEGORY_CONTAINER: '[data-region=\"new-category-container\"]',\n NEW_CATEGORY_TAB: '#id_newcategoryheader',\n TAB_CONTENT: '[data-region=\"tab-content\"]',\n ADD_ON_PAGE_FORM_ELEMENT: '[name=\"addonpage\"]',\n ADD_RANDOM_BUTTON: 'input[type=\"submit\"][name=\"addrandom\"]',\n ADD_NEW_CATEGORY_BUTTON: 'input[type=\"submit\"][name=\"newcategory\"]',\n SUBMIT_BUTTON_ELEMENT: 'input[type=\"submit\"][name=\"addrandom\"], input[type=\"submit\"][name=\"newcategory\"]',\n FORM_HEADER: 'legend',\n SELECT_NUMBER_TO_ADD: '#menurandomcount',\n NEW_CATEGORY_ELEMENT: '#categoryname',\n PARENT_CATEGORY_ELEMENT: '#parentcategory',\n FILTER_CONDITION_ELEMENT: '[data-filtercondition]',\n FORM_ELEMENT: '#add_random_question_form',\n MESSAGE_INPUT: '[name=\"message\"]',\n};\n\nexport default class ModalAddRandomQuestion extends Modal {\n static TYPE = 'mod_quiz-quiz-add-random-question';\n static TEMPLATE = 'mod_quiz/modal_add_random_question';\n\n /**\n * Create the add random question modal.\n *\n * @param {Number} contextId Current context id.\n * @param {string} category Category id and category context id comma separated.\n * @param {string} returnUrl URL to return to after form submission.\n * @param {Number} cmid Current course module id.\n * @param {boolean} showNewCategory Display the New category tab when selecting random questions.\n */\n static init(contextId, category, returnUrl, cmid, showNewCategory = true) {\n const selector = '.menu [data-action=\"addarandomquestion\"]';\n document.addEventListener('click', (e) => {\n const trigger = e.target.closest(selector);\n if (!trigger) {\n return;\n }\n e.preventDefault();\n\n ModalAddRandomQuestion.create({\n contextId,\n category,\n returnUrl,\n cmid,\n\n title: trigger.dataset.header,\n addOnPage: trigger.dataset.addonpage,\n\n templateContext: {\n hidden: showNewCategory,\n },\n });\n });\n }\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n constructor(root) {\n super(root);\n this.category = null;\n this.returnUrl = null;\n this.cmid = null;\n this.loadedForm = false;\n }\n\n configure(modalConfig) {\n this.setCategory(modalConfig.category);\n this.setReturnUrl(modalConfig.returnUrl);\n this.setCMID(modalConfig.cmid);\n\n super.configure(modalConfig);\n }\n\n /**\n * Set the id of the page that the question should be added to\n * when the user clicks the add to quiz link.\n *\n * @method setAddOnPageId\n * @param {int} id\n */\n setAddOnPageId(id) {\n super.setAddOnPageId(id);\n this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id);\n }\n\n /**\n * Set the category for this form. The category is a comma separated\n * category id and category context id.\n *\n * @method setCategory\n * @param {string} category\n */\n setCategory(category) {\n this.category = category;\n }\n\n /**\n * Returns the saved category.\n *\n * @method getCategory\n * @return {string}\n */\n getCategory() {\n return this.category;\n }\n\n /**\n * Set the return URL for the form.\n *\n * @method setReturnUrl\n * @param {string} url\n */\n setReturnUrl(url) {\n this.returnUrl = url;\n }\n\n /**\n * Returns the return URL for the form.\n *\n * @method getReturnUrl\n * @return {string}\n */\n getReturnUrl() {\n return this.returnUrl;\n }\n\n /**\n * Set the course module id for the form.\n *\n * @method setCMID\n * @param {Number} id\n */\n setCMID(id) {\n this.cmid = id;\n }\n\n /**\n * Returns the course module id for the form.\n *\n * @method getCMID\n * @return {Number}\n */\n getCMID() {\n return this.cmid;\n }\n\n /**\n * Moves a given form element inside (a child of) a given tab element.\n *\n * Hides the 'legend' (e.g. header) element of the form element because the\n * tab has the name.\n *\n * Moves the submit button into a footer element at the bottom of the form\n * element for styling purposes.\n *\n * @method moveContentIntoTab\n * @param {jquery} tabContent The form element to move into the tab.\n * @param {jquey} tabElement The tab element for the form element to move into.\n */\n moveContentIntoTab(tabContent, tabElement) {\n // Hide the header because the tabs show us which part of the form we're\n // looking at.\n tabContent.find(SELECTORS.FORM_HEADER).addClass('hidden');\n // Move the element inside a tab.\n tabContent.wrap(tabElement);\n }\n\n /**\n * Empty the tab content container and move all tabs from the form into the\n * tab container element.\n *\n * @method moveTabsIntoTabContent\n * @param {jquery} form The form element.\n */\n moveTabsIntoTabContent(form) {\n // Empty it to remove the loading icon.\n const tabContent = this.getBody().find(SELECTORS.TAB_CONTENT).empty();\n // Make sure all tabs are inside the tab content element.\n form.find('[role=\"tabpanel\"]').wrapAll(tabContent);\n }\n\n /**\n * Make sure all of the tabs have a cancel button in their fotter to sit along\n * side the submit button.\n *\n * @method moveCancelButtonToTabs\n * @param {jquey} form The form element.\n */\n moveCancelButtonToTabs(form) {\n const cancelButton = form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass('ml-1');\n const tabFooters = form.find('[data-region=\"footer\"]');\n // Remove the buttons container element.\n cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove();\n cancelButton.clone().appendTo(tabFooters);\n }\n\n /**\n * Load the add random question form in a fragement and perform some transformation\n * on the HTML to convert it into tabs for rendering in the modal.\n *\n * @method loadForm\n * @return {promise} Resolved with form HTML and JS.\n */\n loadForm() {\n const cmid = this.getCMID();\n const cat = this.getCategory();\n const addonpage = this.getAddOnPageId();\n const returnurl = this.getReturnUrl();\n\n return Fragment.loadFragment(\n 'mod_quiz',\n 'add_random_question_form',\n this.getContextId(),\n {\n addonpage,\n cat,\n returnurl,\n cmid,\n }\n )\n .then((html, js) =>{\n const form = $(html);\n const existingCategoryTabContent = form.find(SELECTORS.EXISTING_CATEGORY_TAB);\n const existingCategoryTab = this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER);\n const newCategoryTabContent = form.find(SELECTORS.NEW_CATEGORY_TAB);\n const newCategoryTab = this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);\n\n // Transform the form into tabs for better rendering in the modal.\n this.moveContentIntoTab(existingCategoryTabContent, existingCategoryTab);\n this.moveContentIntoTab(newCategoryTabContent, newCategoryTab);\n this.moveTabsIntoTabContent(form);\n\n Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT), form, js);\n return;\n })\n .then(() => {\n // Make sure the form change checker is disabled otherwise it'll stop the user from navigating away from the\n // page once the modal is hidden.\n FormChangeChecker.disableAllChecks();\n\n // Add question to quiz.\n this.getBody()[0].addEventListener('click', (e) => {\n const button = e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT);\n if (!button) {\n return;\n }\n e.preventDefault();\n\n const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value;\n\n // Add Random questions if the add random button was clicked.\n const addRandomButton = e.target.closest(SELECTORS.ADD_RANDOM_BUTTON);\n if (addRandomButton) {\n const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition;\n\n this.addQuestions(cmid, addonpage, randomcount, filtercondition, '', '');\n return;\n }\n // Add new category if the add category button was clicked.\n const addCategoryButton = e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON);\n if (addCategoryButton) {\n this.addQuestions(\n cmid,\n addonpage,\n randomcount,\n '',\n document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,\n document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value\n );\n return;\n }\n });\n })\n .catch(Notification.exception);\n }\n\n /**\n * Call web service function to add random questions\n *\n * @param {number} cmid course module id\n * @param {number} addonpage the page where random questions will be added to\n * @param {number} randomcount Number of random questions\n * @param {string} filtercondition Filter condition\n * @param {string} newcategory add new category\n * @param {string} parentcategory parent category of new category\n */\n async addQuestions(\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory\n ) {\n // We do not need to resolve this Pending because the form submission will result in a page redirect.\n new Pending('mod-quiz/modal_add_random_questions');\n const call = {\n methodname: 'mod_quiz_add_random_questions',\n args: {\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory,\n }\n };\n try {\n const response = await fetchMany([call])[0];\n const form = document.querySelector(SELECTORS.FORM_ELEMENT);\n const messageInput = form.querySelector(SELECTORS.MESSAGE_INPUT);\n messageInput.value = response.message;\n form.submit();\n } catch (e) {\n Notification.exception(e);\n }\n }\n\n /**\n * Override the modal show function to load the form when this modal is first\n * shown.\n *\n * @method show\n */\n show() {\n super.show(this);\n\n if (!this.loadedForm) {\n this.loadForm(window.location.search);\n this.loadedForm = true;\n }\n }\n}\n\nModalAddRandomQuestion.registerModalType();\n"],"names":["SELECTORS","EXISTING_CATEGORY_CONTAINER","EXISTING_CATEGORY_TAB","NEW_CATEGORY_CONTAINER","NEW_CATEGORY_TAB","TAB_CONTENT","ADD_ON_PAGE_FORM_ELEMENT","ADD_RANDOM_BUTTON","ADD_NEW_CATEGORY_BUTTON","SUBMIT_BUTTON_ELEMENT","FORM_HEADER","SELECT_NUMBER_TO_ADD","NEW_CATEGORY_ELEMENT","PARENT_CATEGORY_ELEMENT","FILTER_CONDITION_ELEMENT","FORM_ELEMENT","MESSAGE_INPUT","ModalAddRandomQuestion","Modal","contextId","category","returnUrl","cmid","showNewCategory","document","addEventListener","e","trigger","target","closest","preventDefault","create","title","dataset","header","addOnPage","addonpage","templateContext","hidden","constructor","root","loadedForm","configure","modalConfig","setCategory","setReturnUrl","setCMID","setAddOnPageId","id","getBody","find","val","getCategory","this","url","getReturnUrl","getCMID","moveContentIntoTab","tabContent","tabElement","addClass","wrap","moveTabsIntoTabContent","form","empty","wrapAll","moveCancelButtonToTabs","cancelButton","CANCEL_BUTTON_ELEMENT","tabFooters","BUTTON_CONTAINER","remove","clone","appendTo","loadForm","cat","getAddOnPageId","returnurl","Fragment","loadFragment","getContextId","then","html","js","existingCategoryTabContent","existingCategoryTab","newCategoryTabContent","newCategoryTab","Templates","replaceNode","FormChangeChecker","disableAllChecks","randomcount","querySelector","value","filtercondition","_document$querySelect","addQuestions","catch","Notification","exception","newcategory","parentcategory","Pending","call","methodname","args","response","message","submit","show","window","location","search","registerModalType"],"mappings":"g5DAgCMA,UAAY,CACdC,4BAA6B,8CAC7BC,sBAAuB,6BACvBC,uBAAwB,yCACxBC,iBAAkB,wBAClBC,YAAa,8BACbC,yBAA0B,qBAC1BC,kBAAmB,yCACnBC,wBAAyB,2CACzBC,sBAAuB,mFACvBC,YAAa,SACbC,qBAAsB,mBACtBC,qBAAsB,gBACtBC,wBAAyB,kBACzBC,yBAA0B,yBAC1BC,aAAc,4BACdC,cAAe,0BAGEC,+BAA+BC,wCAapCC,UAAWC,SAAUC,UAAWC,UAAMC,2EAE9CC,SAASC,iBAAiB,SAAUC,UAC1BC,QAAUD,EAAEE,OAAOC,QAFZ,4CAGRF,UAGLD,EAAEI,iBAEFb,uBAAuBc,OAAO,CAC1BZ,UAAAA,UACAC,SAAAA,SACAC,UAAAA,UACAC,KAAAA,KAEAU,MAAOL,QAAQM,QAAQC,OACvBC,UAAWR,QAAQM,QAAQG,UAE3BC,gBAAiB,CACbC,OAAQf,uBAWxBgB,YAAYC,YACFA,WACDpB,SAAW,UACXC,UAAY,UACZC,KAAO,UACPmB,YAAa,EAGtBC,UAAUC,kBACDC,YAAYD,YAAYvB,eACxByB,aAAaF,YAAYtB,gBACzByB,QAAQH,YAAYrB,YAEnBoB,UAAUC,aAUpBI,eAAeC,UACLD,eAAeC,SAChBC,UAAUC,KAAKlD,UAAUM,0BAA0B6C,IAAIH,IAUhEJ,YAAYxB,eACHA,SAAWA,SASpBgC,qBACWC,KAAKjC,SAShByB,aAAaS,UACJjC,UAAYiC,IASrBC,sBACWF,KAAKhC,UAShByB,QAAQE,SACC1B,KAAO0B,GAShBQ,iBACWH,KAAK/B,KAgBhBmC,mBAAmBC,WAAYC,YAG3BD,WAAWR,KAAKlD,UAAUU,aAAakD,SAAS,UAEhDF,WAAWG,KAAKF,YAUpBG,uBAAuBC,YAEbL,WAAaL,KAAKJ,UAAUC,KAAKlD,UAAUK,aAAa2D,QAE9DD,KAAKb,KAAK,qBAAqBe,QAAQP,YAU3CQ,uBAAuBH,YACbI,aAAeJ,KAAKb,KAAKlD,UAAUoE,uBAAuBR,SAAS,QACnES,WAAaN,KAAKb,KAAK,0BAE7BiB,aAAatC,QAAQ7B,UAAUsE,kBAAkBC,SACjDJ,aAAaK,QAAQC,SAASJ,YAUlCK,iBACUpD,KAAO+B,KAAKG,UACZmB,IAAMtB,KAAKD,cACXhB,UAAYiB,KAAKuB,iBACjBC,UAAYxB,KAAKE,sBAEhBuB,SAASC,aACZ,WACA,2BACA1B,KAAK2B,eACL,CACI5C,UAAAA,UACAuC,IAAAA,IACAE,UAAAA,UACAvD,KAAAA,OAGP2D,MAAK,CAACC,KAAMC,YACHpB,MAAO,mBAAEmB,MACTE,2BAA6BrB,KAAKb,KAAKlD,UAAUE,uBACjDmF,oBAAsBhC,KAAKJ,UAAUC,KAAKlD,UAAUC,6BACpDqF,sBAAwBvB,KAAKb,KAAKlD,UAAUI,kBAC5CmF,eAAiBlC,KAAKJ,UAAUC,KAAKlD,UAAUG,6BAGhDsD,mBAAmB2B,2BAA4BC,0BAC/C5B,mBAAmB6B,sBAAuBC,qBAC1CzB,uBAAuBC,MAE5ByB,UAAUC,YAAYpC,KAAKJ,UAAUC,KAAKlD,UAAUK,aAAc0D,KAAMoB,OAG3EF,MAAK,KAGFS,kBAAkBC,wBAGb1C,UAAU,GAAGxB,iBAAiB,SAAUC,QAC1BA,EAAEE,OAAOC,QAAQ7B,UAAUS,8BAI1CiB,EAAEI,uBAEI8D,YAAcpE,SAASqE,cAAc7F,UAAUW,sBAAsBmF,SAGnDpE,EAAEE,OAAOC,QAAQ7B,UAAUO,mBAC9B,iCACXwF,8CAAkBvE,SAASqE,cAAc7F,UAAUc,0BAA0BmB,gDAA3D+D,sBAAoED,iCAEvFE,aAAa3E,KAAMc,UAAWwD,YAAaG,gBAAiB,GAAI,IAI/CrE,EAAEE,OAAOC,QAAQ7B,UAAUQ,+BAE5CyF,aACD3E,KACAc,UACAwD,YACA,GACApE,SAASqE,cAAc7F,UAAUY,sBAAsBkF,MACvDtE,SAASqE,cAAc7F,UAAUa,yBAAyBiF,aAMzEI,MAAMC,aAAaC,8BAcpB9E,KACAc,UACAwD,YACAG,gBACAM,YACAC,oBAGIC,iBAAQ,6CACNC,KAAO,CACTC,WAAY,gCACZC,KAAM,CACFpF,KAAAA,KACAc,UAAAA,UACAwD,YAAAA,YACAG,gBAAAA,gBACAM,YAAAA,YACAC,eAAAA,2BAIEK,eAAiB,cAAU,CAACH,OAAO,GACnCzC,KAAOvC,SAASqE,cAAc7F,UAAUe,cACzBgD,KAAK8B,cAAc7F,UAAUgB,eACrC8E,MAAQa,SAASC,QAC9B7C,KAAK8C,SACP,MAAOnF,GACLyE,aAAaC,UAAU1E,IAU/BoF,aACUA,KAAKzD,MAENA,KAAKZ,kBACDiC,SAASqC,OAAOC,SAASC,aACzBxE,YAAa,mEA3TTxB,8BACH,qDADGA,kCAEC,sCA8TtBA,uBAAuBiG"} \ No newline at end of file diff --git a/mod/quiz/amd/src/modal_add_random_question.js b/mod/quiz/amd/src/modal_add_random_question.js index ec8b3cf40d2..8a572b23032 100644 --- a/mod/quiz/amd/src/modal_add_random_question.js +++ b/mod/quiz/amd/src/modal_add_random_question.js @@ -284,11 +284,12 @@ export default class ModalAddRandomQuestion extends Modal { e.preventDefault(); const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value; - const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition; // Add Random questions if the add random button was clicked. const addRandomButton = e.target.closest(SELECTORS.ADD_RANDOM_BUTTON); if (addRandomButton) { + const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition; + this.addQuestions(cmid, addonpage, randomcount, filtercondition, '', ''); return; } @@ -299,7 +300,7 @@ export default class ModalAddRandomQuestion extends Modal { cmid, addonpage, randomcount, - filtercondition, + '', document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value, document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value ); diff --git a/mod/quiz/classes/external/add_random_questions.php b/mod/quiz/classes/external/add_random_questions.php index 88a62e30520..422791dd0e3 100644 --- a/mod/quiz/classes/external/add_random_questions.php +++ b/mod/quiz/classes/external/add_random_questions.php @@ -51,7 +51,13 @@ class add_random_questions extends external_api { 'cmid' => new external_value(PARAM_INT, 'The cmid of the quiz'), 'addonpage' => new external_value(PARAM_INT, 'The page where random questions will be added to'), 'randomcount' => new external_value(PARAM_INT, 'Number of random questions'), - 'filtercondition' => new external_value(PARAM_TEXT, 'Filter condition'), + 'filtercondition' => new external_value( + PARAM_TEXT, + '(Optional) The filter condition used when adding random questions from an existing category. + Not required if adding random questions from a new category.', + VALUE_DEFAULT, + '', + ), 'newcategory' => new external_value( PARAM_TEXT, '(Optional) The name of a new question category to create and use for the random questions.', @@ -83,7 +89,7 @@ class add_random_questions extends external_api { int $cmid, int $addonpage, int $randomcount, - string $filtercondition, + string $filtercondition = '', string $newcategory = '', string $parentcategory = '', ): array { @@ -108,7 +114,8 @@ class add_random_questions extends external_api { self::validate_context($thiscontext); require_capability('mod/quiz:manage', $thiscontext); - $filtercondition = json_decode($filtercondition, true); + // If filtercondition is not empty, decode it. Otherwise, set it to empty array. + $filtercondition = !empty($filtercondition) ? json_decode($filtercondition, true) : []; // Create new category. if (!empty($newcategory)) { @@ -131,7 +138,15 @@ class add_random_questions extends external_api { 'filteroptions' => ['includesubcategories' => false], ] ]; - $filtercondition['filter'] = $filter; + // Generate default filter condition for the random question to be added in the new category. + $filtercondition = [ + 'qpage' => 0, + 'cat' => "{$categoryid},{$thiscontext->id}", + 'qperpage' => DEFAULT_QUESTIONS_PER_PAGE, + 'tabname' => 'questions', + 'sortdata' => [], + 'filter' => $filter, + ]; } // Add random question to the quiz. diff --git a/mod/quiz/upgrade.txt b/mod/quiz/upgrade.txt index fb40f8d30dd..8fd9bf70ac3 100644 --- a/mod/quiz/upgrade.txt +++ b/mod/quiz/upgrade.txt @@ -8,7 +8,9 @@ This files describes API changes in the quiz code. In the distant past it was always a stdClass, then at one point there was an undocumented change making it sometimes a stdClass and sometimes a cm_info. Now it is consistently a cm_info. Type hints have been updated to reflect this. - +* The parameter filtercondition in the web service mod_quiz_add_random_questions is now optional. This parameter is + only used when adding random questions from an existing category. It is not required when adding random questions from + a new category since it is not used in this case. === 4.2 === diff --git a/question/classes/local/bank/view.php b/question/classes/local/bank/view.php index f01b43c0d7e..f7f0bda6568 100644 --- a/question/classes/local/bank/view.php +++ b/question/classes/local/bank/view.php @@ -1167,8 +1167,10 @@ class view { echo \html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()]); echo \html_writer::input_hidden_params($this->baseurl); + $filtercondition = json_encode($this->get_pagevars()); + // Embeded filterconditon into the div. echo \html_writer::start_tag('div', - ['class' => 'categoryquestionscontainer']); + ['class' => 'categoryquestionscontainer', 'data-filtercondition' => $filtercondition]); if ($totalquestions > 0) { // Bulk load any required statistics. $this->load_required_statistics($questions); @@ -1365,11 +1367,8 @@ class view { echo $OUTPUT->render($pagingbar); // Table of questions. - // Embeded filterconditon into the div. - $filtercondition = json_encode($this->get_pagevars()); - echo \html_writer::start_tag('div', - ['class' => 'question_table', 'id' => 'question_table', 'data-filtercondition' => $filtercondition]); + ['class' => 'question_table', 'id' => 'question_table']); $this->print_table($questions); echo \html_writer::end_tag('div'); echo $OUTPUT->render($pagingbar); From bef518efb8b6127dcbf88e15bb5f21800edac123 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Tue, 3 Oct 2023 23:53:02 +0200 Subject: [PATCH 2/2] MDL-79531 mod_quiz: Create only one random question in new category --- mod/quiz/amd/build/modal_add_random_question.min.js | 2 +- mod/quiz/amd/build/modal_add_random_question.min.js.map | 2 +- mod/quiz/amd/src/modal_add_random_question.js | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/mod/quiz/amd/build/modal_add_random_question.min.js b/mod/quiz/amd/build/modal_add_random_question.min.js index cf5a36ab7e6..af4c41fad09 100644 --- a/mod/quiz/amd/build/modal_add_random_question.min.js +++ b/mod/quiz/amd/build/modal_add_random_question.min.js @@ -1,3 +1,3 @@ -define("mod_quiz/modal_add_random_question",["exports","jquery","./add_question_modal","core/notification","core/fragment","core/templates","core_form/changechecker","core/ajax","core/pending"],(function(_exports,_jquery,_add_question_modal,Notification,Fragment,Templates,FormChangeChecker,_ajax,_pending){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}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,_jquery=_interopRequireDefault(_jquery),_add_question_modal=_interopRequireDefault(_add_question_modal),Notification=_interopRequireWildcard(Notification),Fragment=_interopRequireWildcard(Fragment),Templates=_interopRequireWildcard(Templates),FormChangeChecker=_interopRequireWildcard(FormChangeChecker),_pending=_interopRequireDefault(_pending);const SELECTORS={EXISTING_CATEGORY_CONTAINER:'[data-region="existing-category-container"]',EXISTING_CATEGORY_TAB:"#id_existingcategoryheader",NEW_CATEGORY_CONTAINER:'[data-region="new-category-container"]',NEW_CATEGORY_TAB:"#id_newcategoryheader",TAB_CONTENT:'[data-region="tab-content"]',ADD_ON_PAGE_FORM_ELEMENT:'[name="addonpage"]',ADD_RANDOM_BUTTON:'input[type="submit"][name="addrandom"]',ADD_NEW_CATEGORY_BUTTON:'input[type="submit"][name="newcategory"]',SUBMIT_BUTTON_ELEMENT:'input[type="submit"][name="addrandom"], input[type="submit"][name="newcategory"]',FORM_HEADER:"legend",SELECT_NUMBER_TO_ADD:"#menurandomcount",NEW_CATEGORY_ELEMENT:"#categoryname",PARENT_CATEGORY_ELEMENT:"#parentcategory",FILTER_CONDITION_ELEMENT:"[data-filtercondition]",FORM_ELEMENT:"#add_random_question_form",MESSAGE_INPUT:'[name="message"]'};class ModalAddRandomQuestion extends _add_question_modal.default{static init(contextId,category,returnUrl,cmid){let showNewCategory=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];document.addEventListener("click",(e=>{const trigger=e.target.closest('.menu [data-action="addarandomquestion"]');trigger&&(e.preventDefault(),ModalAddRandomQuestion.create({contextId:contextId,category:category,returnUrl:returnUrl,cmid:cmid,title:trigger.dataset.header,addOnPage:trigger.dataset.addonpage,templateContext:{hidden:showNewCategory}}))}))}constructor(root){super(root),this.category=null,this.returnUrl=null,this.cmid=null,this.loadedForm=!1}configure(modalConfig){this.setCategory(modalConfig.category),this.setReturnUrl(modalConfig.returnUrl),this.setCMID(modalConfig.cmid),super.configure(modalConfig)}setAddOnPageId(id){super.setAddOnPageId(id),this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id)}setCategory(category){this.category=category}getCategory(){return this.category}setReturnUrl(url){this.returnUrl=url}getReturnUrl(){return this.returnUrl}setCMID(id){this.cmid=id}getCMID(){return this.cmid}moveContentIntoTab(tabContent,tabElement){tabContent.find(SELECTORS.FORM_HEADER).addClass("hidden"),tabContent.wrap(tabElement)}moveTabsIntoTabContent(form){const tabContent=this.getBody().find(SELECTORS.TAB_CONTENT).empty();form.find('[role="tabpanel"]').wrapAll(tabContent)}moveCancelButtonToTabs(form){const cancelButton=form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass("ml-1"),tabFooters=form.find('[data-region="footer"]');cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove(),cancelButton.clone().appendTo(tabFooters)}loadForm(){const cmid=this.getCMID(),cat=this.getCategory(),addonpage=this.getAddOnPageId(),returnurl=this.getReturnUrl();return Fragment.loadFragment("mod_quiz","add_random_question_form",this.getContextId(),{addonpage:addonpage,cat:cat,returnurl:returnurl,cmid:cmid}).then(((html,js)=>{const form=(0,_jquery.default)(html),existingCategoryTabContent=form.find(SELECTORS.EXISTING_CATEGORY_TAB),existingCategoryTab=this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER),newCategoryTabContent=form.find(SELECTORS.NEW_CATEGORY_TAB),newCategoryTab=this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);this.moveContentIntoTab(existingCategoryTabContent,existingCategoryTab),this.moveContentIntoTab(newCategoryTabContent,newCategoryTab),this.moveTabsIntoTabContent(form),Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT),form,js)})).then((()=>{FormChangeChecker.disableAllChecks(),this.getBody()[0].addEventListener("click",(e=>{if(!e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT))return;e.preventDefault();const randomcount=document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value;if(e.target.closest(SELECTORS.ADD_RANDOM_BUTTON)){var _document$querySelect;const filtercondition=null===(_document$querySelect=document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset)||void 0===_document$querySelect?void 0:_document$querySelect.filtercondition;return void this.addQuestions(cmid,addonpage,randomcount,filtercondition,"","")}e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON)&&this.addQuestions(cmid,addonpage,randomcount,"",document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value)}))})).catch(Notification.exception)}async addQuestions(cmid,addonpage,randomcount,filtercondition,newcategory,parentcategory){new _pending.default("mod-quiz/modal_add_random_questions");const call={methodname:"mod_quiz_add_random_questions",args:{cmid:cmid,addonpage:addonpage,randomcount:randomcount,filtercondition:filtercondition,newcategory:newcategory,parentcategory:parentcategory}};try{const response=await(0,_ajax.call)([call])[0],form=document.querySelector(SELECTORS.FORM_ELEMENT);form.querySelector(SELECTORS.MESSAGE_INPUT).value=response.message,form.submit()}catch(e){Notification.exception(e)}}show(){super.show(this),this.loadedForm||(this.loadForm(window.location.search),this.loadedForm=!0)}}return _exports.default=ModalAddRandomQuestion,_defineProperty(ModalAddRandomQuestion,"TYPE","mod_quiz-quiz-add-random-question"),_defineProperty(ModalAddRandomQuestion,"TEMPLATE","mod_quiz/modal_add_random_question"),ModalAddRandomQuestion.registerModalType(),_exports.default})); +define("mod_quiz/modal_add_random_question",["exports","jquery","./add_question_modal","core/notification","core/fragment","core/templates","core_form/changechecker","core/ajax","core/pending"],(function(_exports,_jquery,_add_question_modal,Notification,Fragment,Templates,FormChangeChecker,_ajax,_pending){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}return newObj.default=obj,cache&&cache.set(obj,newObj),newObj}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,_jquery=_interopRequireDefault(_jquery),_add_question_modal=_interopRequireDefault(_add_question_modal),Notification=_interopRequireWildcard(Notification),Fragment=_interopRequireWildcard(Fragment),Templates=_interopRequireWildcard(Templates),FormChangeChecker=_interopRequireWildcard(FormChangeChecker),_pending=_interopRequireDefault(_pending);const SELECTORS={EXISTING_CATEGORY_CONTAINER:'[data-region="existing-category-container"]',EXISTING_CATEGORY_TAB:"#id_existingcategoryheader",NEW_CATEGORY_CONTAINER:'[data-region="new-category-container"]',NEW_CATEGORY_TAB:"#id_newcategoryheader",TAB_CONTENT:'[data-region="tab-content"]',ADD_ON_PAGE_FORM_ELEMENT:'[name="addonpage"]',ADD_RANDOM_BUTTON:'input[type="submit"][name="addrandom"]',ADD_NEW_CATEGORY_BUTTON:'input[type="submit"][name="newcategory"]',SUBMIT_BUTTON_ELEMENT:'input[type="submit"][name="addrandom"], input[type="submit"][name="newcategory"]',FORM_HEADER:"legend",SELECT_NUMBER_TO_ADD:"#menurandomcount",NEW_CATEGORY_ELEMENT:"#categoryname",PARENT_CATEGORY_ELEMENT:"#parentcategory",FILTER_CONDITION_ELEMENT:"[data-filtercondition]",FORM_ELEMENT:"#add_random_question_form",MESSAGE_INPUT:'[name="message"]'};class ModalAddRandomQuestion extends _add_question_modal.default{static init(contextId,category,returnUrl,cmid){let showNewCategory=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];document.addEventListener("click",(e=>{const trigger=e.target.closest('.menu [data-action="addarandomquestion"]');trigger&&(e.preventDefault(),ModalAddRandomQuestion.create({contextId:contextId,category:category,returnUrl:returnUrl,cmid:cmid,title:trigger.dataset.header,addOnPage:trigger.dataset.addonpage,templateContext:{hidden:showNewCategory}}))}))}constructor(root){super(root),this.category=null,this.returnUrl=null,this.cmid=null,this.loadedForm=!1}configure(modalConfig){this.setCategory(modalConfig.category),this.setReturnUrl(modalConfig.returnUrl),this.setCMID(modalConfig.cmid),super.configure(modalConfig)}setAddOnPageId(id){super.setAddOnPageId(id),this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id)}setCategory(category){this.category=category}getCategory(){return this.category}setReturnUrl(url){this.returnUrl=url}getReturnUrl(){return this.returnUrl}setCMID(id){this.cmid=id}getCMID(){return this.cmid}moveContentIntoTab(tabContent,tabElement){tabContent.find(SELECTORS.FORM_HEADER).addClass("hidden"),tabContent.wrap(tabElement)}moveTabsIntoTabContent(form){const tabContent=this.getBody().find(SELECTORS.TAB_CONTENT).empty();form.find('[role="tabpanel"]').wrapAll(tabContent)}moveCancelButtonToTabs(form){const cancelButton=form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass("ml-1"),tabFooters=form.find('[data-region="footer"]');cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove(),cancelButton.clone().appendTo(tabFooters)}loadForm(){const cmid=this.getCMID(),cat=this.getCategory(),addonpage=this.getAddOnPageId(),returnurl=this.getReturnUrl();return Fragment.loadFragment("mod_quiz","add_random_question_form",this.getContextId(),{addonpage:addonpage,cat:cat,returnurl:returnurl,cmid:cmid}).then(((html,js)=>{const form=(0,_jquery.default)(html),existingCategoryTabContent=form.find(SELECTORS.EXISTING_CATEGORY_TAB),existingCategoryTab=this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER),newCategoryTabContent=form.find(SELECTORS.NEW_CATEGORY_TAB),newCategoryTab=this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);this.moveContentIntoTab(existingCategoryTabContent,existingCategoryTab),this.moveContentIntoTab(newCategoryTabContent,newCategoryTab),this.moveTabsIntoTabContent(form),Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT),form,js)})).then((()=>{FormChangeChecker.disableAllChecks(),this.getBody()[0].addEventListener("click",(e=>{if(!e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT))return;e.preventDefault();if(e.target.closest(SELECTORS.ADD_RANDOM_BUTTON)){var _document$querySelect;const randomcount=document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value,filtercondition=null===(_document$querySelect=document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset)||void 0===_document$querySelect?void 0:_document$querySelect.filtercondition;return void this.addQuestions(cmid,addonpage,randomcount,filtercondition,"","")}e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON)&&this.addQuestions(cmid,addonpage,1,"",document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value)}))})).catch(Notification.exception)}async addQuestions(cmid,addonpage,randomcount,filtercondition,newcategory,parentcategory){new _pending.default("mod-quiz/modal_add_random_questions");const call={methodname:"mod_quiz_add_random_questions",args:{cmid:cmid,addonpage:addonpage,randomcount:randomcount,filtercondition:filtercondition,newcategory:newcategory,parentcategory:parentcategory}};try{const response=await(0,_ajax.call)([call])[0],form=document.querySelector(SELECTORS.FORM_ELEMENT);form.querySelector(SELECTORS.MESSAGE_INPUT).value=response.message,form.submit()}catch(e){Notification.exception(e)}}show(){super.show(this),this.loadedForm||(this.loadForm(window.location.search),this.loadedForm=!0)}}return _exports.default=ModalAddRandomQuestion,_defineProperty(ModalAddRandomQuestion,"TYPE","mod_quiz-quiz-add-random-question"),_defineProperty(ModalAddRandomQuestion,"TEMPLATE","mod_quiz/modal_add_random_question"),ModalAddRandomQuestion.registerModalType(),_exports.default})); //# sourceMappingURL=modal_add_random_question.min.js.map \ No newline at end of file diff --git a/mod/quiz/amd/build/modal_add_random_question.min.js.map b/mod/quiz/amd/build/modal_add_random_question.min.js.map index 6a6fcb140e3..6d26ea8047f 100644 --- a/mod/quiz/amd/build/modal_add_random_question.min.js.map +++ b/mod/quiz/amd/build/modal_add_random_question.min.js.map @@ -1 +1 @@ -{"version":3,"file":"modal_add_random_question.min.js","sources":["../src/modal_add_random_question.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 .\n\n/**\n * Contain the logic for the add random question modal.\n *\n * @module mod_quiz/modal_add_random_question\n * @copyright 2018 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Modal from './add_question_modal';\nimport * as Notification from 'core/notification';\nimport * as Fragment from 'core/fragment';\nimport * as Templates from 'core/templates';\nimport * as FormChangeChecker from 'core_form/changechecker';\nimport {call as fetchMany} from 'core/ajax';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n EXISTING_CATEGORY_CONTAINER: '[data-region=\"existing-category-container\"]',\n EXISTING_CATEGORY_TAB: '#id_existingcategoryheader',\n NEW_CATEGORY_CONTAINER: '[data-region=\"new-category-container\"]',\n NEW_CATEGORY_TAB: '#id_newcategoryheader',\n TAB_CONTENT: '[data-region=\"tab-content\"]',\n ADD_ON_PAGE_FORM_ELEMENT: '[name=\"addonpage\"]',\n ADD_RANDOM_BUTTON: 'input[type=\"submit\"][name=\"addrandom\"]',\n ADD_NEW_CATEGORY_BUTTON: 'input[type=\"submit\"][name=\"newcategory\"]',\n SUBMIT_BUTTON_ELEMENT: 'input[type=\"submit\"][name=\"addrandom\"], input[type=\"submit\"][name=\"newcategory\"]',\n FORM_HEADER: 'legend',\n SELECT_NUMBER_TO_ADD: '#menurandomcount',\n NEW_CATEGORY_ELEMENT: '#categoryname',\n PARENT_CATEGORY_ELEMENT: '#parentcategory',\n FILTER_CONDITION_ELEMENT: '[data-filtercondition]',\n FORM_ELEMENT: '#add_random_question_form',\n MESSAGE_INPUT: '[name=\"message\"]',\n};\n\nexport default class ModalAddRandomQuestion extends Modal {\n static TYPE = 'mod_quiz-quiz-add-random-question';\n static TEMPLATE = 'mod_quiz/modal_add_random_question';\n\n /**\n * Create the add random question modal.\n *\n * @param {Number} contextId Current context id.\n * @param {string} category Category id and category context id comma separated.\n * @param {string} returnUrl URL to return to after form submission.\n * @param {Number} cmid Current course module id.\n * @param {boolean} showNewCategory Display the New category tab when selecting random questions.\n */\n static init(contextId, category, returnUrl, cmid, showNewCategory = true) {\n const selector = '.menu [data-action=\"addarandomquestion\"]';\n document.addEventListener('click', (e) => {\n const trigger = e.target.closest(selector);\n if (!trigger) {\n return;\n }\n e.preventDefault();\n\n ModalAddRandomQuestion.create({\n contextId,\n category,\n returnUrl,\n cmid,\n\n title: trigger.dataset.header,\n addOnPage: trigger.dataset.addonpage,\n\n templateContext: {\n hidden: showNewCategory,\n },\n });\n });\n }\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n constructor(root) {\n super(root);\n this.category = null;\n this.returnUrl = null;\n this.cmid = null;\n this.loadedForm = false;\n }\n\n configure(modalConfig) {\n this.setCategory(modalConfig.category);\n this.setReturnUrl(modalConfig.returnUrl);\n this.setCMID(modalConfig.cmid);\n\n super.configure(modalConfig);\n }\n\n /**\n * Set the id of the page that the question should be added to\n * when the user clicks the add to quiz link.\n *\n * @method setAddOnPageId\n * @param {int} id\n */\n setAddOnPageId(id) {\n super.setAddOnPageId(id);\n this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id);\n }\n\n /**\n * Set the category for this form. The category is a comma separated\n * category id and category context id.\n *\n * @method setCategory\n * @param {string} category\n */\n setCategory(category) {\n this.category = category;\n }\n\n /**\n * Returns the saved category.\n *\n * @method getCategory\n * @return {string}\n */\n getCategory() {\n return this.category;\n }\n\n /**\n * Set the return URL for the form.\n *\n * @method setReturnUrl\n * @param {string} url\n */\n setReturnUrl(url) {\n this.returnUrl = url;\n }\n\n /**\n * Returns the return URL for the form.\n *\n * @method getReturnUrl\n * @return {string}\n */\n getReturnUrl() {\n return this.returnUrl;\n }\n\n /**\n * Set the course module id for the form.\n *\n * @method setCMID\n * @param {Number} id\n */\n setCMID(id) {\n this.cmid = id;\n }\n\n /**\n * Returns the course module id for the form.\n *\n * @method getCMID\n * @return {Number}\n */\n getCMID() {\n return this.cmid;\n }\n\n /**\n * Moves a given form element inside (a child of) a given tab element.\n *\n * Hides the 'legend' (e.g. header) element of the form element because the\n * tab has the name.\n *\n * Moves the submit button into a footer element at the bottom of the form\n * element for styling purposes.\n *\n * @method moveContentIntoTab\n * @param {jquery} tabContent The form element to move into the tab.\n * @param {jquey} tabElement The tab element for the form element to move into.\n */\n moveContentIntoTab(tabContent, tabElement) {\n // Hide the header because the tabs show us which part of the form we're\n // looking at.\n tabContent.find(SELECTORS.FORM_HEADER).addClass('hidden');\n // Move the element inside a tab.\n tabContent.wrap(tabElement);\n }\n\n /**\n * Empty the tab content container and move all tabs from the form into the\n * tab container element.\n *\n * @method moveTabsIntoTabContent\n * @param {jquery} form The form element.\n */\n moveTabsIntoTabContent(form) {\n // Empty it to remove the loading icon.\n const tabContent = this.getBody().find(SELECTORS.TAB_CONTENT).empty();\n // Make sure all tabs are inside the tab content element.\n form.find('[role=\"tabpanel\"]').wrapAll(tabContent);\n }\n\n /**\n * Make sure all of the tabs have a cancel button in their fotter to sit along\n * side the submit button.\n *\n * @method moveCancelButtonToTabs\n * @param {jquey} form The form element.\n */\n moveCancelButtonToTabs(form) {\n const cancelButton = form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass('ml-1');\n const tabFooters = form.find('[data-region=\"footer\"]');\n // Remove the buttons container element.\n cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove();\n cancelButton.clone().appendTo(tabFooters);\n }\n\n /**\n * Load the add random question form in a fragement and perform some transformation\n * on the HTML to convert it into tabs for rendering in the modal.\n *\n * @method loadForm\n * @return {promise} Resolved with form HTML and JS.\n */\n loadForm() {\n const cmid = this.getCMID();\n const cat = this.getCategory();\n const addonpage = this.getAddOnPageId();\n const returnurl = this.getReturnUrl();\n\n return Fragment.loadFragment(\n 'mod_quiz',\n 'add_random_question_form',\n this.getContextId(),\n {\n addonpage,\n cat,\n returnurl,\n cmid,\n }\n )\n .then((html, js) =>{\n const form = $(html);\n const existingCategoryTabContent = form.find(SELECTORS.EXISTING_CATEGORY_TAB);\n const existingCategoryTab = this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER);\n const newCategoryTabContent = form.find(SELECTORS.NEW_CATEGORY_TAB);\n const newCategoryTab = this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);\n\n // Transform the form into tabs for better rendering in the modal.\n this.moveContentIntoTab(existingCategoryTabContent, existingCategoryTab);\n this.moveContentIntoTab(newCategoryTabContent, newCategoryTab);\n this.moveTabsIntoTabContent(form);\n\n Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT), form, js);\n return;\n })\n .then(() => {\n // Make sure the form change checker is disabled otherwise it'll stop the user from navigating away from the\n // page once the modal is hidden.\n FormChangeChecker.disableAllChecks();\n\n // Add question to quiz.\n this.getBody()[0].addEventListener('click', (e) => {\n const button = e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT);\n if (!button) {\n return;\n }\n e.preventDefault();\n\n const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value;\n\n // Add Random questions if the add random button was clicked.\n const addRandomButton = e.target.closest(SELECTORS.ADD_RANDOM_BUTTON);\n if (addRandomButton) {\n const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition;\n\n this.addQuestions(cmid, addonpage, randomcount, filtercondition, '', '');\n return;\n }\n // Add new category if the add category button was clicked.\n const addCategoryButton = e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON);\n if (addCategoryButton) {\n this.addQuestions(\n cmid,\n addonpage,\n randomcount,\n '',\n document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,\n document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value\n );\n return;\n }\n });\n })\n .catch(Notification.exception);\n }\n\n /**\n * Call web service function to add random questions\n *\n * @param {number} cmid course module id\n * @param {number} addonpage the page where random questions will be added to\n * @param {number} randomcount Number of random questions\n * @param {string} filtercondition Filter condition\n * @param {string} newcategory add new category\n * @param {string} parentcategory parent category of new category\n */\n async addQuestions(\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory\n ) {\n // We do not need to resolve this Pending because the form submission will result in a page redirect.\n new Pending('mod-quiz/modal_add_random_questions');\n const call = {\n methodname: 'mod_quiz_add_random_questions',\n args: {\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory,\n }\n };\n try {\n const response = await fetchMany([call])[0];\n const form = document.querySelector(SELECTORS.FORM_ELEMENT);\n const messageInput = form.querySelector(SELECTORS.MESSAGE_INPUT);\n messageInput.value = response.message;\n form.submit();\n } catch (e) {\n Notification.exception(e);\n }\n }\n\n /**\n * Override the modal show function to load the form when this modal is first\n * shown.\n *\n * @method show\n */\n show() {\n super.show(this);\n\n if (!this.loadedForm) {\n this.loadForm(window.location.search);\n this.loadedForm = true;\n }\n }\n}\n\nModalAddRandomQuestion.registerModalType();\n"],"names":["SELECTORS","EXISTING_CATEGORY_CONTAINER","EXISTING_CATEGORY_TAB","NEW_CATEGORY_CONTAINER","NEW_CATEGORY_TAB","TAB_CONTENT","ADD_ON_PAGE_FORM_ELEMENT","ADD_RANDOM_BUTTON","ADD_NEW_CATEGORY_BUTTON","SUBMIT_BUTTON_ELEMENT","FORM_HEADER","SELECT_NUMBER_TO_ADD","NEW_CATEGORY_ELEMENT","PARENT_CATEGORY_ELEMENT","FILTER_CONDITION_ELEMENT","FORM_ELEMENT","MESSAGE_INPUT","ModalAddRandomQuestion","Modal","contextId","category","returnUrl","cmid","showNewCategory","document","addEventListener","e","trigger","target","closest","preventDefault","create","title","dataset","header","addOnPage","addonpage","templateContext","hidden","constructor","root","loadedForm","configure","modalConfig","setCategory","setReturnUrl","setCMID","setAddOnPageId","id","getBody","find","val","getCategory","this","url","getReturnUrl","getCMID","moveContentIntoTab","tabContent","tabElement","addClass","wrap","moveTabsIntoTabContent","form","empty","wrapAll","moveCancelButtonToTabs","cancelButton","CANCEL_BUTTON_ELEMENT","tabFooters","BUTTON_CONTAINER","remove","clone","appendTo","loadForm","cat","getAddOnPageId","returnurl","Fragment","loadFragment","getContextId","then","html","js","existingCategoryTabContent","existingCategoryTab","newCategoryTabContent","newCategoryTab","Templates","replaceNode","FormChangeChecker","disableAllChecks","randomcount","querySelector","value","filtercondition","_document$querySelect","addQuestions","catch","Notification","exception","newcategory","parentcategory","Pending","call","methodname","args","response","message","submit","show","window","location","search","registerModalType"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"modal_add_random_question.min.js","sources":["../src/modal_add_random_question.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 .\n\n/**\n * Contain the logic for the add random question modal.\n *\n * @module mod_quiz/modal_add_random_question\n * @copyright 2018 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Modal from './add_question_modal';\nimport * as Notification from 'core/notification';\nimport * as Fragment from 'core/fragment';\nimport * as Templates from 'core/templates';\nimport * as FormChangeChecker from 'core_form/changechecker';\nimport {call as fetchMany} from 'core/ajax';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n EXISTING_CATEGORY_CONTAINER: '[data-region=\"existing-category-container\"]',\n EXISTING_CATEGORY_TAB: '#id_existingcategoryheader',\n NEW_CATEGORY_CONTAINER: '[data-region=\"new-category-container\"]',\n NEW_CATEGORY_TAB: '#id_newcategoryheader',\n TAB_CONTENT: '[data-region=\"tab-content\"]',\n ADD_ON_PAGE_FORM_ELEMENT: '[name=\"addonpage\"]',\n ADD_RANDOM_BUTTON: 'input[type=\"submit\"][name=\"addrandom\"]',\n ADD_NEW_CATEGORY_BUTTON: 'input[type=\"submit\"][name=\"newcategory\"]',\n SUBMIT_BUTTON_ELEMENT: 'input[type=\"submit\"][name=\"addrandom\"], input[type=\"submit\"][name=\"newcategory\"]',\n FORM_HEADER: 'legend',\n SELECT_NUMBER_TO_ADD: '#menurandomcount',\n NEW_CATEGORY_ELEMENT: '#categoryname',\n PARENT_CATEGORY_ELEMENT: '#parentcategory',\n FILTER_CONDITION_ELEMENT: '[data-filtercondition]',\n FORM_ELEMENT: '#add_random_question_form',\n MESSAGE_INPUT: '[name=\"message\"]',\n};\n\nexport default class ModalAddRandomQuestion extends Modal {\n static TYPE = 'mod_quiz-quiz-add-random-question';\n static TEMPLATE = 'mod_quiz/modal_add_random_question';\n\n /**\n * Create the add random question modal.\n *\n * @param {Number} contextId Current context id.\n * @param {string} category Category id and category context id comma separated.\n * @param {string} returnUrl URL to return to after form submission.\n * @param {Number} cmid Current course module id.\n * @param {boolean} showNewCategory Display the New category tab when selecting random questions.\n */\n static init(contextId, category, returnUrl, cmid, showNewCategory = true) {\n const selector = '.menu [data-action=\"addarandomquestion\"]';\n document.addEventListener('click', (e) => {\n const trigger = e.target.closest(selector);\n if (!trigger) {\n return;\n }\n e.preventDefault();\n\n ModalAddRandomQuestion.create({\n contextId,\n category,\n returnUrl,\n cmid,\n\n title: trigger.dataset.header,\n addOnPage: trigger.dataset.addonpage,\n\n templateContext: {\n hidden: showNewCategory,\n },\n });\n });\n }\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n constructor(root) {\n super(root);\n this.category = null;\n this.returnUrl = null;\n this.cmid = null;\n this.loadedForm = false;\n }\n\n configure(modalConfig) {\n this.setCategory(modalConfig.category);\n this.setReturnUrl(modalConfig.returnUrl);\n this.setCMID(modalConfig.cmid);\n\n super.configure(modalConfig);\n }\n\n /**\n * Set the id of the page that the question should be added to\n * when the user clicks the add to quiz link.\n *\n * @method setAddOnPageId\n * @param {int} id\n */\n setAddOnPageId(id) {\n super.setAddOnPageId(id);\n this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id);\n }\n\n /**\n * Set the category for this form. The category is a comma separated\n * category id and category context id.\n *\n * @method setCategory\n * @param {string} category\n */\n setCategory(category) {\n this.category = category;\n }\n\n /**\n * Returns the saved category.\n *\n * @method getCategory\n * @return {string}\n */\n getCategory() {\n return this.category;\n }\n\n /**\n * Set the return URL for the form.\n *\n * @method setReturnUrl\n * @param {string} url\n */\n setReturnUrl(url) {\n this.returnUrl = url;\n }\n\n /**\n * Returns the return URL for the form.\n *\n * @method getReturnUrl\n * @return {string}\n */\n getReturnUrl() {\n return this.returnUrl;\n }\n\n /**\n * Set the course module id for the form.\n *\n * @method setCMID\n * @param {Number} id\n */\n setCMID(id) {\n this.cmid = id;\n }\n\n /**\n * Returns the course module id for the form.\n *\n * @method getCMID\n * @return {Number}\n */\n getCMID() {\n return this.cmid;\n }\n\n /**\n * Moves a given form element inside (a child of) a given tab element.\n *\n * Hides the 'legend' (e.g. header) element of the form element because the\n * tab has the name.\n *\n * Moves the submit button into a footer element at the bottom of the form\n * element for styling purposes.\n *\n * @method moveContentIntoTab\n * @param {jquery} tabContent The form element to move into the tab.\n * @param {jquey} tabElement The tab element for the form element to move into.\n */\n moveContentIntoTab(tabContent, tabElement) {\n // Hide the header because the tabs show us which part of the form we're\n // looking at.\n tabContent.find(SELECTORS.FORM_HEADER).addClass('hidden');\n // Move the element inside a tab.\n tabContent.wrap(tabElement);\n }\n\n /**\n * Empty the tab content container and move all tabs from the form into the\n * tab container element.\n *\n * @method moveTabsIntoTabContent\n * @param {jquery} form The form element.\n */\n moveTabsIntoTabContent(form) {\n // Empty it to remove the loading icon.\n const tabContent = this.getBody().find(SELECTORS.TAB_CONTENT).empty();\n // Make sure all tabs are inside the tab content element.\n form.find('[role=\"tabpanel\"]').wrapAll(tabContent);\n }\n\n /**\n * Make sure all of the tabs have a cancel button in their fotter to sit along\n * side the submit button.\n *\n * @method moveCancelButtonToTabs\n * @param {jquey} form The form element.\n */\n moveCancelButtonToTabs(form) {\n const cancelButton = form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass('ml-1');\n const tabFooters = form.find('[data-region=\"footer\"]');\n // Remove the buttons container element.\n cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove();\n cancelButton.clone().appendTo(tabFooters);\n }\n\n /**\n * Load the add random question form in a fragement and perform some transformation\n * on the HTML to convert it into tabs for rendering in the modal.\n *\n * @method loadForm\n * @return {promise} Resolved with form HTML and JS.\n */\n loadForm() {\n const cmid = this.getCMID();\n const cat = this.getCategory();\n const addonpage = this.getAddOnPageId();\n const returnurl = this.getReturnUrl();\n\n return Fragment.loadFragment(\n 'mod_quiz',\n 'add_random_question_form',\n this.getContextId(),\n {\n addonpage,\n cat,\n returnurl,\n cmid,\n }\n )\n .then((html, js) =>{\n const form = $(html);\n const existingCategoryTabContent = form.find(SELECTORS.EXISTING_CATEGORY_TAB);\n const existingCategoryTab = this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER);\n const newCategoryTabContent = form.find(SELECTORS.NEW_CATEGORY_TAB);\n const newCategoryTab = this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);\n\n // Transform the form into tabs for better rendering in the modal.\n this.moveContentIntoTab(existingCategoryTabContent, existingCategoryTab);\n this.moveContentIntoTab(newCategoryTabContent, newCategoryTab);\n this.moveTabsIntoTabContent(form);\n\n Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT), form, js);\n return;\n })\n .then(() => {\n // Make sure the form change checker is disabled otherwise it'll stop the user from navigating away from the\n // page once the modal is hidden.\n FormChangeChecker.disableAllChecks();\n\n // Add question to quiz.\n this.getBody()[0].addEventListener('click', (e) => {\n const button = e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT);\n if (!button) {\n return;\n }\n e.preventDefault();\n\n // Add Random questions if the add random button was clicked.\n const addRandomButton = e.target.closest(SELECTORS.ADD_RANDOM_BUTTON);\n if (addRandomButton) {\n const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value;\n const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition;\n\n this.addQuestions(cmid, addonpage, randomcount, filtercondition, '', '');\n return;\n }\n // Add new category if the add category button was clicked.\n const addCategoryButton = e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON);\n if (addCategoryButton) {\n this.addQuestions(\n cmid,\n addonpage,\n 1,\n '',\n document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,\n document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value\n );\n return;\n }\n });\n })\n .catch(Notification.exception);\n }\n\n /**\n * Call web service function to add random questions\n *\n * @param {number} cmid course module id\n * @param {number} addonpage the page where random questions will be added to\n * @param {number} randomcount Number of random questions\n * @param {string} filtercondition Filter condition\n * @param {string} newcategory add new category\n * @param {string} parentcategory parent category of new category\n */\n async addQuestions(\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory\n ) {\n // We do not need to resolve this Pending because the form submission will result in a page redirect.\n new Pending('mod-quiz/modal_add_random_questions');\n const call = {\n methodname: 'mod_quiz_add_random_questions',\n args: {\n cmid,\n addonpage,\n randomcount,\n filtercondition,\n newcategory,\n parentcategory,\n }\n };\n try {\n const response = await fetchMany([call])[0];\n const form = document.querySelector(SELECTORS.FORM_ELEMENT);\n const messageInput = form.querySelector(SELECTORS.MESSAGE_INPUT);\n messageInput.value = response.message;\n form.submit();\n } catch (e) {\n Notification.exception(e);\n }\n }\n\n /**\n * Override the modal show function to load the form when this modal is first\n * shown.\n *\n * @method show\n */\n show() {\n super.show(this);\n\n if (!this.loadedForm) {\n this.loadForm(window.location.search);\n this.loadedForm = true;\n }\n }\n}\n\nModalAddRandomQuestion.registerModalType();\n"],"names":["SELECTORS","EXISTING_CATEGORY_CONTAINER","EXISTING_CATEGORY_TAB","NEW_CATEGORY_CONTAINER","NEW_CATEGORY_TAB","TAB_CONTENT","ADD_ON_PAGE_FORM_ELEMENT","ADD_RANDOM_BUTTON","ADD_NEW_CATEGORY_BUTTON","SUBMIT_BUTTON_ELEMENT","FORM_HEADER","SELECT_NUMBER_TO_ADD","NEW_CATEGORY_ELEMENT","PARENT_CATEGORY_ELEMENT","FILTER_CONDITION_ELEMENT","FORM_ELEMENT","MESSAGE_INPUT","ModalAddRandomQuestion","Modal","contextId","category","returnUrl","cmid","showNewCategory","document","addEventListener","e","trigger","target","closest","preventDefault","create","title","dataset","header","addOnPage","addonpage","templateContext","hidden","constructor","root","loadedForm","configure","modalConfig","setCategory","setReturnUrl","setCMID","setAddOnPageId","id","getBody","find","val","getCategory","this","url","getReturnUrl","getCMID","moveContentIntoTab","tabContent","tabElement","addClass","wrap","moveTabsIntoTabContent","form","empty","wrapAll","moveCancelButtonToTabs","cancelButton","CANCEL_BUTTON_ELEMENT","tabFooters","BUTTON_CONTAINER","remove","clone","appendTo","loadForm","cat","getAddOnPageId","returnurl","Fragment","loadFragment","getContextId","then","html","js","existingCategoryTabContent","existingCategoryTab","newCategoryTabContent","newCategoryTab","Templates","replaceNode","FormChangeChecker","disableAllChecks","randomcount","querySelector","value","filtercondition","_document$querySelect","addQuestions","catch","Notification","exception","newcategory","parentcategory","Pending","call","methodname","args","response","message","submit","show","window","location","search","registerModalType"],"mappings":"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"} \ No newline at end of file diff --git a/mod/quiz/amd/src/modal_add_random_question.js b/mod/quiz/amd/src/modal_add_random_question.js index 8a572b23032..151e81316d6 100644 --- a/mod/quiz/amd/src/modal_add_random_question.js +++ b/mod/quiz/amd/src/modal_add_random_question.js @@ -283,11 +283,10 @@ export default class ModalAddRandomQuestion extends Modal { } e.preventDefault(); - const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value; - // Add Random questions if the add random button was clicked. const addRandomButton = e.target.closest(SELECTORS.ADD_RANDOM_BUTTON); if (addRandomButton) { + const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value; const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition; this.addQuestions(cmid, addonpage, randomcount, filtercondition, '', ''); @@ -299,7 +298,7 @@ export default class ModalAddRandomQuestion extends Modal { this.addQuestions( cmid, addonpage, - randomcount, + 1, '', document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value, document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value