diff --git a/server/moodle/mod/livequiz/amd/build/create_question.min.js.map b/server/moodle/mod/livequiz/amd/build/create_question.min.js.map index e956b7f0b..4419e861c 100644 --- a/server/moodle/mod/livequiz/amd/build/create_question.min.js.map +++ b/server/moodle/mod/livequiz/amd/build/create_question.min.js.map @@ -1 +1 @@ -{"version":3,"file":"create_question.min.js","sources":["../src/create_question.js"],"sourcesContent":["import Templates from \"core/templates\";\nimport { exception as displayException } from \"core/notification\";\nimport { save_question } from \"./repository\";\nimport { add_delete_question_listeners } from \"./delete_question\";\nimport { add_edit_question_listeners } from \"./edit_question\";\nimport {\n rerender_take_quiz_button,\n rerender_saved_questions_list,\n add_answer_button_event_listener,\n add_cancel_edit_button_listener,\n validate_submission,\n} from \"./edit_question_helper\";\n\nlet isEditing = false;\nlet editingIndex = 0;\nlet answer_count = 0;\nlet IDs = 0;\nlet take_quiz_url = \"\";\n\n/**\n * Adds an event listener to the \"Add Question\" button.\n * When the button is clicked, it renders the create question menu popup.\n *\n * @param {number} quizid - The ID of the quiz.\n * @param {number} lecturerid - The ID of the lecturer.\n * @param {string} url - The URL to the quiz attempt page.\n * @returns {Promise} A promise that resolves when the initialization is complete.\n */\nexport const init = async (quizid, lecturerid, url) => {\n take_quiz_url = url; //Set url to quiz attempt page to global variable\n let add_question_button = document.getElementById(\"id_buttonaddquestion\");\n add_question_button.addEventListener(\"click\", () => {\n render_create_question_menu_popup(quizid, lecturerid);\n });\n};\n\n/**\n * Renders the create question menu popup for a live quiz.\n *\n * This function loads and renders the question menu popup template, appends it to the main container,\n * Sets up event listeners for adding answers, saving the question, and discarding the question.\n *\n * @param {number} quizid - The ID of the quiz.\n * @param {number} lecturerid - The ID of the lecturer.\n * @returns {void}\n */\nfunction render_create_question_menu_popup(quizid, lecturerid) {\n // This will call the function to load and render our template.\n if(!document.querySelector('.Modal_div')){\n Templates.renderForPromise(\"mod_livequiz/question_menu_popup\")\n\n // It returns a promise that needs to be resoved.\n .then(({ html, js }) => {\n // Here we have compiled template.\n Templates.appendNodeContents(\".main-container\", html, js);\n add_answer_button_event_listener();\n add_save_question_button_listener(quizid, lecturerid);\n add_cancel_edit_button_listener(\"create\");\n })\n\n // Deal with this exception (Using core/notify exception function is recommended).\n .catch((error) => displayException(error));\n }\n}\n\n/**\n * Adds an event listener to the save question button\n *\n * @param {number} quizid - The ID of the quiz.\n * @param {number} lecturerid - The ID of the lecturer.\n */\nfunction add_save_question_button_listener(quizid, lecturerid) {\n let save_question_button = document.querySelector(\".save_button\");\n save_question_button.addEventListener(\"click\", () => {\n handle_question_submission(quizid, lecturerid);\n });\n}\n\nfunction handle_question_submission(quizid, lecturerid) {\n let savedQuestion = prepare_question(); //Prepare the question object to be sent to DB\n\n if(!validate_submission(savedQuestion.answers)) {\n return;\n }\n\n let update_event_listeners = () => {\n add_edit_question_listeners(quizid, lecturerid);\n add_delete_question_listeners(quizid, lecturerid);\n }\n\n save_question(savedQuestion, lecturerid, quizid).then((questions) => {\n rerender_saved_questions_list(questions, update_event_listeners); //Re-render saved questions list\n rerender_take_quiz_button(take_quiz_url, true); //Re-render take quiz button\n });\n\n let modal_div = document.querySelector(\".backdrop\");\n modal_div.remove();\n}\n\nfunction prepare_question() {\n let question_input_title = document.getElementById(\"question_title_id\");\n let question_indput_description = document.getElementById(\n \"question_description_id\"\n );\n let question_indput_explanation = document.getElementById(\n \"question_explanation_id\"\n );\n let questionTitle = question_input_title.value.trim();\n let questionDesription = question_indput_description.value.trim();\n let questionExplanation = question_indput_explanation.value.trim();\n\n let questionType = document.getElementById(\"question_type_checkbox_id\").checked ? 1 : 0;\n\n let answers = prepare_answers();\n\n // CHECK HERE IF THE QUESTION IS VALID\n let savedQuestion = {\n id: 0,\n title: questionTitle,\n answers: answers,\n description: questionDesription,\n explanation: questionExplanation,\n type: questionType,\n };\n\n return savedQuestion;\n}\n\nfunction prepare_answers() {\n let answers = [];\n let answers_div = document.querySelector(\".all_answers_for_question_div\");\n\n for (let i = 0; i < answers_div.children.length; i++) {\n let answertext = answers_div.children[i]\n .querySelector(\".answer_input\")\n .value.trim();\n\n let iscorrect =\n answers_div.children[i].querySelector(\".answer_checkbox\").checked;\n iscorrect = iscorrect ? 1 : 0;\n\n answers.push({\n description: answertext,\n correct: iscorrect,\n explanation: \"\",\n });\n }\n return answers;\n}\n\n"],"names":["take_quiz_url","async","quizid","lecturerid","url","document","getElementById","addEventListener","querySelector","renderForPromise","then","_ref","html","js","appendNodeContents","savedQuestion","question_input_title","question_indput_description","question_indput_explanation","questionTitle","value","trim","questionDesription","questionExplanation","questionType","checked","answers","answers_div","i","children","length","answertext","iscorrect","push","description","correct","explanation","prepare_answers","id","title","type","prepare_question","update_event_listeners","questions","remove","handle_question_submission","add_save_question_button_listener","catch","error","render_create_question_menu_popup"],"mappings":"2aAiBIA,cAAgB,iBAWAC,MAAOC,OAAQC,WAAYC,OAC7CJ,cAAgBI,IACUC,SAASC,eAAe,wBAC9BC,iBAAiB,SAAS,eAeLL,OAAQC,YAE7CE,SAASG,cAAc,kCACfC,iBAAiB,oCAGxBC,MAAKC,WAACC,KAAEA,KAAFC,GAAQA,4BAEHC,mBAAmB,kBAAmBF,KAAMC,0EAiBnBX,OAAQC,YACtBE,SAASG,cAAc,gBAC7BD,iBAAiB,SAAS,eAKbL,OAAQC,gBACtCY,6BAqBAC,qBAAuBX,SAASC,eAAe,qBAC/CW,4BAA8BZ,SAASC,eACzC,2BAEEY,4BAA8Bb,SAASC,eACzC,2BAEEa,cAAgBH,qBAAqBI,MAAMC,OAC3CC,mBAAqBL,4BAA4BG,MAAMC,OACvDE,oBAAsBL,4BAA4BE,MAAMC,OAExDG,aAAenB,SAASC,eAAe,6BAA6BmB,QAAU,EAAI,EAElFC,uBAgBAA,QAAU,GACVC,YAActB,SAASG,cAAc,qCAEpC,IAAIoB,EAAI,EAAGA,EAAID,YAAYE,SAASC,OAAQF,IAAK,KAChDG,WAAaJ,YAAYE,SAASD,GACjCpB,cAAc,iBACdY,MAAMC,OAEPW,UACAL,YAAYE,SAASD,GAAGpB,cAAc,oBAAoBiB,QAC9DO,UAAYA,UAAY,EAAI,EAE1BN,QAAQO,KAAK,CACXC,YAAaH,WACbI,QAASH,UACTI,YAAa,YAGZV,QAlCOW,SAGM,CAClBC,GAAI,EACJC,MAAOpB,cACPO,QAASA,QACTQ,YAAaZ,mBACbc,YAAab,oBACbiB,KAAMhB,cA3CYiB,QAEhB,6CAAoB1B,cAAcW,oBAIlCgB,uBAAyB,oDACCxC,OAAQC,+DACND,OAAQC,2CAG1BY,cAAeZ,WAAYD,QAAQQ,MAAMiC,oEACvBA,UAAWD,4EACf1C,eAAe,MAG3BK,SAASG,cAAc,aAC7BoC,SAtBRC,CAA2B3C,OAAQC,eAlB/B2C,CAAkC5C,OAAQC,sEACV,aAIjC4C,OAAOC,QAAU,2BAAiBA,SA7BrCC,CAAkC/C,OAAQC"} \ No newline at end of file +{"version":3,"file":"create_question.min.js","sources":["../src/create_question.js"],"sourcesContent":["import Templates from \"core/templates\";\r\nimport { exception as displayException } from \"core/notification\";\r\nimport { save_question } from \"./repository\";\r\nimport { add_delete_question_listeners } from \"./delete_question\";\r\nimport { add_edit_question_listeners } from \"./edit_question\";\r\nimport {\r\n rerender_take_quiz_button,\r\n rerender_saved_questions_list,\r\n add_answer_button_event_listener,\r\n add_cancel_edit_button_listener,\r\n validate_submission,\r\n} from \"./edit_question_helper\";\r\n\r\nlet isEditing = false;\r\nlet editingIndex = 0;\r\nlet answer_count = 0;\r\nlet IDs = 0;\r\nlet take_quiz_url = \"\";\r\n\r\n/**\r\n * Adds an event listener to the \"Add Question\" button.\r\n * When the button is clicked, it renders the create question menu popup.\r\n *\r\n * @param {number} quizid - The ID of the quiz.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n * @param {string} url - The URL to the quiz attempt page.\r\n * @returns {Promise} A promise that resolves when the initialization is complete.\r\n */\r\nexport const init = async (quizid, lecturerid, url) => {\r\n take_quiz_url = url; //Set url to quiz attempt page to global variable\r\n let add_question_button = document.getElementById(\"id_buttonaddquestion\");\r\n add_question_button.addEventListener(\"click\", () => {\r\n render_create_question_menu_popup(quizid, lecturerid);\r\n });\r\n};\r\n\r\n/**\r\n * Renders the create question menu popup for a live quiz.\r\n *\r\n * This function loads and renders the question menu popup template, appends it to the main container,\r\n * Sets up event listeners for adding answers, saving the question, and discarding the question.\r\n *\r\n * @param {number} quizid - The ID of the quiz.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n * @returns {void}\r\n */\r\nfunction render_create_question_menu_popup(quizid, lecturerid) {\r\n // This will call the function to load and render our template.\r\n if(!document.querySelector('.Modal_div')){\r\n Templates.renderForPromise(\"mod_livequiz/question_menu_popup\")\r\n\r\n // It returns a promise that needs to be resoved.\r\n .then(({ html, js }) => {\r\n // Here we have compiled template.\r\n Templates.appendNodeContents(\".main-container\", html, js);\r\n add_answer_button_event_listener();\r\n add_save_question_button_listener(quizid, lecturerid);\r\n add_cancel_edit_button_listener(\"create\");\r\n })\r\n\r\n // Deal with this exception (Using core/notify exception function is recommended).\r\n .catch((error) => displayException(error));\r\n }\r\n}\r\n\r\n/**\r\n * Adds an event listener to the save question button\r\n *\r\n * @param {number} quizid - The ID of the quiz.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n */\r\nfunction add_save_question_button_listener(quizid, lecturerid) {\r\n let save_question_button = document.querySelector(\".save_button\");\r\n save_question_button.addEventListener(\"click\", () => {\r\n handle_question_submission(quizid, lecturerid);\r\n });\r\n}\r\n\r\nfunction handle_question_submission(quizid, lecturerid) {\r\n let savedQuestion = prepare_question(); //Prepare the question object to be sent to DB\r\n\r\n if(!validate_submission(savedQuestion.answers)) {\r\n return;\r\n }\r\n\r\n let update_event_listeners = () => {\r\n add_edit_question_listeners(quizid, lecturerid);\r\n add_delete_question_listeners(quizid, lecturerid);\r\n }\r\n\r\n save_question(savedQuestion, lecturerid, quizid).then((questions) => {\r\n rerender_saved_questions_list(questions, update_event_listeners); //Re-render saved questions list\r\n rerender_take_quiz_button(take_quiz_url, true); //Re-render take quiz button\r\n });\r\n\r\n let modal_div = document.querySelector(\".backdrop\");\r\n modal_div.remove();\r\n}\r\n\r\nfunction prepare_question() {\r\n let question_input_title = document.getElementById(\"question_title_id\");\r\n let question_indput_description = document.getElementById(\r\n \"question_description_id\"\r\n );\r\n let question_indput_explanation = document.getElementById(\r\n \"question_explanation_id\"\r\n );\r\n let questionTitle = question_input_title.value.trim();\r\n let questionDesription = question_indput_description.value.trim();\r\n let questionExplanation = question_indput_explanation.value.trim();\r\n\r\n let questionType = document.getElementById(\"question_type_checkbox_id\").checked ? 1 : 0;\r\n\r\n let answers = prepare_answers();\r\n\r\n // CHECK HERE IF THE QUESTION IS VALID\r\n let savedQuestion = {\r\n id: 0,\r\n title: questionTitle,\r\n answers: answers,\r\n description: questionDesription,\r\n explanation: questionExplanation,\r\n type: questionType,\r\n };\r\n\r\n return savedQuestion;\r\n}\r\n\r\nfunction prepare_answers() {\r\n let answers = [];\r\n let answers_div = document.querySelector(\".all_answers_for_question_div\");\r\n\r\n for (let i = 0; i < answers_div.children.length; i++) {\r\n let answertext = answers_div.children[i]\r\n .querySelector(\".answer_input\")\r\n .value.trim();\r\n\r\n let iscorrect =\r\n answers_div.children[i].querySelector(\".answer_checkbox\").checked;\r\n iscorrect = iscorrect ? 1 : 0;\r\n\r\n answers.push({\r\n description: answertext,\r\n correct: iscorrect,\r\n explanation: \"\",\r\n });\r\n }\r\n return answers;\r\n}\r\n\r\n"],"names":["take_quiz_url","async","quizid","lecturerid","url","document","getElementById","addEventListener","querySelector","renderForPromise","then","_ref","html","js","appendNodeContents","savedQuestion","question_input_title","question_indput_description","question_indput_explanation","questionTitle","value","trim","questionDesription","questionExplanation","questionType","checked","answers","answers_div","i","children","length","answertext","iscorrect","push","description","correct","explanation","prepare_answers","id","title","type","prepare_question","update_event_listeners","questions","remove","handle_question_submission","add_save_question_button_listener","catch","error","render_create_question_menu_popup"],"mappings":"2aAiBIA,cAAgB,iBAWAC,MAAOC,OAAQC,WAAYC,OAC7CJ,cAAgBI,IACUC,SAASC,eAAe,wBAC9BC,iBAAiB,SAAS,eAeLL,OAAQC,YAE7CE,SAASG,cAAc,kCACfC,iBAAiB,oCAGxBC,MAAKC,WAACC,KAAEA,KAAFC,GAAQA,4BAEHC,mBAAmB,kBAAmBF,KAAMC,0EAiBnBX,OAAQC,YACtBE,SAASG,cAAc,gBAC7BD,iBAAiB,SAAS,eAKbL,OAAQC,gBACtCY,6BAqBAC,qBAAuBX,SAASC,eAAe,qBAC/CW,4BAA8BZ,SAASC,eACzC,2BAEEY,4BAA8Bb,SAASC,eACzC,2BAEEa,cAAgBH,qBAAqBI,MAAMC,OAC3CC,mBAAqBL,4BAA4BG,MAAMC,OACvDE,oBAAsBL,4BAA4BE,MAAMC,OAExDG,aAAenB,SAASC,eAAe,6BAA6BmB,QAAU,EAAI,EAElFC,uBAgBAA,QAAU,GACVC,YAActB,SAASG,cAAc,qCAEpC,IAAIoB,EAAI,EAAGA,EAAID,YAAYE,SAASC,OAAQF,IAAK,KAChDG,WAAaJ,YAAYE,SAASD,GACjCpB,cAAc,iBACdY,MAAMC,OAEPW,UACAL,YAAYE,SAASD,GAAGpB,cAAc,oBAAoBiB,QAC9DO,UAAYA,UAAY,EAAI,EAE1BN,QAAQO,KAAK,CACXC,YAAaH,WACbI,QAASH,UACTI,YAAa,YAGZV,QAlCOW,SAGM,CAClBC,GAAI,EACJC,MAAOpB,cACPO,QAASA,QACTQ,YAAaZ,mBACbc,YAAab,oBACbiB,KAAMhB,cA3CYiB,QAEhB,6CAAoB1B,cAAcW,oBAIlCgB,uBAAyB,oDACCxC,OAAQC,+DACND,OAAQC,2CAG1BY,cAAeZ,WAAYD,QAAQQ,MAAMiC,oEACvBA,UAAWD,4EACf1C,eAAe,MAG3BK,SAASG,cAAc,aAC7BoC,SAtBRC,CAA2B3C,OAAQC,eAlB/B2C,CAAkC5C,OAAQC,sEACV,aAIjC4C,OAAOC,QAAU,2BAAiBA,SA7BrCC,CAAkC/C,OAAQC"} diff --git a/server/moodle/mod/livequiz/amd/build/delete_question.min.js b/server/moodle/mod/livequiz/amd/build/delete_question.min.js index 79fc40a29..d62905064 100644 --- a/server/moodle/mod/livequiz/amd/build/delete_question.min.js +++ b/server/moodle/mod/livequiz/amd/build/delete_question.min.js @@ -1,3 +1,3 @@ -define("mod_livequiz/delete_question",["exports","./repository","./edit_question_helper"],(function(_exports,_repository,_edit_question_helper){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_delete_question_listeners=add_delete_question_listeners,_exports.init=void 0;let take_quiz_url="";function add_delete_question_listeners(quizid,lecturerid){let question_list=document.getElementById("saved_questions_list");question_list.querySelectorAll(".delete-question").forEach((element=>{element.addEventListener("click",(()=>{let list_item=element.closest("li"),questionid=parseInt(element.dataset.id,10);confirm("Are you sure you want to delete this question?")&&(0,_repository.delete_question)(questionid,lecturerid,quizid).then((response=>{if(response.success){list_item.remove(),element.remove(),0===question_list.querySelectorAll("li").length&&(0,_edit_question_helper.rerender_take_quiz_button)(take_quiz_url,!1)}else alert("Cannot delete question: "+response.message)}))}))}))}_exports.init=async(quizid,lecturerid,url)=>{take_quiz_url=url,add_delete_question_listeners(quizid,lecturerid)}})); +define("mod_livequiz/delete_question",["exports","./repository","./edit_question_helper"],(function(_exports,_repository,_edit_question_helper){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_delete_question_listeners=add_delete_question_listeners,_exports.init=void 0;let take_quiz_url="";function add_delete_question_listeners(quizid,lecturerid){let question_list=document.getElementById("saved_questions_list");question_list.querySelectorAll(".delete-question").forEach((element=>{element.addEventListener("click",(()=>{let list_item=element.closest("li"),questionid=parseInt(element.dataset.id,10);confirm("Are you sure you want to delete this question?")&&(0,_repository.delete_question)(questionid,lecturerid,quizid).then((response=>{if(!response.success)throw"Cannot delete question, since it already has participations";list_item.remove(),element.remove(),0===question_list.querySelectorAll("li").length&&(0,_edit_question_helper.rerender_take_quiz_button)(take_quiz_url,!1)})).catch((error=>{alert(error)}))}))}))}_exports.init=async(quizid,lecturerid,url)=>{take_quiz_url=url,add_delete_question_listeners(quizid,lecturerid)}})); //# sourceMappingURL=delete_question.min.js.map \ No newline at end of file diff --git a/server/moodle/mod/livequiz/amd/build/delete_question.min.js.map b/server/moodle/mod/livequiz/amd/build/delete_question.min.js.map index 90581d85d..7e0c27acd 100644 --- a/server/moodle/mod/livequiz/amd/build/delete_question.min.js.map +++ b/server/moodle/mod/livequiz/amd/build/delete_question.min.js.map @@ -1 +1 @@ -{"version":3,"file":"delete_question.min.js","sources":["../src/delete_question.js"],"sourcesContent":["import { delete_question } from \"./repository\";\nimport { rerender_take_quiz_button } from \"./edit_question_helper\";\n\nlet take_quiz_url = \"\";\n\nexport const init = async (quizid, lecturerid, url) => {\n take_quiz_url = url; //Set url to quiz attempt page to global variable\n add_delete_question_listeners(quizid, lecturerid);\n};\n\nexport function add_delete_question_listeners(quizid, lecturerid) {\n let question_list = document.getElementById(\"saved_questions_list\");\n let delete_question_elements = question_list.querySelectorAll(\".delete-question\");\n\n delete_question_elements.forEach((element) => {\n element.addEventListener(\"click\", () => {\n let list_item = element.closest(\"li\"); // Get the list item.\n let questionid = parseInt(element.dataset.id, 10);\n if (!confirm(\"Are you sure you want to delete this question?\")) {\n return;\n } else {\n delete_question(questionid, lecturerid, quizid)\n .then((response) => {\n if (response.success) {\n list_item.remove(); // Remove the question from the list.\n element.remove(); // Remove the delete button.\n let updated_list_length = question_list.querySelectorAll(\"li\").length;\n if (updated_list_length === 0) {\n rerender_take_quiz_button(take_quiz_url, false);\n }\n } else {\n alert(\"Cannot delete question: \" + response.message);\n }\n });\n }\n });\n });\n}\n"],"names":["take_quiz_url","add_delete_question_listeners","quizid","lecturerid","question_list","document","getElementById","querySelectorAll","forEach","element","addEventListener","list_item","closest","questionid","parseInt","dataset","id","confirm","then","response","success","remove","length","alert","message","async","url"],"mappings":"sSAGIA,cAAgB,YAOJC,8BAA8BC,OAAQC,gBAChDC,cAAgBC,SAASC,eAAe,wBACbF,cAAcG,iBAAiB,oBAErCC,SAASC,UAChCA,QAAQC,iBAAiB,SAAS,SAC5BC,UAAYF,QAAQG,QAAQ,MAC5BC,WAAaC,SAASL,QAAQM,QAAQC,GAAI,IACnCC,QAAQ,mFAGOJ,WAAYV,WAAYD,QACnCgB,MAAMC,cACCA,SAASC,QAAS,CAClBT,UAAUU,SACVZ,QAAQY,SAEoB,IADFjB,cAAcG,iBAAiB,MAAMe,4DAEjCtB,eAAe,QAG7CuB,MAAM,2BAA6BJ,SAASK,gCA1BpDC,MAAOvB,OAAQC,WAAYuB,OAC7C1B,cAAgB0B,IAChBzB,8BAA8BC,OAAQC"} \ No newline at end of file +{"version":3,"file":"delete_question.min.js","sources":["../src/delete_question.js"],"sourcesContent":["import { delete_question } from \"./repository\";\r\nimport { rerender_take_quiz_button } from \"./edit_question_helper\";\r\n\r\nlet take_quiz_url = \"\";\r\n\r\nexport const init = async (quizid, lecturerid, url) => {\r\n take_quiz_url = url; //Set url to quiz attempt page to global variable\r\n add_delete_question_listeners(quizid, lecturerid);\r\n};\r\n\r\nexport function add_delete_question_listeners(quizid, lecturerid) {\r\n let question_list = document.getElementById(\"saved_questions_list\");\r\n let delete_question_elements = question_list.querySelectorAll(\".delete-question\");\r\n\r\n delete_question_elements.forEach((element) => {\r\n element.addEventListener(\"click\", () => {\r\n let list_item = element.closest(\"li\"); // Get the list item.\r\n let questionid = parseInt(element.dataset.id, 10);\r\n if (!confirm(\"Are you sure you want to delete this question?\")) {\r\n return;\r\n } else {\r\n delete_question(questionid, lecturerid, quizid)\r\n .then((response) => {\r\n if (response.success) {\r\n list_item.remove(); // Remove the question from the list.\r\n element.remove(); // Remove the delete button.\r\n let updated_list_length = question_list.querySelectorAll(\"li\").length;\r\n if (updated_list_length === 0) {\r\n rerender_take_quiz_button(take_quiz_url, false);\r\n }\r\n } else {\r\n throw(\"Cannot delete question, since it already has participations\");\r\n }\r\n }).catch((error) => {\r\n alert(error);\r\n });\r\n }\r\n });\r\n });\r\n}\r\n"],"names":["take_quiz_url","add_delete_question_listeners","quizid","lecturerid","question_list","document","getElementById","querySelectorAll","forEach","element","addEventListener","list_item","closest","questionid","parseInt","dataset","id","confirm","then","response","success","remove","length","catch","error","alert","async","url"],"mappings":"sSAGIA,cAAgB,YAOJC,8BAA8BC,OAAQC,gBAChDC,cAAgBC,SAASC,eAAe,wBACbF,cAAcG,iBAAiB,oBAErCC,SAASC,UAChCA,QAAQC,iBAAiB,SAAS,SAC5BC,UAAYF,QAAQG,QAAQ,MAC5BC,WAAaC,SAASL,QAAQM,QAAQC,GAAI,IACnCC,QAAQ,mFAGOJ,WAAYV,WAAYD,QACnCgB,MAAMC,eACCA,SAASC,aAQH,8DAPNT,UAAUU,SACVZ,QAAQY,SAEoB,IADFjB,cAAcG,iBAAiB,MAAMe,4DAEjCtB,eAAe,MAKlDuB,OAAOC,QACNC,MAAMD,8BA7BVE,MAAOxB,OAAQC,WAAYwB,OAC7C3B,cAAgB2B,IAChB1B,8BAA8BC,OAAQC"} \ No newline at end of file diff --git a/server/moodle/mod/livequiz/amd/build/edit_question.min.js b/server/moodle/mod/livequiz/amd/build/edit_question.min.js index b706c19a6..ee3d3775e 100644 --- a/server/moodle/mod/livequiz/amd/build/edit_question.min.js +++ b/server/moodle/mod/livequiz/amd/build/edit_question.min.js @@ -1,3 +1,3 @@ -define("mod_livequiz/edit_question",["exports","core/templates","core/notification","./repository","./edit_question_helper","./delete_question"],(function(_exports,_templates,_notification,_repository,_edit_question_helper,_delete_question){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_edit_question_listeners=add_edit_question_listeners,_exports.init=void 0,_templates=(obj=_templates)&&obj.__esModule?obj:{default:obj};function add_edit_question_listeners(quizid,lecturerid){document.getElementById("saved_questions_list").addEventListener("click",(event=>{let target=event.target;if(target.classList.contains("edit-question-btn")||target.classList.contains("question-title")){let questionid=parseInt(target.dataset.id,10);!function(quizid,lecturerid,questionid){document.querySelector(".Modal_div")||_templates.default.renderForPromise("mod_livequiz/question_menu_popup").then((_ref=>{let{html:html,js:js}=_ref;_templates.default.appendNodeContents(".main-container",html,js),(0,_repository.get_question)(quizid,questionid).then((question=>{!function(questiondata){document.getElementById("question_title_id").value=questiondata.questiontitle,document.getElementById("question_description_id").value=questiondata.questiondescription,document.getElementById("question_explanation_id").value=questiondata.questionexplanation,document.getElementById("question_type_checkbox_id").checked="radio"===questiondata.questiontype;let answers=questiondata.answers;for(let i=0;i{!function(quizid,lecturerid,questionid){let question_input_title=document.getElementById("question_title_id"),question_indput_description=document.getElementById("question_description_id"),question_indput_explanation=document.getElementById("question_explanation_id"),questionTitle=question_input_title.value.trim(),questionDescription=question_indput_description.value.trim(),questionExplanation=question_indput_explanation.value.trim(),questionType=document.getElementById("question_type_checkbox_id").checked?1:0,answers=[],answers_div=document.querySelector(".all_answers_for_question_div");for(let i=0;i{const contextsavedquestions={questions:questions};document.querySelector("#saved_questions_list").remove(),_templates.default.renderForPromise("mod_livequiz/saved_questions_list",contextsavedquestions).then((_ref2=>{let{html:html,js:js}=_ref2;_templates.default.appendNodeContents("#saved-questions-container",html,js),add_edit_question_listeners(quizid,lecturerid),(0,_delete_question.add_delete_question_listeners)(quizid,lecturerid)})).catch((error=>(0,_notification.exception)(error)))})),document.querySelector(".backdrop").remove()}(quizid,lecturerid,questionid)}))}(quizid,lecturerid,questionid),(0,_edit_question_helper.add_cancel_edit_button_listener)("edit")})).catch((error=>(0,_notification.exception)(error)))}(quizid,lecturerid,questionid)}}))}function restore_answer_data_in_popup(answer){let answer_container=(0,_edit_question_helper.create_answer_container)(answer.answerid);answer_container.querySelector(".answer_input").value=answer.answerdescription,answer_container.querySelector(".answer_checkbox").checked=answer.answercorrect,document.querySelector(".all_answers_for_question_div").appendChild(answer_container)}_exports.init=async(quizid,lecturerid)=>{add_edit_question_listeners(quizid,lecturerid)}})); +define("mod_livequiz/edit_question",["exports","core/templates","core/notification","./repository","./edit_question_helper","./delete_question"],(function(_exports,_templates,_notification,_repository,_edit_question_helper,_delete_question){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_edit_question_listeners=add_edit_question_listeners,_exports.init=void 0,_templates=(obj=_templates)&&obj.__esModule?obj:{default:obj};function add_edit_question_listeners(quizid,lecturerid){document.getElementById("saved_questions_list").addEventListener("click",(event=>{let target=event.target;if(target.classList.contains("edit-question-btn")||target.classList.contains("question-title")){let questionid=parseInt(target.dataset.id,10);!function(quizid,lecturerid,questionid){document.querySelector(".Modal_div")||_templates.default.renderForPromise("mod_livequiz/question_menu_popup").then((_ref=>{let{html:html,js:js}=_ref;_templates.default.appendNodeContents(".main-container",html,js),(0,_repository.get_question)(quizid,questionid).then((question=>{!function(questiondata){document.getElementById("question_title_id").value=questiondata.questiontitle,document.getElementById("question_description_id").value=questiondata.questiondescription,document.getElementById("question_explanation_id").value=questiondata.questionexplanation,document.getElementById("question_type_checkbox_id").checked="radio"===questiondata.questiontype;let answers=questiondata.answers;for(let i=0;i{!function(quizid,lecturerid,questionid){let question_input_title=document.getElementById("question_title_id"),question_indput_description=document.getElementById("question_description_id"),question_indput_explanation=document.getElementById("question_explanation_id"),questionTitle=question_input_title.value.trim(),questionDescription=question_indput_description.value.trim(),questionExplanation=question_indput_explanation.value.trim(),questionType=document.getElementById("question_type_checkbox_id").checked?1:0,answers=[],answers_div=document.querySelector(".all_answers_for_question_div");for(let i=0;i{const contextsavedquestions={questions:questions};document.querySelector("#saved_questions_list").remove(),_templates.default.renderForPromise("mod_livequiz/saved_questions_list",contextsavedquestions).then((_ref2=>{let{html:html,js:js}=_ref2;_templates.default.appendNodeContents("#saved-questions-container",html,js),add_edit_question_listeners(quizid,lecturerid),(0,_delete_question.add_delete_question_listeners)(quizid,lecturerid)})).catch((error=>(0,_notification.exception)(error)))})).catch((()=>alert("Cannot edit a question, since it already has participations"))),document.querySelector(".backdrop").remove()}(quizid,lecturerid,questionid)}))}(quizid,lecturerid,questionid),(0,_edit_question_helper.add_cancel_edit_button_listener)("edit")})).catch((error=>(0,_notification.exception)(error)))}(quizid,lecturerid,questionid)}}))}function restore_answer_data_in_popup(answer){let answer_container=(0,_edit_question_helper.create_answer_container)(answer.answerid);answer_container.querySelector(".answer_input").value=answer.answerdescription,answer_container.querySelector(".answer_checkbox").checked=answer.answercorrect,document.querySelector(".all_answers_for_question_div").appendChild(answer_container)}_exports.init=async(quizid,lecturerid)=>{add_edit_question_listeners(quizid,lecturerid)}})); //# sourceMappingURL=edit_question.min.js.map \ No newline at end of file diff --git a/server/moodle/mod/livequiz/amd/build/edit_question.min.js.map b/server/moodle/mod/livequiz/amd/build/edit_question.min.js.map index b2f17860b..2ef13e480 100644 --- a/server/moodle/mod/livequiz/amd/build/edit_question.min.js.map +++ b/server/moodle/mod/livequiz/amd/build/edit_question.min.js.map @@ -1 +1 @@ -{"version":3,"file":"edit_question.min.js","sources":["../src/edit_question.js"],"sourcesContent":["import Templates from \"core/templates\";\nimport { exception as displayException } from \"core/notification\";\nimport { save_question, get_question} from \"./repository\";\nimport {\n add_answer_button_event_listener,\n create_answer_container,\n add_cancel_edit_button_listener,\n validate_submission} from \"./edit_question_helper\";\nimport {add_delete_question_listeners} from \"./delete_question\";\n\nexport const init = async (quizid, lecturerid) => {\n add_edit_question_listeners(quizid, lecturerid);\n};\n\nexport function add_edit_question_listeners(quizid, lecturerid) {\n let question_list = document.getElementById(\"saved_questions_list\");\n question_list.addEventListener(\"click\", (event) => {\n let target = event.target;\n if(target.classList.contains(\"edit-question-btn\") || target.classList.contains(\"question-title\")) {\n let questionid = parseInt(target.dataset.id, 10);\n render_edit_question_menu_popup(quizid, lecturerid, questionid);\n }\n });\n}\n\nfunction render_edit_question_menu_popup(quizid, lecturerid, questionid) {\n\nif(!document.querySelector('.Modal_div')){\n // This will call the function to load and render our template.\n Templates.renderForPromise(\"mod_livequiz/question_menu_popup\")\n\n // It returns a promise that needs to be resolved.\n .then(({ html, js }) => {\n // Here we have the compiled template.\n Templates.appendNodeContents(\".main-container\", html, js);\n get_question(quizid, questionid).then((question)=> {restore_question_data_in_popup(question);});\n add_answer_button_event_listener();\n add_save_question_button_listener(quizid, lecturerid, questionid);\n add_cancel_edit_button_listener(\"edit\");\n })\n\n // Deal with this exception (Using core/notify exception function is recommended).\n .catch((error) => displayException(error));\n }\n}\n\nfunction add_save_question_button_listener(quizid, lecturerid, questionid) {\n let save_question_button = document.querySelector(\".save_button\");\n save_question_button.addEventListener(\"click\", () => {\n on_save_question_button_clicked(quizid, lecturerid, questionid);\n });\n}\n\nfunction on_save_question_button_clicked(quizid, lecturerid, questionid) {\n let question_input_title = document.getElementById(\"question_title_id\");\n let question_indput_description = document.getElementById(\"question_description_id\");\n let question_indput_explanation = document.getElementById(\"question_explanation_id\");\n let questionTitle = question_input_title.value.trim();\n let questionDescription = question_indput_description.value.trim();\n let questionExplanation = question_indput_explanation.value.trim();\n let questionType = document.getElementById(\"question_type_checkbox_id\").checked ? 1 : 0;\n\n let answers = [];\n let answers_div = document.querySelector(\".all_answers_for_question_div\");\n for (let i = 0; i < answers_div.children.length; i++) {\n let answertext = answers_div.children[i]\n .querySelector(\".answer_input\")\n .value.trim();\n\n let iscorrect =\n answers_div.children[i].querySelector(\".answer_checkbox\").checked;\n iscorrect = iscorrect ? 1 : 0;\n\n answers.push({\n description: answertext,\n correct: iscorrect,\n explanation: \"\",\n });\n }\n\n let savedQuestion = {\n id: questionid,\n title: questionTitle,\n answers: answers,\n description: questionDescription,\n explanation: questionExplanation,\n type: questionType,\n };\n\n if(!validate_submission(savedQuestion.answers)) {\n return;\n }\n\n save_question(savedQuestion, lecturerid, quizid).then((questions) => {\n const contextsavedquestions = {\n questions: questions,\n };\n\n //Remove the saved questions list.\n let questions_list = document.querySelector(\"#saved_questions_list\");\n questions_list.remove();\n\n //Re-render saved questions list.\n Templates.renderForPromise(\n \"mod_livequiz/saved_questions_list\",\n contextsavedquestions\n )\n .then(({ html, js }) => {\n Templates.appendNodeContents(\"#saved-questions-container\", html, js);\n add_edit_question_listeners(quizid, lecturerid);\n add_delete_question_listeners(quizid,lecturerid);\n })\n .catch((error) => displayException(error));\n });\n //Remove edit question pop-up\n let modal_div = document.querySelector(\".backdrop\");\n modal_div.remove();\n}\nfunction restore_question_data_in_popup(questiondata){\n document.getElementById(\"question_title_id\").value = questiondata.questiontitle;\n document.getElementById(\"question_description_id\").value = questiondata.questiondescription;\n document.getElementById(\"question_explanation_id\").value = questiondata.questionexplanation;\n document.getElementById(\"question_type_checkbox_id\").checked = questiondata.questiontype === 'radio';\n let answers = questiondata.answers;\n for(let i=0; i < answers.length; i++){\n restore_answer_data_in_popup(answers[i]);\n }\n}\n\nfunction restore_answer_data_in_popup(answer) {\n let answer_container = create_answer_container(answer.answerid);\n answer_container.querySelector(\".answer_input\").value = answer.answerdescription;\n answer_container.querySelector(\".answer_checkbox\").checked = answer.answercorrect;\n let parent_element = document.querySelector(\".all_answers_for_question_div\");\n parent_element.appendChild(answer_container);\n}\n\n\n\n\n\n\n\n\n"],"names":["add_edit_question_listeners","quizid","lecturerid","document","getElementById","addEventListener","event","target","classList","contains","questionid","parseInt","dataset","id","querySelector","renderForPromise","then","_ref","html","js","appendNodeContents","question","questiondata","value","questiontitle","questiondescription","questionexplanation","checked","questiontype","answers","i","length","restore_answer_data_in_popup","restore_question_data_in_popup","question_input_title","question_indput_description","question_indput_explanation","questionTitle","trim","questionDescription","questionExplanation","questionType","answers_div","children","answertext","iscorrect","push","description","correct","explanation","savedQuestion","title","type","questions","contextsavedquestions","remove","_ref2","catch","error","on_save_question_button_clicked","add_save_question_button_listener","render_edit_question_menu_popup","answer","answer_container","answerid","answerdescription","answercorrect","appendChild","async"],"mappings":"8cAcgBA,4BAA4BC,OAAQC,YAC5BC,SAASC,eAAe,wBAC9BC,iBAAiB,SAAUC,YACjCC,OAASD,MAAMC,UAChBA,OAAOC,UAAUC,SAAS,sBAAwBF,OAAOC,UAAUC,SAAS,kBAAmB,KAC1FC,WAAaC,SAASJ,OAAOK,QAAQC,GAAI,cAMhBZ,OAAQC,WAAYQ,YAEzDP,SAASW,cAAc,kCAEbC,iBAAiB,oCAGtBC,MAAKC,WAACC,KAAEA,KAAFC,GAAQA,4BAEDC,mBAAmB,kBAAmBF,KAAMC,iCACzClB,OAAQS,YAAYM,MAAMK,qBAmFXC,cACpCnB,SAASC,eAAe,qBAAqBmB,MAAQD,aAAaE,cAClErB,SAASC,eAAe,2BAA2BmB,MAAQD,aAAaG,oBACxEtB,SAASC,eAAe,2BAA2BmB,MAAQD,aAAaI,oBACxEvB,SAASC,eAAe,6BAA6BuB,QAAwC,UAA9BL,aAAaM,iBACxEC,QAAUP,aAAaO,YACvB,IAAIC,EAAE,EAAGA,EAAID,QAAQE,OAAQD,IAC7BE,6BAA6BH,QAAQC,IA1FmBG,CAA+BZ,mFAWpDpB,OAAQC,WAAYQ,YAChCP,SAASW,cAAc,gBAC7BT,iBAAiB,SAAS,eAKVJ,OAAQC,WAAYQ,gBACrDwB,qBAAuB/B,SAASC,eAAe,qBAC/C+B,4BAA8BhC,SAASC,eAAe,2BACtDgC,4BAA8BjC,SAASC,eAAe,2BACtDiC,cAAgBH,qBAAqBX,MAAMe,OAC3CC,oBAAsBJ,4BAA4BZ,MAAMe,OACxDE,oBAAsBJ,4BAA4Bb,MAAMe,OACxDG,aAAetC,SAASC,eAAe,6BAA6BuB,QAAU,EAAI,EAElFE,QAAU,GACVa,YAAcvC,SAASW,cAAc,qCACpC,IAAIgB,EAAI,EAAGA,EAAIY,YAAYC,SAASZ,OAAQD,IAAK,KAC9Cc,WAAaF,YAAYC,SAASb,GACjChB,cAAc,iBACdS,MAAMe,OAEPO,UACAH,YAAYC,SAASb,GAAGhB,cAAc,oBAAoBa,QAC9DkB,UAAYA,UAAY,EAAI,EAE5BhB,QAAQiB,KAAK,CACTC,YAAaH,WACbI,QAASH,UACTI,YAAa,SAIjBC,cAAgB,CAChBrC,GAAIH,WACJyC,MAAOd,cACPR,QAASA,QACTkB,YAAaR,oBACbU,YAAaT,oBACbY,KAAMX,mBAGN,6CAAoBS,cAAcrB,8CAIxBqB,cAAehD,WAAYD,QAAQe,MAAMqC,kBAC7CC,sBAAwB,CAC1BD,UAAWA,WAIMlD,SAASW,cAAc,yBAC7ByC,4BAGLxC,iBACN,oCACAuC,uBAECtC,MAAKwC,YAACtC,KAAEA,KAAFC,GAAQA,6BACDC,mBAAmB,6BAA8BF,KAAMC,IACjEnB,4BAA4BC,OAAQC,+DACND,OAAOC,eAExCuD,OAAOC,QAAU,2BAAiBA,YAG3BvD,SAASW,cAAc,aAC7ByC,SAnENI,CAAgC1D,OAAQC,WAAYQ,eAZhDkD,CAAkC3D,OAAQC,WAAYQ,sEACtB,WAIrC+C,OAAOC,QAAU,2BAAiBA,SAtB7BG,CAAgC5D,OAAQC,WAAYQ,yBA6GvDsB,6BAA6B8B,YAC9BC,kBAAmB,iDAAwBD,OAAOE,UACtDD,iBAAiBjD,cAAc,iBAAiBS,MAAQuC,OAAOG,kBAC/DF,iBAAiBjD,cAAc,oBAAoBa,QAAUmC,OAAOI,cAC/C/D,SAASW,cAAc,iCAC7BqD,YAAYJ,gCA5HXK,MAAOnE,OAAQC,cAC/BF,4BAA4BC,OAAQC"} \ No newline at end of file +{"version":3,"file":"edit_question.min.js","sources":["../src/edit_question.js"],"sourcesContent":["import Templates from \"core/templates\";\r\nimport { exception as displayException } from \"core/notification\";\r\nimport { save_question, get_question} from \"./repository\";\r\nimport {\r\n add_answer_button_event_listener,\r\n create_answer_container,\r\n add_cancel_edit_button_listener,\r\n validate_submission} from \"./edit_question_helper\";\r\nimport {add_delete_question_listeners} from \"./delete_question\";\r\n\r\nexport const init = async (quizid, lecturerid) => {\r\n add_edit_question_listeners(quizid, lecturerid);\r\n};\r\n\r\nexport function add_edit_question_listeners(quizid, lecturerid) {\r\n let question_list = document.getElementById(\"saved_questions_list\");\r\n question_list.addEventListener(\"click\", (event) => {\r\n let target = event.target;\r\n if(target.classList.contains(\"edit-question-btn\") || target.classList.contains(\"question-title\")) {\r\n let questionid = parseInt(target.dataset.id, 10);\r\n render_edit_question_menu_popup(quizid, lecturerid, questionid);\r\n }\r\n });\r\n}\r\n\r\nfunction render_edit_question_menu_popup(quizid, lecturerid, questionid) {\r\n\r\nif(!document.querySelector('.Modal_div')){\r\n // This will call the function to load and render our template.\r\n Templates.renderForPromise(\"mod_livequiz/question_menu_popup\")\r\n\r\n // It returns a promise that needs to be resolved.\r\n .then(({ html, js }) => {\r\n // Here we have the compiled template.\r\n Templates.appendNodeContents(\".main-container\", html, js);\r\n get_question(quizid, questionid).then((question)=> {restore_question_data_in_popup(question);});\r\n add_answer_button_event_listener();\r\n add_save_question_button_listener(quizid, lecturerid, questionid);\r\n add_cancel_edit_button_listener(\"edit\");\r\n })\r\n\r\n // Deal with this exception (Using core/notify exception function is recommended).\r\n .catch((error) => displayException(error));\r\n }\r\n}\r\n\r\nfunction add_save_question_button_listener(quizid, lecturerid, questionid) {\r\n let save_question_button = document.querySelector(\".save_button\");\r\n save_question_button.addEventListener(\"click\", () => {\r\n on_save_question_button_clicked(quizid, lecturerid, questionid);\r\n });\r\n}\r\n\r\nfunction on_save_question_button_clicked(quizid, lecturerid, questionid) {\r\n let question_input_title = document.getElementById(\"question_title_id\");\r\n let question_indput_description = document.getElementById(\"question_description_id\");\r\n let question_indput_explanation = document.getElementById(\"question_explanation_id\");\r\n let questionTitle = question_input_title.value.trim();\r\n let questionDescription = question_indput_description.value.trim();\r\n let questionExplanation = question_indput_explanation.value.trim();\r\n let questionType = document.getElementById(\"question_type_checkbox_id\").checked ? 1 : 0;\r\n\r\n let answers = [];\r\n let answers_div = document.querySelector(\".all_answers_for_question_div\");\r\n for (let i = 0; i < answers_div.children.length; i++) {\r\n let answertext = answers_div.children[i]\r\n .querySelector(\".answer_input\")\r\n .value.trim();\r\n\r\n let iscorrect =\r\n answers_div.children[i].querySelector(\".answer_checkbox\").checked;\r\n iscorrect = iscorrect ? 1 : 0;\r\n\r\n answers.push({\r\n description: answertext,\r\n correct: iscorrect,\r\n explanation: \"\",\r\n });\r\n }\r\n\r\n let savedQuestion = {\r\n id: questionid,\r\n title: questionTitle,\r\n answers: answers,\r\n description: questionDescription,\r\n explanation: questionExplanation,\r\n type: questionType,\r\n };\r\n\r\n if(!validate_submission(savedQuestion.answers)) {\r\n return;\r\n }\r\n\r\n save_question(savedQuestion, lecturerid, quizid)\r\n .then((questions) => {\r\n const contextsavedquestions = {\r\n questions: questions,\r\n };\r\n\r\n //Remove the saved questions list.\r\n let questions_list = document.querySelector(\"#saved_questions_list\");\r\n questions_list.remove();\r\n\r\n //Re-render saved questions list.\r\n Templates.renderForPromise(\r\n \"mod_livequiz/saved_questions_list\",\r\n contextsavedquestions\r\n )\r\n .then(({ html, js }) => {\r\n Templates.appendNodeContents(\"#saved-questions-container\", html, js);\r\n add_edit_question_listeners(quizid, lecturerid);\r\n add_delete_question_listeners(quizid,lecturerid);\r\n })\r\n .catch((error) => displayException(error));\r\n }).catch(() => alert(\"Cannot edit a question, since it already has participations\"));\r\n //Remove edit question pop-up\r\n let modal_div = document.querySelector(\".backdrop\");\r\n modal_div.remove();\r\n}\r\nfunction restore_question_data_in_popup(questiondata){\r\n document.getElementById(\"question_title_id\").value = questiondata.questiontitle;\r\n document.getElementById(\"question_description_id\").value = questiondata.questiondescription;\r\n document.getElementById(\"question_explanation_id\").value = questiondata.questionexplanation;\r\n document.getElementById(\"question_type_checkbox_id\").checked = questiondata.questiontype === 'radio';\r\n let answers = questiondata.answers;\r\n for(let i=0; i < answers.length; i++){\r\n restore_answer_data_in_popup(answers[i]);\r\n }\r\n}\r\n\r\nfunction restore_answer_data_in_popup(answer) {\r\n let answer_container = create_answer_container(answer.answerid);\r\n answer_container.querySelector(\".answer_input\").value = answer.answerdescription;\r\n answer_container.querySelector(\".answer_checkbox\").checked = answer.answercorrect;\r\n let parent_element = document.querySelector(\".all_answers_for_question_div\");\r\n parent_element.appendChild(answer_container);\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"],"names":["add_edit_question_listeners","quizid","lecturerid","document","getElementById","addEventListener","event","target","classList","contains","questionid","parseInt","dataset","id","querySelector","renderForPromise","then","_ref","html","js","appendNodeContents","question","questiondata","value","questiontitle","questiondescription","questionexplanation","checked","questiontype","answers","i","length","restore_answer_data_in_popup","restore_question_data_in_popup","question_input_title","question_indput_description","question_indput_explanation","questionTitle","trim","questionDescription","questionExplanation","questionType","answers_div","children","answertext","iscorrect","push","description","correct","explanation","savedQuestion","title","type","questions","contextsavedquestions","remove","_ref2","catch","error","alert","on_save_question_button_clicked","add_save_question_button_listener","render_edit_question_menu_popup","answer","answer_container","answerid","answerdescription","answercorrect","appendChild","async"],"mappings":"8cAcgBA,4BAA4BC,OAAQC,YAC5BC,SAASC,eAAe,wBAC9BC,iBAAiB,SAAUC,YACjCC,OAASD,MAAMC,UAChBA,OAAOC,UAAUC,SAAS,sBAAwBF,OAAOC,UAAUC,SAAS,kBAAmB,KAC1FC,WAAaC,SAASJ,OAAOK,QAAQC,GAAI,cAMhBZ,OAAQC,WAAYQ,YAEzDP,SAASW,cAAc,kCAEbC,iBAAiB,oCAGtBC,MAAKC,WAACC,KAAEA,KAAFC,GAAQA,4BAEDC,mBAAmB,kBAAmBF,KAAMC,iCACzClB,OAAQS,YAAYM,MAAMK,qBAoFXC,cACpCnB,SAASC,eAAe,qBAAqBmB,MAAQD,aAAaE,cAClErB,SAASC,eAAe,2BAA2BmB,MAAQD,aAAaG,oBACxEtB,SAASC,eAAe,2BAA2BmB,MAAQD,aAAaI,oBACxEvB,SAASC,eAAe,6BAA6BuB,QAAwC,UAA9BL,aAAaM,iBACxEC,QAAUP,aAAaO,YACvB,IAAIC,EAAE,EAAGA,EAAID,QAAQE,OAAQD,IAC7BE,6BAA6BH,QAAQC,IA3FmBG,CAA+BZ,mFAWpDpB,OAAQC,WAAYQ,YAChCP,SAASW,cAAc,gBAC7BT,iBAAiB,SAAS,eAKVJ,OAAQC,WAAYQ,gBACrDwB,qBAAuB/B,SAASC,eAAe,qBAC/C+B,4BAA8BhC,SAASC,eAAe,2BACtDgC,4BAA8BjC,SAASC,eAAe,2BACtDiC,cAAgBH,qBAAqBX,MAAMe,OAC3CC,oBAAsBJ,4BAA4BZ,MAAMe,OACxDE,oBAAsBJ,4BAA4Bb,MAAMe,OACxDG,aAAetC,SAASC,eAAe,6BAA6BuB,QAAU,EAAI,EAElFE,QAAU,GACVa,YAAcvC,SAASW,cAAc,qCACpC,IAAIgB,EAAI,EAAGA,EAAIY,YAAYC,SAASZ,OAAQD,IAAK,KAC9Cc,WAAaF,YAAYC,SAASb,GACjChB,cAAc,iBACdS,MAAMe,OAEPO,UACAH,YAAYC,SAASb,GAAGhB,cAAc,oBAAoBa,QAC9DkB,UAAYA,UAAY,EAAI,EAE5BhB,QAAQiB,KAAK,CACTC,YAAaH,WACbI,QAASH,UACTI,YAAa,SAIjBC,cAAgB,CAChBrC,GAAIH,WACJyC,MAAOd,cACPR,QAASA,QACTkB,YAAaR,oBACbU,YAAaT,oBACbY,KAAMX,mBAGN,6CAAoBS,cAAcrB,8CAIxBqB,cAAehD,WAAYD,QACpCe,MAAMqC,kBACDC,sBAAwB,CAC1BD,UAAWA,WAIMlD,SAASW,cAAc,yBAC7ByC,4BAGLxC,iBACN,oCACAuC,uBAECtC,MAAKwC,YAACtC,KAAEA,KAAFC,GAAQA,6BACDC,mBAAmB,6BAA8BF,KAAMC,IACjEnB,4BAA4BC,OAAQC,+DACND,OAAOC,eAExCuD,OAAOC,QAAU,2BAAiBA,YACxCD,OAAM,IAAME,MAAM,iEAELxD,SAASW,cAAc,aAC7ByC,SApENK,CAAgC3D,OAAQC,WAAYQ,eAZhDmD,CAAkC5D,OAAQC,WAAYQ,sEACtB,WAIrC+C,OAAOC,QAAU,2BAAiBA,SAtB7BI,CAAgC7D,OAAQC,WAAYQ,yBA8GvDsB,6BAA6B+B,YAC9BC,kBAAmB,iDAAwBD,OAAOE,UACtDD,iBAAiBlD,cAAc,iBAAiBS,MAAQwC,OAAOG,kBAC/DF,iBAAiBlD,cAAc,oBAAoBa,QAAUoC,OAAOI,cAC/ChE,SAASW,cAAc,iCAC7BsD,YAAYJ,gCA7HXK,MAAOpE,OAAQC,cAC/BF,4BAA4BC,OAAQC"} \ No newline at end of file diff --git a/server/moodle/mod/livequiz/amd/build/edit_question_helper.min.js.map b/server/moodle/mod/livequiz/amd/build/edit_question_helper.min.js.map index 24a29d222..446d719a8 100644 --- a/server/moodle/mod/livequiz/amd/build/edit_question_helper.min.js.map +++ b/server/moodle/mod/livequiz/amd/build/edit_question_helper.min.js.map @@ -1 +1 @@ -{"version":3,"file":"edit_question_helper.min.js","sources":["../src/edit_question_helper.js"],"sourcesContent":["import Templates from \"core/templates\";\nimport { exception as displayException } from \"core/notification\";\n\nlet IDs = 0;\nlet isEditing = false;\nlet editingIndex = 0;\n\n/**\n * Adds an event listener to the \"Add Answer\" button.\n * When the button is clicked, it appends a new answer input field.\n */\nexport const add_answer_button_event_listener = () => {\n //Adding event listerner to add answer button\n let answer_button = document.querySelector(\".add_new_answer_to_question\");\n answer_button.addEventListener(\"click\", () => {\n append_answer_input();\n });\n};\n\n/**\n * Appends a new answer input container to the container holding all answers\n * \n * This function creates a new answer container with an incremented ID and appends it to the \n * element with the class \"all_answers_for_question_div\".\n */\nexport function append_answer_input() {\n let answer_container = create_answer_container(IDs + 1);\n let parent_element = document.querySelector(\".all_answers_for_question_div\");\n parent_element.appendChild(answer_container);\n IDs++;\n}\n\n/**\n * Creates a new answer container element.\n * THIS SHOULD PROBABLY BE MADE INTO MUSTACHE TEMPLATE INSTEAD OF A FUNCTION\n *\n * @param {string} id - The unique identifier for the answer container.\n * @returns {HTMLDivElement} The created answer container element.\n */\nexport function create_answer_container(id) {\n let answer_container = document.createElement(\"div\");\n answer_container.className = \"container_for_new_answer\";\n\n let answer_input = document.createElement(\"input\");\n answer_input.className = \"answer_input\";\n answer_input.placeholder = \"Enter answer\";\n answer_input.id = \"answer_input_\" + id;\n answer_input.setAttribute(\"required\", true);\n\n let answer_checkbox = document.createElement(\"input\");\n answer_checkbox.setAttribute(\"type\", \"checkbox\");\n answer_checkbox.className = \"answer_checkbox\";\n answer_checkbox.id = \"answer_checkbox_\" + id;\n\n let delete_answer_button = create_element(\n \"delete_answer_button\",\n \"button\",\n \"delete_answer_button\",\n \"X\"\n );\n delete_answer_button.id = \"delete_answer_button_\" + id;\n\n answer_container.appendChild(answer_checkbox);\n answer_container.appendChild(answer_input);\n answer_container.appendChild(delete_answer_button);\n\n delete_answer_button.addEventListener(\"click\", () => {\n answer_container.remove();\n });\n return answer_container;\n}\n\n/**\n * Creates a new HTML element with the specified type, class, and content.\n *\n * @param {HTMLElement} element_name - The variable to hold the created element.\n * @param {string} type - The type of the HTML element to create (e.g., 'div', 'span').\n * @param {string} class_name - The class name to assign to the created element.\n * @param {string} content - The text content to set for the created element.\n * @returns {HTMLElement} The newly created HTML element.\n */\nfunction create_element(element_name, type, class_name, content) {\n element_name = document.createElement(type);\n element_name.className = class_name;\n element_name.textContent = content;\n return element_name;\n}\n\n/**\n * Rerenders the saved questions list.\n *\n * This function removes the existing saved questions list from the DOM,\n * Renders the \"mod_livequiz/saved_questions_list\" template with the provided questions\n * After re-rendering, it calls the provided callback function, if any.\n *\n * @param {Array} questions - An array of question objects to be rendered.\n * @param {Function} [callback] - An optional callback function to be executed after the list is re-rendered.\n */\nexport function rerender_saved_questions_list(questions, callback) {\n // The template needs to know the questions to render.\n const contextsavedquestions = {\n questions: questions,\n };\n\n // Remove the saved questions list.\n let questions_list = document.querySelector(\"#saved_questions_list\");\n questions_list.remove();\n\n // Re-render saved questions list.\n Templates.renderForPromise(\n \"mod_livequiz/saved_questions_list\",\n contextsavedquestions\n )\n .then(({ html, js }) => {\n Templates.appendNodeContents(\"#saved-questions-container\", html, js);\n\n // Call the functions in callback, this allows for custom functions to be called after the rerendering.\n if (typeof callback === \"function\") {\n callback();\n }\n })\n .catch((error) => console.log(error));\n}\n\n/**\n * Renders the \"mod_livequiz/take_quiz_button\" template based on whether there are questions in the quiz.\n *\n * @param {string} url - The URL for the \"Take Quiz\" button to redirect to.\n * @param {boolean} hasquestions - Indicates if the quiz has questions.\n * @param {function} [callback] - Optional callback function to execute after re-rendering.\n */\n\nexport function rerender_take_quiz_button(url, hasquestions, callback) {\n //The template needs to know if there are questions in the quiz.\n //If there are questions -> Create a button to redirect to the quiz.\n //If there are no questions -> Display a paragraph that says there are no questions.\n\n const contexttakequiz = {\n url: url,\n hasquestions: hasquestions,\n };\n\n if (hasquestions) {\n //Remove no question paragraph if there are questions.\n let no_question_paragraph = document.querySelector(\".no-question-text\");\n if (no_question_paragraph) {\n no_question_paragraph.remove(); //We have just added a question so remove the no question text\n } else {\n let take_quiz_button = document.querySelector(\"#takeQuizBtn\");\n take_quiz_button.remove();\n }\n } else {\n //Remove take quiz link if there are no questions\n let take_quiz_button = document.querySelector(\"#takeQuizBtn\");\n take_quiz_button.remove();\n }\n\n Templates.renderForPromise(\"mod_livequiz/take_quiz_button\", contexttakequiz)\n // It returns a promise that needs to be resoved.\n .then(({ html, js }) => {\n // Here we have compiled template.\n Templates.appendNodeContents(\"#page-mod-livequiz-quizcreator\", html, js);\n if (typeof callback === \"function\") {\n callback();\n }\n })\n\n // Deal with this exception (Using core/notify exception function is recommended).\n .catch((error) => displayException(error));\n}\n\n/**\n * Sets up the event listener for the cancel button\n * @param {string} context - The context in which the cancel button is being used.\n */\nexport function add_cancel_edit_button_listener(context) {\n let discard_question_button = document.querySelector(\n \".discard_question_button\"\n );\n let modal_div = document.querySelector(\".backdrop\");\n let stringForConfirm = \"\";\n\n // Set the string for the confirm box based on the context.\n switch (context) {\n case \"create\":\n stringForConfirm = \"Are you sure you want to cancel creating the question?\";\n break;\n case \"edit\":\n stringForConfirm = \"Are you sure you want to cancel editing the question?\";\n break;\n case \"import\":\n stringForConfirm = \"Are you sure you want to cancel importing the question?\";\n break;\n default:\n stringForConfirm = \"Are you sure you want to cancel the changes made?\";\n }\n discard_question_button.addEventListener(\"click\", () => {\n if(confirm(stringForConfirm)) {\n isEditing = false;\n editingIndex = null;\n modal_div.remove();\n }\n else {\n return;\n }\n });\n}\n\n\n/**\n * This validates that all inputs to create/edit question, if not all inputs are satisfied, it will return false.\n * @param answers The answers of the question.\n * @returns {boolean} True if input fields are satisfied, false otherwise.\n */\nexport function validate_submission(answers) {\n let isValid = true; // Is the question valid.\n let answersValid = true; // Are all the answers valid.\n let questionTitle = document.getElementById(\"question_title_id\").value.trim();\n let questionTitleTextarea = document.getElementById(\"question_title_id\");\n let questionTitleAlert = document.getElementById(\"title_textarea_alert\");\n let questionDesription = document.getElementById(\"question_description_id\").value.trim();\n let questionDesriptionTextarea = document.getElementById(\"question_description_id\");\n let questionDescriptionAlert = document.getElementById(\"question_textarea_alert\");\n let atLeastOneCorrectAnswerAlert = document.getElementById(\"question_alert_one_correct\");\n let answerDescriptionAlert = document.getElementById(\"question_alert_description\");\n let atLeastTwoAnswersAlert = document.getElementById(\"question_alert_two_answers\");\n let maxOneCorrectAnswerAlert = document.getElementById(\"question_alert_max_one_correct\");\n let questionType = document.getElementById(\"question_type_checkbox_id\").checked;\n let answersBox = document.getElementById(\"all_answers\");\n let isValidText = document.getElementById(\"validText\");\n\n // Function to set the border style of an element.\n const setBorderStyle = (element, isValid) => {\n element.style.border = isValid ? \"1px solid #ccc\" : \"1px solid red\";\n };\n\n // Checks if the question title is empty.\n if (!questionTitle) {\n setBorderStyle(questionTitleTextarea, !!questionTitle);\n questionTitleAlert.style.display = \"block\";\n isValid = false;\n } else {\n questionTitleAlert.style.display = \"none\";\n setBorderStyle(questionTitleTextarea, true);\n }\n\n // Checks if the question description is empty.\n if (!questionDesription) {\n setBorderStyle(questionDesriptionTextarea, !!questionDesription);\n questionDescriptionAlert.style.display = \"block\";\n isValid = false;\n } else {\n questionDescriptionAlert.style.display = \"none\";\n setBorderStyle(questionDesriptionTextarea, true);\n }\n\n // Checks if there are at least two answers.\n if (answers.length < 2) {\n isValid = false;\n answersValid = false;\n atLeastTwoAnswersAlert.style.display = \"block\";\n }\n else {\n atLeastTwoAnswersAlert.style.display = \"none\";\n }\n\n // Checks if at least one answer is correct.\n if (!answers.some(answer => answer.correct === 1)) {\n isValid = false;\n answersValid = false;\n atLeastOneCorrectAnswerAlert.style.display = \"block\";\n }\n else {\n atLeastOneCorrectAnswerAlert.style.display = \"none\";\n }\n\n // Checks if all answers have a description.\n if (answers.some(answer => !answer.description.trim())) {\n isValid = false;\n answersValid = false;\n answerDescriptionAlert.style.display = \"block\";\n } else {\n answerDescriptionAlert.style.display = \"none\";\n }\n\n // Checks if multiple correct answers have been set, when not allowed to. \n if (questionType) {\n let checkedAnswers = 0;\n answers.forEach(answer => {\n checkedAnswers += answer.correct;\n });\n if (checkedAnswers > 1){\n isValid = false;\n answersValid = false;\n maxOneCorrectAnswerAlert.style.display = \"block\";\n } else {\n maxOneCorrectAnswerAlert.style.display = \"none\";\n } \n } else {\n maxOneCorrectAnswerAlert.style.display = \"none\";\n }\n\n if (!answersValid) { // If not all answers are valid show the box with warnings.\n answersBox.style.display = \"block\";\n } else {\n answersBox.style.display = \"none\";\n }\n\n if (!isValid) { // If the question is not valid show warning.\n isValidText.style.display = \"block\";\n return false;\n }\n return true;\n}\n"],"names":["context","discard_question_button","document","querySelector","modal_div","stringForConfirm","addEventListener","confirm","isEditing","editingIndex","remove","questions","callback","contextsavedquestions","renderForPromise","then","_ref","html","js","appendNodeContents","catch","error","console","log","url","hasquestions","contexttakequiz","no_question_paragraph","_ref2","answers","isValid","answersValid","questionTitle","getElementById","value","trim","questionTitleTextarea","questionTitleAlert","questionDesription","questionDesriptionTextarea","questionDescriptionAlert","atLeastOneCorrectAnswerAlert","answerDescriptionAlert","atLeastTwoAnswersAlert","maxOneCorrectAnswerAlert","questionType","checked","answersBox","isValidText","setBorderStyle","element","style","border","display","length","some","answer","correct","description","checkedAnswers","forEach","IDs","append_answer_input","answer_container","create_answer_container","appendChild","id","createElement","className","answer_input","placeholder","setAttribute","answer_checkbox","delete_answer_button","element_name","type","class_name","content","textContent"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"edit_question_helper.min.js","sources":["../src/edit_question_helper.js"],"sourcesContent":["import Templates from \"core/templates\";\r\nimport { exception as displayException } from \"core/notification\";\r\n\r\nlet IDs = 0;\r\nlet isEditing = false;\r\nlet editingIndex = 0;\r\n\r\n/**\r\n * Adds an event listener to the \"Add Answer\" button.\r\n * When the button is clicked, it appends a new answer input field.\r\n */\r\nexport const add_answer_button_event_listener = () => {\r\n //Adding event listerner to add answer button\r\n let answer_button = document.querySelector(\".add_new_answer_to_question\");\r\n answer_button.addEventListener(\"click\", () => {\r\n append_answer_input();\r\n });\r\n};\r\n\r\n/**\r\n * Appends a new answer input container to the container holding all answers\r\n * \r\n * This function creates a new answer container with an incremented ID and appends it to the \r\n * element with the class \"all_answers_for_question_div\".\r\n */\r\nexport function append_answer_input() {\r\n let answer_container = create_answer_container(IDs + 1);\r\n let parent_element = document.querySelector(\".all_answers_for_question_div\");\r\n parent_element.appendChild(answer_container);\r\n IDs++;\r\n}\r\n\r\n/**\r\n * Creates a new answer container element.\r\n * THIS SHOULD PROBABLY BE MADE INTO MUSTACHE TEMPLATE INSTEAD OF A FUNCTION\r\n *\r\n * @param {string} id - The unique identifier for the answer container.\r\n * @returns {HTMLDivElement} The created answer container element.\r\n */\r\nexport function create_answer_container(id) {\r\n let answer_container = document.createElement(\"div\");\r\n answer_container.className = \"container_for_new_answer\";\r\n\r\n let answer_input = document.createElement(\"input\");\r\n answer_input.className = \"answer_input\";\r\n answer_input.placeholder = \"Enter answer\";\r\n answer_input.id = \"answer_input_\" + id;\r\n answer_input.setAttribute(\"required\", true);\r\n\r\n let answer_checkbox = document.createElement(\"input\");\r\n answer_checkbox.setAttribute(\"type\", \"checkbox\");\r\n answer_checkbox.className = \"answer_checkbox\";\r\n answer_checkbox.id = \"answer_checkbox_\" + id;\r\n\r\n let delete_answer_button = create_element(\r\n \"delete_answer_button\",\r\n \"button\",\r\n \"delete_answer_button\",\r\n \"X\"\r\n );\r\n delete_answer_button.id = \"delete_answer_button_\" + id;\r\n\r\n answer_container.appendChild(answer_checkbox);\r\n answer_container.appendChild(answer_input);\r\n answer_container.appendChild(delete_answer_button);\r\n\r\n delete_answer_button.addEventListener(\"click\", () => {\r\n answer_container.remove();\r\n });\r\n return answer_container;\r\n}\r\n\r\n/**\r\n * Creates a new HTML element with the specified type, class, and content.\r\n *\r\n * @param {HTMLElement} element_name - The variable to hold the created element.\r\n * @param {string} type - The type of the HTML element to create (e.g., 'div', 'span').\r\n * @param {string} class_name - The class name to assign to the created element.\r\n * @param {string} content - The text content to set for the created element.\r\n * @returns {HTMLElement} The newly created HTML element.\r\n */\r\nfunction create_element(element_name, type, class_name, content) {\r\n element_name = document.createElement(type);\r\n element_name.className = class_name;\r\n element_name.textContent = content;\r\n return element_name;\r\n}\r\n\r\n/**\r\n * Rerenders the saved questions list.\r\n *\r\n * This function removes the existing saved questions list from the DOM,\r\n * Renders the \"mod_livequiz/saved_questions_list\" template with the provided questions\r\n * After re-rendering, it calls the provided callback function, if any.\r\n *\r\n * @param {Array} questions - An array of question objects to be rendered.\r\n * @param {Function} [callback] - An optional callback function to be executed after the list is re-rendered.\r\n */\r\nexport function rerender_saved_questions_list(questions, callback) {\r\n // The template needs to know the questions to render.\r\n const contextsavedquestions = {\r\n questions: questions,\r\n };\r\n\r\n // Remove the saved questions list.\r\n let questions_list = document.querySelector(\"#saved_questions_list\");\r\n questions_list.remove();\r\n\r\n // Re-render saved questions list.\r\n Templates.renderForPromise(\r\n \"mod_livequiz/saved_questions_list\",\r\n contextsavedquestions\r\n )\r\n .then(({ html, js }) => {\r\n Templates.appendNodeContents(\"#saved-questions-container\", html, js);\r\n\r\n // Call the functions in callback, this allows for custom functions to be called after the rerendering.\r\n if (typeof callback === \"function\") {\r\n callback();\r\n }\r\n })\r\n .catch((error) => console.log(error));\r\n}\r\n\r\n/**\r\n * Renders the \"mod_livequiz/take_quiz_button\" template based on whether there are questions in the quiz.\r\n *\r\n * @param {string} url - The URL for the \"Take Quiz\" button to redirect to.\r\n * @param {boolean} hasquestions - Indicates if the quiz has questions.\r\n * @param {function} [callback] - Optional callback function to execute after re-rendering.\r\n */\r\n\r\nexport function rerender_take_quiz_button(url, hasquestions, callback) {\r\n //The template needs to know if there are questions in the quiz.\r\n //If there are questions -> Create a button to redirect to the quiz.\r\n //If there are no questions -> Display a paragraph that says there are no questions.\r\n\r\n const contexttakequiz = {\r\n url: url,\r\n hasquestions: hasquestions,\r\n };\r\n\r\n if (hasquestions) {\r\n //Remove no question paragraph if there are questions.\r\n let no_question_paragraph = document.querySelector(\".no-question-text\");\r\n if (no_question_paragraph) {\r\n no_question_paragraph.remove(); //We have just added a question so remove the no question text\r\n } else {\r\n let take_quiz_button = document.querySelector(\"#takeQuizBtn\");\r\n take_quiz_button.remove();\r\n }\r\n } else {\r\n //Remove take quiz link if there are no questions\r\n let take_quiz_button = document.querySelector(\"#takeQuizBtn\");\r\n take_quiz_button.remove();\r\n }\r\n\r\n Templates.renderForPromise(\"mod_livequiz/take_quiz_button\", contexttakequiz)\r\n // It returns a promise that needs to be resoved.\r\n .then(({ html, js }) => {\r\n // Here we have compiled template.\r\n Templates.appendNodeContents(\"#page-mod-livequiz-quizcreator\", html, js);\r\n if (typeof callback === \"function\") {\r\n callback();\r\n }\r\n })\r\n\r\n // Deal with this exception (Using core/notify exception function is recommended).\r\n .catch((error) => displayException(error));\r\n}\r\n\r\n/**\r\n * Sets up the event listener for the cancel button\r\n * @param {string} context - The context in which the cancel button is being used.\r\n */\r\nexport function add_cancel_edit_button_listener(context) {\r\n let discard_question_button = document.querySelector(\r\n \".discard_question_button\"\r\n );\r\n let modal_div = document.querySelector(\".backdrop\");\r\n let stringForConfirm = \"\";\r\n\r\n // Set the string for the confirm box based on the context.\r\n switch (context) {\r\n case \"create\":\r\n stringForConfirm = \"Are you sure you want to cancel creating the question?\";\r\n break;\r\n case \"edit\":\r\n stringForConfirm = \"Are you sure you want to cancel editing the question?\";\r\n break;\r\n case \"import\":\r\n stringForConfirm = \"Are you sure you want to cancel importing the question?\";\r\n break;\r\n default:\r\n stringForConfirm = \"Are you sure you want to cancel the changes made?\";\r\n }\r\n discard_question_button.addEventListener(\"click\", () => {\r\n if(confirm(stringForConfirm)) {\r\n isEditing = false;\r\n editingIndex = null;\r\n modal_div.remove();\r\n }\r\n else {\r\n return;\r\n }\r\n });\r\n}\r\n\r\n\r\n/**\r\n * This validates that all inputs to create/edit question, if not all inputs are satisfied, it will return false.\r\n * @param answers The answers of the question.\r\n * @returns {boolean} True if input fields are satisfied, false otherwise.\r\n */\r\nexport function validate_submission(answers) {\r\n let isValid = true; // Is the question valid.\r\n let answersValid = true; // Are all the answers valid.\r\n let questionTitle = document.getElementById(\"question_title_id\").value.trim();\r\n let questionTitleTextarea = document.getElementById(\"question_title_id\");\r\n let questionTitleAlert = document.getElementById(\"title_textarea_alert\");\r\n let questionDesription = document.getElementById(\"question_description_id\").value.trim();\r\n let questionDesriptionTextarea = document.getElementById(\"question_description_id\");\r\n let questionDescriptionAlert = document.getElementById(\"question_textarea_alert\");\r\n let atLeastOneCorrectAnswerAlert = document.getElementById(\"question_alert_one_correct\");\r\n let answerDescriptionAlert = document.getElementById(\"question_alert_description\");\r\n let atLeastTwoAnswersAlert = document.getElementById(\"question_alert_two_answers\");\r\n let maxOneCorrectAnswerAlert = document.getElementById(\"question_alert_max_one_correct\");\r\n let questionType = document.getElementById(\"question_type_checkbox_id\").checked;\r\n let answersBox = document.getElementById(\"all_answers\");\r\n let isValidText = document.getElementById(\"validText\");\r\n\r\n // Function to set the border style of an element.\r\n const setBorderStyle = (element, isValid) => {\r\n element.style.border = isValid ? \"1px solid #ccc\" : \"1px solid red\";\r\n };\r\n\r\n // Checks if the question title is empty.\r\n if (!questionTitle) {\r\n setBorderStyle(questionTitleTextarea, !!questionTitle);\r\n questionTitleAlert.style.display = \"block\";\r\n isValid = false;\r\n } else {\r\n questionTitleAlert.style.display = \"none\";\r\n setBorderStyle(questionTitleTextarea, true);\r\n }\r\n\r\n // Checks if the question description is empty.\r\n if (!questionDesription) {\r\n setBorderStyle(questionDesriptionTextarea, !!questionDesription);\r\n questionDescriptionAlert.style.display = \"block\";\r\n isValid = false;\r\n } else {\r\n questionDescriptionAlert.style.display = \"none\";\r\n setBorderStyle(questionDesriptionTextarea, true);\r\n }\r\n\r\n // Checks if there are at least two answers.\r\n if (answers.length < 2) {\r\n isValid = false;\r\n answersValid = false;\r\n atLeastTwoAnswersAlert.style.display = \"block\";\r\n }\r\n else {\r\n atLeastTwoAnswersAlert.style.display = \"none\";\r\n }\r\n\r\n // Checks if at least one answer is correct.\r\n if (!answers.some(answer => answer.correct === 1)) {\r\n isValid = false;\r\n answersValid = false;\r\n atLeastOneCorrectAnswerAlert.style.display = \"block\";\r\n }\r\n else {\r\n atLeastOneCorrectAnswerAlert.style.display = \"none\";\r\n }\r\n\r\n // Checks if all answers have a description.\r\n if (answers.some(answer => !answer.description.trim())) {\r\n isValid = false;\r\n answersValid = false;\r\n answerDescriptionAlert.style.display = \"block\";\r\n } else {\r\n answerDescriptionAlert.style.display = \"none\";\r\n }\r\n\r\n // Checks if multiple correct answers have been set, when not allowed to. \r\n if (questionType) {\r\n let checkedAnswers = 0;\r\n answers.forEach(answer => {\r\n checkedAnswers += answer.correct;\r\n });\r\n if (checkedAnswers > 1){\r\n isValid = false;\r\n answersValid = false;\r\n maxOneCorrectAnswerAlert.style.display = \"block\";\r\n } else {\r\n maxOneCorrectAnswerAlert.style.display = \"none\";\r\n } \r\n } else {\r\n maxOneCorrectAnswerAlert.style.display = \"none\";\r\n }\r\n\r\n if (!answersValid) { // If not all answers are valid show the box with warnings.\r\n answersBox.style.display = \"block\";\r\n } else {\r\n answersBox.style.display = \"none\";\r\n }\r\n\r\n if (!isValid) { // If the question is not valid show warning.\r\n isValidText.style.display = \"block\";\r\n return false;\r\n }\r\n return true;\r\n}\r\n"],"names":["context","discard_question_button","document","querySelector","modal_div","stringForConfirm","addEventListener","confirm","isEditing","editingIndex","remove","questions","callback","contextsavedquestions","renderForPromise","then","_ref","html","js","appendNodeContents","catch","error","console","log","url","hasquestions","contexttakequiz","no_question_paragraph","_ref2","answers","isValid","answersValid","questionTitle","getElementById","value","trim","questionTitleTextarea","questionTitleAlert","questionDesription","questionDesriptionTextarea","questionDescriptionAlert","atLeastOneCorrectAnswerAlert","answerDescriptionAlert","atLeastTwoAnswersAlert","maxOneCorrectAnswerAlert","questionType","checked","answersBox","isValidText","setBorderStyle","element","style","border","display","length","some","answer","correct","description","checkedAnswers","forEach","IDs","append_answer_input","answer_container","create_answer_container","appendChild","id","createElement","className","answer_input","placeholder","setAttribute","answer_checkbox","delete_answer_button","element_name","type","class_name","content","textContent"],"mappings":"4SA+KgDA,aAC1CC,wBAA0BC,SAASC,cACnC,4BAEAC,UAAYF,SAASC,cAAc,aACnCE,iBAAmB,UAGfL,aACD,SACHK,iBAAmB,mEAEhB,OACHA,iBAAmB,kEAEhB,SACHA,iBAAmB,wEAGnBA,iBAAmB,oDAEvBJ,wBAAwBK,iBAAiB,SAAS,KAC7CC,QAAQF,oBACTG,WAAY,EACZC,aAAe,KACfL,UAAUM,wKAtG8BC,UAAWC,gBAEjDC,sBAAwB,CAC5BF,UAAWA,WAIQT,SAASC,cAAc,yBAC7BO,4BAGLI,iBACR,oCACAD,uBAECE,MAAKC,WAACC,KAAEA,KAAFC,GAAQA,4BACHC,mBAAmB,6BAA8BF,KAAMC,IAGzC,mBAAbN,UACTA,cAGHQ,OAAOC,OAAUC,QAAQC,IAAIF,sDAWQG,IAAKC,aAAcb,gBAKrDc,gBAAkB,CACtBF,IAAKA,IACLC,aAAcA,iBAGZA,aAAc,KAEZE,sBAAwBzB,SAASC,cAAc,wBAC/CwB,sBACFA,sBAAsBjB,aACjB,CACkBR,SAASC,cAAc,gBAC7BO,cAEd,CAEkBR,SAASC,cAAc,gBAC7BO,4BAGTI,iBAAiB,gCAAiCY,iBAEzDX,MAAKa,YAACX,KAAEA,KAAFC,GAAQA,6BAEHC,mBAAmB,iCAAkCF,KAAMC,IAC7C,mBAAbN,UACTA,cAKHQ,OAAOC,QAAU,2BAAiBA,gDA8CHQ,aAC9BC,SAAU,EACVC,cAAe,EACfC,cAAgB9B,SAAS+B,eAAe,qBAAqBC,MAAMC,OACnEC,sBAAwBlC,SAAS+B,eAAe,qBAChDI,mBAAqBnC,SAAS+B,eAAe,wBAC7CK,mBAAqBpC,SAAS+B,eAAe,2BAA2BC,MAAMC,OAC9EI,2BAA6BrC,SAAS+B,eAAe,2BACrDO,yBAA2BtC,SAAS+B,eAAe,2BACnDQ,6BAA+BvC,SAAS+B,eAAe,8BACvDS,uBAAyBxC,SAAS+B,eAAe,8BACjDU,uBAAyBzC,SAAS+B,eAAe,8BACjDW,yBAA2B1C,SAAS+B,eAAe,kCACnDY,aAAe3C,SAAS+B,eAAe,6BAA6Ba,QACpEC,WAAa7C,SAAS+B,eAAe,eACrCe,YAAc9C,SAAS+B,eAAe,mBAGpCgB,eAAiB,CAACC,QAASpB,WAC/BoB,QAAQC,MAAMC,OAAStB,QAAU,iBAAmB,iBAIjDE,eAKHK,mBAAmBc,MAAME,QAAU,OACnCJ,eAAeb,uBAAuB,KALtCa,eAAeb,wBAAyBJ,eACxCK,mBAAmBc,MAAME,QAAU,QACnCvB,SAAU,GAOPQ,oBAKHE,yBAAyBW,MAAME,QAAU,OACzCJ,eAAeV,4BAA4B,KAL3CU,eAAeV,6BAA8BD,oBAC7CE,yBAAyBW,MAAME,QAAU,QACzCvB,SAAU,GAORD,QAAQyB,OAAS,GACnBxB,SAAU,EACVC,cAAe,EACfY,uBAAuBQ,MAAME,QAAU,SAGvCV,uBAAuBQ,MAAME,QAAU,OAIpCxB,QAAQ0B,MAAKC,QAA6B,IAAnBA,OAAOC,UAMjChB,6BAA6BU,MAAME,QAAU,QAL7CvB,SAAU,EACVC,cAAe,EACfU,6BAA6BU,MAAME,QAAU,SAO3CxB,QAAQ0B,MAAKC,SAAWA,OAAOE,YAAYvB,UAC7CL,SAAU,EACVC,cAAe,EACfW,uBAAuBS,MAAME,QAAU,SAEvCX,uBAAuBS,MAAME,QAAU,UAIrCR,aAAc,KACZc,eAAiB,EACrB9B,QAAQ+B,SAAQJ,SACdG,gBAAkBH,OAAOC,WAEvBE,eAAiB,GACnB7B,SAAU,EACVC,cAAe,EACfa,yBAAyBO,MAAME,QAAU,SAEzCT,yBAAyBO,MAAME,QAAU,YAG3CT,yBAAyBO,MAAME,QAAU,OAMzCN,WAAWI,MAAME,QAHdtB,aAGwB,OAFA,YAKxBD,eACHkB,YAAYG,MAAME,QAAU,SACrB,SAEF,qEArTLQ,IAAM,EACNrD,WAAY,EACZC,aAAe,WAoBHqD,0BACVC,iBAAmBC,wBAAwBH,IAAM,GAChC3D,SAASC,cAAc,iCAC7B8D,YAAYF,kBAC3BF,eAUcG,wBAAwBE,QAClCH,iBAAmB7D,SAASiE,cAAc,OAC9CJ,iBAAiBK,UAAY,+BAEzBC,aAAenE,SAASiE,cAAc,SAC1CE,aAAaD,UAAY,eACzBC,aAAaC,YAAc,eAC3BD,aAAaH,GAAK,gBAAkBA,GACpCG,aAAaE,aAAa,YAAY,OAElCC,gBAAkBtE,SAASiE,cAAc,SAC7CK,gBAAgBD,aAAa,OAAQ,YACrCC,gBAAgBJ,UAAY,kBAC5BI,gBAAgBN,GAAK,mBAAqBA,OAEtCO,sBA2BkBC,aA1BpB,uBA0BkCC,KAzBlC,SAyBwCC,WAxBxC,uBAwBoDC,QAvBpD,KAwBFH,aAAexE,SAASiE,cAAcQ,OACzBP,UAAYQ,WACzBF,aAAaI,YAAcD,QACpBH,kBAJeA,aAAcC,KAAMC,WAAYC,eArBtDJ,qBAAqBP,GAAK,wBAA0BA,GAEpDH,iBAAiBE,YAAYO,iBAC7BT,iBAAiBE,YAAYI,cAC7BN,iBAAiBE,YAAYQ,sBAE7BA,qBAAqBnE,iBAAiB,SAAS,KAC7CyD,iBAAiBrD,YAEZqD,2DA1DuC,KAE1B7D,SAASC,cAAc,+BAC7BG,iBAAiB,SAAS,KACtCwD"} \ No newline at end of file diff --git a/server/moodle/mod/livequiz/amd/build/import_question.min.js.map b/server/moodle/mod/livequiz/amd/build/import_question.min.js.map index cf3e734e1..6d9d2978a 100644 --- a/server/moodle/mod/livequiz/amd/build/import_question.min.js.map +++ b/server/moodle/mod/livequiz/amd/build/import_question.min.js.map @@ -1 +1 @@ -{"version":3,"file":"import_question.min.js","sources":["../src/import_question.js"],"sourcesContent":["import Templates from \"core/templates\";\nimport {add_cancel_edit_button_listener, rerender_saved_questions_list} from \"./edit_question_helper\";\nimport {add_edit_question_listeners} from \"./edit_question\";\nimport {add_delete_question_listeners} from \"./delete_question\";\nimport {displayException} from \"core/notification\";\nimport {external_reuse_questions, get_lecturer_quiz} from \"./repository\";\nimport {rerender_take_quiz_button} from \"./edit_question_helper\";\n\n/**\n * Adds an event listener to the \"Import Question\" button.\n * When the button is clicked, it renders the import question menu popup.\n *\n * @param {number} quizid - The ID of the quiz.\n * @param {number} lecturerid - The ID of the lecturer.\n * @param {string} url - The URL to the quiz attempt page.\n * @returns {Promise} A promise that resolves when the initialization is complete.\n */\nexport const init = async (quizid, lecturerid, url) => {\n let import_question_button = document.getElementById(\n \"id_buttonimportquestion\"\n );\n import_question_button.addEventListener(\"click\", () => {\n render_import_question_menu_popup(quizid, lecturerid, url);\n });\n};\n\n/**\n * Renders the import question menu popup for a live quiz.\n *\n * This function loads and renders the import question menu popup template, appends it to the main container,\n * Sets up event listeners for importing questions and cancelling the import.\n *\n * @param {number} quizid - The ID of the quiz.\n * @param {number} lecturerid - The ID of the lecturer.\n * @param {string} url - The URL to the quiz attempt page.\n * @returns {void} - Nothing.\n */\nasync function render_import_question_menu_popup(quizid, lecturerid, url) {\n // This will call the function to load and render our template.\n if (!document.querySelector(\".Modal_div\")) {\n Templates.renderForPromise(\"mod_livequiz/import_question_popup\")\n // It returns a promise that needs to be resolved.\n .then(async({html, js}) => {\n // Here we have compiled template.\n Templates.appendNodeContents(\".main-container\", html, js);\n await importQuestions(quizid, url, lecturerid);\n add_cancel_edit_button_listener(\"import\");\n add_old_questions_to_popup(lecturerid, quizid);\n })\n\n // Deal with this exception (Using core/notify exception function is recommended).\n .catch((error) => displayException(error));\n }\n}\n\n/**\n * Adds old questions to the import question popup.\n * @param {number} lecturerid - The ID of the lecturer.\n * @param {number} quizid - The ID of the quiz.\n */\nfunction add_old_questions_to_popup(lecturerid, quizid) {\n get_lecturer_quiz(lecturerid).then((oldquizzes) => {\n oldquizzes = oldquizzes.filter(currentquiz => currentquiz.quizid !== quizid);\n let oldQuizzesContainer = document.querySelector(\".oldQuizzes\");\n if (oldquizzes.length === 0) {\n let noQuestions = document.createElement(\"p\");\n noQuestions.textContent = \"No questions available.\";\n oldQuizzesContainer.appendChild(noQuestions);\n return;\n }\n oldquizzes.forEach((quiz) => { // Loop through all quizzes.\n if (quiz.questions.length > 0) {\n let question_checkboxes = [];\n let quiz_div = document.createElement('div');\n //Create quiz checkbox.\n let quiz_checkbox = document.createElement('input');\n quiz_checkbox.type = \"checkbox\";\n quiz_checkbox.value = quiz.quizid;\n quiz_checkbox.id = quiz.quizid;\n quiz_checkbox.style.marginRight = \"5px\"; // Add margin so the text is not too close to the checkbox.\n quiz_checkbox.name = quiz.quiztitle;\n // Create quiz Label.\n let quiz_label = document.createElement('label');\n quiz_label.htmlFor = `quiz_${quiz.quizid}`;\n quiz_label.textContent = quiz.quiztitle;\n quiz_label.style.fontWeight = \"bold\"; // Make the quiz title bold.\n quiz_div.class = \"oldquiz\"; // Might be used for styling.\n\n // Append the checkbox and label to the div.\n quiz_div.appendChild(quiz_checkbox);\n quiz_div.appendChild(quiz_label);\n // Set the border style\n quiz_div.style.border = \"2px solid black\";\n // Create container for questions.\n let questions_div = document.createElement(\"div\");\n questions_div.style.marginBottom = \"20px\";\n questions_div.style.marginLeft = \"20px\"; // Add margin to the left so the questions are indented.\n questions_div.id = \"questionsdiv\";\n // Loop through each question and add it to the container.\n quiz.questions.forEach((question) => {\n //Create question checkbox.\n let question_div = document.createElement('div');\n let question_checkbox = document.createElement('input');\n question_checkbox.type = \"checkbox\";\n question_checkbox.value = `question_${question.questionid}`;\n question_checkbox.style.marginRight = \"5px\"; // Add margin so the text is not too close to the checkbox.\n question_checkbox.id = question.questionid;\n question_checkbox.name = question.questiontitle;\n question_checkboxes.push(question_checkbox);\n // Create question Label.\n let question_label = document.createElement('label');\n question_label.htmlFor = `question_${question.questionid}`;\n question_label.textContent = question.questiontitle;\n\n question_div.appendChild(question_checkbox);\n question_div.appendChild(question_label);\n questions_div.appendChild(question_div);\n });\n add_quiz_checkbox_listener(quiz_checkbox, question_checkboxes);\n add_question_checkbox_listener(quiz_checkbox, question_checkboxes);\n quiz_div.appendChild(questions_div);\n oldQuizzesContainer.appendChild(quiz_div);\n }\n });\n }).catch((error) => console.log(error));\n}\n\n/**\n * Imports questions into a quiz.\n *\n * @param {number} quizid - The ID of the quiz.\n * @param {string} url - The URL of the quiz page.\n * @param {number} lecturerid - The ID of the lecturer.\n * @returns {Promise} A promise that resolves when the questions are imported.\n */\nasync function importQuestions(quizid, url, lecturerid) {\n let quiz_url = url;\n const importQuestionBtn = document.querySelector(\".import_btn\");\n\n importQuestionBtn.addEventListener(\"click\", async() => {\n try {\n let questionids = get_checked_questions();\n if (questionids.length === 0) {\n alert(\"No questions selected. Pleas choose at least one question to import.\")\n return;\n }\n call_reuse_questions(quizid, questionids, lecturerid, quiz_url);\n } catch (error) {\n window.console.error(\"Error in import of questions\");\n console.log(error);\n }\n });\n}\n\n/**\n * Calls the external function to reuse questions.\n * @param {number} quizid - The ID of the quiz.\n * @param {array} questionids - The IDs of the questions to reuse.\n * @param {number} lecturerid - The ID of the lecturer.\n * @param {string} quiz_url - The URL of the quiz page.\n */\nfunction call_reuse_questions(quizid, questionids, lecturerid, quiz_url) {\n external_reuse_questions(quizid, questionids, lecturerid)\n .then((questions) => {\n let update_event_listeners = () => {\n add_edit_question_listeners(quizid, lecturerid);\n add_delete_question_listeners(quizid, lecturerid);\n };\n rerender_saved_questions_list(questions, update_event_listeners); // Re-render saved questions list.\n rerender_take_quiz_button(quiz_url, true); // Re-render take quiz button.\n })\n .catch((error) => console.log(error));\n let modal_div = document.querySelector(\".backdrop\");\n modal_div.remove();\n}\n\n/**\n * Retrieves the values of all checked questions from the lecturer's question list.\n *\n * @returns {Array} An array containing the ids of the checked questions.\n */\nfunction get_checked_questions() {\n let checkedquestions = [];\n let questions_div = document.querySelector(\".oldQuizzes\");\n\n // Loop through all quizzes and get the checked questions.\n for (let quiz_div of questions_div.children) {\n // Loop through all quizzes.\n for (let content of quiz_div.children) {\n // Loop through all content of the quiz.\n if (content.tagName === \"DIV\") {\n // Only look in div elements\n for (let question_div of content.children) {\n // Loop through all questions.\n for (let children of question_div.children) {\n // Loop through all children of the question.\n if (children.tagName === \"INPUT\") {\n // Only look in input elements.\n let checkbox = children;\n if (checkbox.checked) {\n // If the checkbox is checked, add the id to the array.\n checkedquestions.push(parseInt(checkbox.id));\n }\n }\n }\n }\n }\n }\n }\n return checkedquestions; // Returns the checked questions.\n}\n\n/**\n * Adds an event listener to the quiz checkboxes.\n * @param checkbox - The checkbox to add the event listener to.\n * @param questioncheckboxes - The question checkboxes that are manipulated when event is triggered.\n */\nfunction add_quiz_checkbox_listener(checkbox, questioncheckboxes) {\n checkbox.addEventListener(\"change\", () => {\n questioncheckboxes.forEach((questioncheckbox) => {\n questioncheckbox.checked = checkbox.checked; // Set all questions to checked if the quiz is checked.\n });\n });\n}\n\n/**\n * Adds an event listener to the question checkboxes.\n * @param checkbox - The checkbox that is manipulated when all questions are checked.\n * @param questioncheckboxes - The question checkboxes to add the event listener to.\n */\nfunction add_question_checkbox_listener(checkbox, questioncheckboxes) {\n questioncheckboxes.forEach((questioncheckbox) => {\n questioncheckbox.addEventListener(\"change\", () => {\n if (questioncheckbox.checked) {\n // If the question is checked, check if all questions are checked.\n let checkboxes_same = false;\n checkboxes_same = check_questions_checked(questioncheckboxes);\n if (checkboxes_same) {\n // If all questions are checked, check the quiz checkbox.\n checkbox.checked = questioncheckbox.checked;\n }\n } else {\n // If the question is unchecked, uncheck the quiz checkbox.\n checkbox.checked = questioncheckbox.checked;\n }\n });\n });\n}\n\n/**\n * Checks if all questions are checked.\n * @param questions\n * @returns {bool} - True if all questions are checked, false otherwise.\n */\nfunction check_questions_checked(questions) {\n return questions.every((question) => question.checked); // Returns true only if all are checked\n}\n"],"names":["async","quizid","lecturerid","url","document","getElementById","addEventListener","querySelector","renderForPromise","then","html","js","appendNodeContents","quiz_url","questionids","checkedquestions","questions_div","quiz_div","children","content","tagName","question_div","checkbox","checked","push","parseInt","id","get_checked_questions","length","alert","questions","update_event_listeners","catch","error","console","log","remove","call_reuse_questions","window","importQuestions","oldquizzes","filter","currentquiz","oldQuizzesContainer","noQuestions","createElement","textContent","appendChild","forEach","quiz","question_checkboxes","quiz_checkbox","type","value","style","marginRight","name","quiztitle","quiz_label","htmlFor","fontWeight","class","border","marginBottom","marginLeft","question","question_checkbox","questionid","questiontitle","question_label","questioncheckboxes","questioncheckbox","checkboxes_same","every","add_question_checkbox_listener","add_old_questions_to_popup","render_import_question_menu_popup"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"import_question.min.js","sources":["../src/import_question.js"],"sourcesContent":["import Templates from \"core/templates\";\r\nimport {add_cancel_edit_button_listener, rerender_saved_questions_list} from \"./edit_question_helper\";\r\nimport {add_edit_question_listeners} from \"./edit_question\";\r\nimport {add_delete_question_listeners} from \"./delete_question\";\r\nimport {displayException} from \"core/notification\";\r\nimport {external_reuse_questions, get_lecturer_quiz} from \"./repository\";\r\nimport {rerender_take_quiz_button} from \"./edit_question_helper\";\r\n\r\n/**\r\n * Adds an event listener to the \"Import Question\" button.\r\n * When the button is clicked, it renders the import question menu popup.\r\n *\r\n * @param {number} quizid - The ID of the quiz.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n * @param {string} url - The URL to the quiz attempt page.\r\n * @returns {Promise} A promise that resolves when the initialization is complete.\r\n */\r\nexport const init = async (quizid, lecturerid, url) => {\r\n let import_question_button = document.getElementById(\r\n \"id_buttonimportquestion\"\r\n );\r\n import_question_button.addEventListener(\"click\", () => {\r\n render_import_question_menu_popup(quizid, lecturerid, url);\r\n });\r\n};\r\n\r\n/**\r\n * Renders the import question menu popup for a live quiz.\r\n *\r\n * This function loads and renders the import question menu popup template, appends it to the main container,\r\n * Sets up event listeners for importing questions and cancelling the import.\r\n *\r\n * @param {number} quizid - The ID of the quiz.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n * @param {string} url - The URL to the quiz attempt page.\r\n * @returns {void} - Nothing.\r\n */\r\nasync function render_import_question_menu_popup(quizid, lecturerid, url) {\r\n // This will call the function to load and render our template.\r\n if (!document.querySelector(\".Modal_div\")) {\r\n Templates.renderForPromise(\"mod_livequiz/import_question_popup\")\r\n // It returns a promise that needs to be resolved.\r\n .then(async({html, js}) => {\r\n // Here we have compiled template.\r\n Templates.appendNodeContents(\".main-container\", html, js);\r\n await importQuestions(quizid, url, lecturerid);\r\n add_cancel_edit_button_listener(\"import\");\r\n add_old_questions_to_popup(lecturerid, quizid);\r\n })\r\n\r\n // Deal with this exception (Using core/notify exception function is recommended).\r\n .catch((error) => displayException(error));\r\n }\r\n}\r\n\r\n/**\r\n * Adds old questions to the import question popup.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n * @param {number} quizid - The ID of the quiz.\r\n */\r\nfunction add_old_questions_to_popup(lecturerid, quizid) {\r\n get_lecturer_quiz(lecturerid).then((oldquizzes) => {\r\n oldquizzes = oldquizzes.filter(currentquiz => currentquiz.quizid !== quizid);\r\n let oldQuizzesContainer = document.querySelector(\".oldQuizzes\");\r\n if (oldquizzes.length === 0) {\r\n let noQuestions = document.createElement(\"p\");\r\n noQuestions.textContent = \"No questions available.\";\r\n oldQuizzesContainer.appendChild(noQuestions);\r\n return;\r\n }\r\n oldquizzes.forEach((quiz) => { // Loop through all quizzes.\r\n if (quiz.questions.length > 0) {\r\n let question_checkboxes = [];\r\n let quiz_div = document.createElement('div');\r\n //Create quiz checkbox.\r\n let quiz_checkbox = document.createElement('input');\r\n quiz_checkbox.type = \"checkbox\";\r\n quiz_checkbox.value = quiz.quizid;\r\n quiz_checkbox.id = quiz.quizid;\r\n quiz_checkbox.style.marginRight = \"5px\"; // Add margin so the text is not too close to the checkbox.\r\n quiz_checkbox.name = quiz.quiztitle;\r\n // Create quiz Label.\r\n let quiz_label = document.createElement('label');\r\n quiz_label.htmlFor = `quiz_${quiz.quizid}`;\r\n quiz_label.textContent = quiz.quiztitle;\r\n quiz_label.style.fontWeight = \"bold\"; // Make the quiz title bold.\r\n quiz_div.class = \"oldquiz\"; // Might be used for styling.\r\n\r\n // Append the checkbox and label to the div.\r\n quiz_div.appendChild(quiz_checkbox);\r\n quiz_div.appendChild(quiz_label);\r\n // Set the border style\r\n quiz_div.style.border = \"2px solid black\";\r\n // Create container for questions.\r\n let questions_div = document.createElement(\"div\");\r\n questions_div.style.marginBottom = \"20px\";\r\n questions_div.style.marginLeft = \"20px\"; // Add margin to the left so the questions are indented.\r\n questions_div.id = \"questionsdiv\";\r\n // Loop through each question and add it to the container.\r\n quiz.questions.forEach((question) => {\r\n //Create question checkbox.\r\n let question_div = document.createElement('div');\r\n let question_checkbox = document.createElement('input');\r\n question_checkbox.type = \"checkbox\";\r\n question_checkbox.value = `question_${question.questionid}`;\r\n question_checkbox.style.marginRight = \"5px\"; // Add margin so the text is not too close to the checkbox.\r\n question_checkbox.id = question.questionid;\r\n question_checkbox.name = question.questiontitle;\r\n question_checkboxes.push(question_checkbox);\r\n // Create question Label.\r\n let question_label = document.createElement('label');\r\n question_label.htmlFor = `question_${question.questionid}`;\r\n question_label.textContent = question.questiontitle;\r\n\r\n question_div.appendChild(question_checkbox);\r\n question_div.appendChild(question_label);\r\n questions_div.appendChild(question_div);\r\n });\r\n add_quiz_checkbox_listener(quiz_checkbox, question_checkboxes);\r\n add_question_checkbox_listener(quiz_checkbox, question_checkboxes);\r\n quiz_div.appendChild(questions_div);\r\n oldQuizzesContainer.appendChild(quiz_div);\r\n }\r\n });\r\n }).catch((error) => console.log(error));\r\n}\r\n\r\n/**\r\n * Imports questions into a quiz.\r\n *\r\n * @param {number} quizid - The ID of the quiz.\r\n * @param {string} url - The URL of the quiz page.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n * @returns {Promise} A promise that resolves when the questions are imported.\r\n */\r\nasync function importQuestions(quizid, url, lecturerid) {\r\n let quiz_url = url;\r\n const importQuestionBtn = document.querySelector(\".import_btn\");\r\n\r\n importQuestionBtn.addEventListener(\"click\", async() => {\r\n try {\r\n let questionids = get_checked_questions();\r\n if (questionids.length === 0) {\r\n alert(\"No questions selected. Pleas choose at least one question to import.\")\r\n return;\r\n }\r\n call_reuse_questions(quizid, questionids, lecturerid, quiz_url);\r\n } catch (error) {\r\n window.console.error(\"Error in import of questions\");\r\n console.log(error);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Calls the external function to reuse questions.\r\n * @param {number} quizid - The ID of the quiz.\r\n * @param {array} questionids - The IDs of the questions to reuse.\r\n * @param {number} lecturerid - The ID of the lecturer.\r\n * @param {string} quiz_url - The URL of the quiz page.\r\n */\r\nfunction call_reuse_questions(quizid, questionids, lecturerid, quiz_url) {\r\n external_reuse_questions(quizid, questionids, lecturerid)\r\n .then((questions) => {\r\n let update_event_listeners = () => {\r\n add_edit_question_listeners(quizid, lecturerid);\r\n add_delete_question_listeners(quizid, lecturerid);\r\n };\r\n rerender_saved_questions_list(questions, update_event_listeners); // Re-render saved questions list.\r\n rerender_take_quiz_button(quiz_url, true); // Re-render take quiz button.\r\n })\r\n .catch((error) => console.log(error));\r\n let modal_div = document.querySelector(\".backdrop\");\r\n modal_div.remove();\r\n}\r\n\r\n/**\r\n * Retrieves the values of all checked questions from the lecturer's question list.\r\n *\r\n * @returns {Array} An array containing the ids of the checked questions.\r\n */\r\nfunction get_checked_questions() {\r\n let checkedquestions = [];\r\n let questions_div = document.querySelector(\".oldQuizzes\");\r\n\r\n // Loop through all quizzes and get the checked questions.\r\n for (let quiz_div of questions_div.children) {\r\n // Loop through all quizzes.\r\n for (let content of quiz_div.children) {\r\n // Loop through all content of the quiz.\r\n if (content.tagName === \"DIV\") {\r\n // Only look in div elements\r\n for (let question_div of content.children) {\r\n // Loop through all questions.\r\n for (let children of question_div.children) {\r\n // Loop through all children of the question.\r\n if (children.tagName === \"INPUT\") {\r\n // Only look in input elements.\r\n let checkbox = children;\r\n if (checkbox.checked) {\r\n // If the checkbox is checked, add the id to the array.\r\n checkedquestions.push(parseInt(checkbox.id));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return checkedquestions; // Returns the checked questions.\r\n}\r\n\r\n/**\r\n * Adds an event listener to the quiz checkboxes.\r\n * @param checkbox - The checkbox to add the event listener to.\r\n * @param questioncheckboxes - The question checkboxes that are manipulated when event is triggered.\r\n */\r\nfunction add_quiz_checkbox_listener(checkbox, questioncheckboxes) {\r\n checkbox.addEventListener(\"change\", () => {\r\n questioncheckboxes.forEach((questioncheckbox) => {\r\n questioncheckbox.checked = checkbox.checked; // Set all questions to checked if the quiz is checked.\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Adds an event listener to the question checkboxes.\r\n * @param checkbox - The checkbox that is manipulated when all questions are checked.\r\n * @param questioncheckboxes - The question checkboxes to add the event listener to.\r\n */\r\nfunction add_question_checkbox_listener(checkbox, questioncheckboxes) {\r\n questioncheckboxes.forEach((questioncheckbox) => {\r\n questioncheckbox.addEventListener(\"change\", () => {\r\n if (questioncheckbox.checked) {\r\n // If the question is checked, check if all questions are checked.\r\n let checkboxes_same = false;\r\n checkboxes_same = check_questions_checked(questioncheckboxes);\r\n if (checkboxes_same) {\r\n // If all questions are checked, check the quiz checkbox.\r\n checkbox.checked = questioncheckbox.checked;\r\n }\r\n } else {\r\n // If the question is unchecked, uncheck the quiz checkbox.\r\n checkbox.checked = questioncheckbox.checked;\r\n }\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Checks if all questions are checked.\r\n * @param questions\r\n * @returns {bool} - True if all questions are checked, false otherwise.\r\n */\r\nfunction check_questions_checked(questions) {\r\n return questions.every((question) => question.checked); // Returns true only if all are checked\r\n}\r\n"],"names":["async","quizid","lecturerid","url","document","getElementById","addEventListener","querySelector","renderForPromise","then","html","js","appendNodeContents","quiz_url","questionids","checkedquestions","questions_div","quiz_div","children","content","tagName","question_div","checkbox","checked","push","parseInt","id","get_checked_questions","length","alert","questions","update_event_listeners","catch","error","console","log","remove","call_reuse_questions","window","importQuestions","oldquizzes","filter","currentquiz","oldQuizzesContainer","noQuestions","createElement","textContent","appendChild","forEach","quiz","question_checkboxes","quiz_checkbox","type","value","style","marginRight","name","quiztitle","quiz_label","htmlFor","fontWeight","class","border","marginBottom","marginLeft","question","question_checkbox","questionid","questiontitle","question_label","questioncheckboxes","questioncheckbox","checkboxes_same","every","add_question_checkbox_listener","add_old_questions_to_popup","render_import_question_menu_popup"],"mappings":"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"} \ No newline at end of file diff --git a/server/moodle/mod/livequiz/amd/src/delete_question.js b/server/moodle/mod/livequiz/amd/src/delete_question.js index 2931d0f80..61c2def70 100644 --- a/server/moodle/mod/livequiz/amd/src/delete_question.js +++ b/server/moodle/mod/livequiz/amd/src/delete_question.js @@ -29,10 +29,12 @@ export function add_delete_question_listeners(quizid, lecturerid) { rerender_take_quiz_button(take_quiz_url, false); } } else { - alert("Cannot delete question: " + response.message); + throw("Cannot delete question, since it already has participations"); } + }).catch((error) => { + alert(error); }); - } - }); + } + }); }); } diff --git a/server/moodle/mod/livequiz/amd/src/edit_question.js b/server/moodle/mod/livequiz/amd/src/edit_question.js index fa93a25f1..ed47031b5 100644 --- a/server/moodle/mod/livequiz/amd/src/edit_question.js +++ b/server/moodle/mod/livequiz/amd/src/edit_question.js @@ -91,7 +91,8 @@ function on_save_question_button_clicked(quizid, lecturerid, questionid) { return; } - save_question(savedQuestion, lecturerid, quizid).then((questions) => { + save_question(savedQuestion, lecturerid, quizid) + .then((questions) => { const contextsavedquestions = { questions: questions, }; @@ -111,7 +112,7 @@ function on_save_question_button_clicked(quizid, lecturerid, questionid) { add_delete_question_listeners(quizid,lecturerid); }) .catch((error) => displayException(error)); - }); + }).catch(() => alert("Cannot edit a question, since it already has participations")); //Remove edit question pop-up let modal_div = document.querySelector(".backdrop"); modal_div.remove(); diff --git a/server/moodle/mod/livequiz/classes/external/get_lecturer_quiz.php b/server/moodle/mod/livequiz/classes/external/get_lecturer_quiz.php index ba74d6c85..cb6cc786d 100644 --- a/server/moodle/mod/livequiz/classes/external/get_lecturer_quiz.php +++ b/server/moodle/mod/livequiz/classes/external/get_lecturer_quiz.php @@ -67,13 +67,15 @@ public static function execute(int $lecturerid): array { // Loop through all quizzes from the lecturer and find the corresponding questions. foreach ($rawquizzes as $rawquiz) { $quizobject = livequiz::get_livequiz_instance($rawquiz->quiz_id); - $rawquestions = quiz_questions_relation::get_questions_from_quiz_id($rawquiz->quiz_id); - foreach ($rawquestions as $rawquestion) { - $question = question::get_question_from_id($rawquestion->get_id()); - $quizobject->add_question($question); + if (self::quiz_active($quizobject)) { // Check if the quiz is active/deleted. + $rawquestions = quiz_questions_relation::get_questions_from_quiz_id($rawquiz->quiz_id); + foreach ($rawquestions as $rawquestion) { + $question = question::get_question_from_id($rawquestion->get_id()); + $quizobject->add_question($question); + } + $preparedquiz = $quizobject->prepare_for_template(); + $quizzes[] = $preparedquiz; } - $preparedquiz = $quizobject->prepare_for_template(); - $quizzes[] = $preparedquiz; } return $quizzes; } @@ -88,4 +90,24 @@ public static function execute(int $lecturerid): array { public static function execute_returns(): external_multiple_structure { return new external_multiple_structure(data_structure_helper::get_quiz_structure(), 'List of quizzes'); } + + /** + * Checks if a quiz is active. + * @param livequiz $quizobject + * @return bool + * @throws dml_exception + */ + private static function quiz_active(livequiz $quizobject): bool { + global $DB; + // Get the livequiz instance. + $quizinstance = $DB->get_record('livequiz', ['id' => $quizobject->get_id()]); + // Get the course module ID. + $cmid = $quizinstance->activity_id; + // Get the course module instance. + $cminstance = $DB->get_record('course_modules', ['id' => $cmid]); + if ($cminstance->deletioninprogress == 1) { // Check if the course module is deleted. + return false; // Return false if the course module is deleted. + } + return true; // Return true if the course module is not deleted. + } } diff --git a/server/moodle/mod/livequiz/classes/services/livequiz_services.php b/server/moodle/mod/livequiz/classes/services/livequiz_services.php index f3e1e32ce..ac8c2f720 100644 --- a/server/moodle/mod/livequiz/classes/services/livequiz_services.php +++ b/server/moodle/mod/livequiz/classes/services/livequiz_services.php @@ -390,7 +390,6 @@ private static function delete_question(int $questionid): void { question::delete_question($questionid); } - /** * A method for fetching the relevant data for the quiz initiation. * diff --git a/server/moodle/mod/livequiz/db/install.xml b/server/moodle/mod/livequiz/db/install.xml index fa2bbfcf7..8f8363f3b 100644 --- a/server/moodle/mod/livequiz/db/install.xml +++ b/server/moodle/mod/livequiz/db/install.xml @@ -9,6 +9,7 @@ + diff --git a/server/moodle/mod/livequiz/db/upgrade.php b/server/moodle/mod/livequiz/db/upgrade.php index 55d8ff0b4..9d285165e 100644 --- a/server/moodle/mod/livequiz/db/upgrade.php +++ b/server/moodle/mod/livequiz/db/upgrade.php @@ -346,6 +346,19 @@ function xmldb_livequiz_upgrade($oldversion): bool { // Livequiz savepoint reached. upgrade_mod_savepoint(true, 2024072516, 'livequiz'); } + if ($oldversion < 2024072555) { + // Define field activityid to be added to livequiz_questions. + $table = new xmldb_table('livequiz'); + $field = new xmldb_field('activity_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'timemodified'); + + // Conditionally launch add field activityid. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Livequiz savepoint reached. + upgrade_mod_savepoint(true, 2024072548, 'livequiz'); + } return true; } diff --git a/server/moodle/mod/livequiz/lib.php b/server/moodle/mod/livequiz/lib.php index 5506f1d7f..eee0cdf78 100644 --- a/server/moodle/mod/livequiz/lib.php +++ b/server/moodle/mod/livequiz/lib.php @@ -32,6 +32,20 @@ function livequiz_add_instance(object $quizdata): bool|int { global $DB; + $modulerecord = $DB->get_records( // Get the course module records. + 'course_modules', + ['course' => $quizdata->course, 'module' => $quizdata->module, 'section' => $quizdata->section], + 'id DESC', + 'id' + ); + + if ($modulerecord) { // Check if a record is found. + $firstrecord = reset($modulerecord); // Get the latest record. + $quizdata->activity_id = $firstrecord->id; // Set the activity ID. + } else { + $quizdata->activity_id = 0; // Handle the case where no record is found. + } + $quizdata->timecreated = time(); $quizdata->timemodified = time(); @@ -64,11 +78,10 @@ function livequiz_update_instance(object $quizdata): bool { * @param int $id ID of the quiz instance * @return bool True on success * @throws dml_exception When a database error occurs + * @throws dml_exception|\PhpXmlRpc\Exception When a database error occurs */ function livequiz_delete_instance(int $id): bool { global $DB; - $DB->delete_records('livequiz', ['id' => $id]); - return true; } diff --git a/server/moodle/mod/livequiz/tests/behat/reuse_questions.feature b/server/moodle/mod/livequiz/tests/behat/reuse_questions.feature index 417fb0b5e..353fc7765 100644 --- a/server/moodle/mod/livequiz/tests/behat/reuse_questions.feature +++ b/server/moodle/mod/livequiz/tests/behat/reuse_questions.feature @@ -7,135 +7,150 @@ Feature: Reuse previously created questions in livequiz activity | username | firstname | lastname | email | | teacher1 | Teacher | 1 | teacher1@example.com | And the following "courses" exist: - | fullname | shortname | - | Test Course | TC | - | Test Course 2 | TC2 | + | fullname | shortname | + | Test Course | TC | + | Test Course 2 | TC2 | And the following "course enrolments" exist: - | user | course | role | - | teacher1 | TC | editingteacher | - | teacher1 | TC2 | editingteacher | + | user | course | role | + | teacher1 | TC | editingteacher | + | teacher1 | TC2 | editingteacher | And the following "activity" exists: - # Create a livequiz activity before the test - | activity | livequiz | - | course | TC | - | idnumber | 1 | - | name | livequiz_europe_quiz | - | intro | Test description | - | section | 0 | + # Create a livequiz activity before the test + | activity | livequiz | + | course | TC | + | idnumber | 1 | + | name | livequiz_europe_quiz | + | intro | Test description | + | section | 0 | And the following "activity" exists: - # Create a livequiz activity before the test - | activity | livequiz | - | course | TC2 | - | idnumber | 0 | - | name | livequiz_europe_quiz_2 | - | intro | Test description | - | section | 0 | + # Create a livequiz activity before the test + | activity | livequiz | + | course | TC2 | + | idnumber | 2 | + | name | livequiz_africa_quiz | + | intro | Test description | + | section | 0 | + And I use demodata "1" for the course "TC" and activity "livequiz" and lecturer "teacher1" + And I use demodata "2" for the course "TC2" and activity "livequiz" and lecturer "teacher1" And I log in as "teacher1" And I am on "Test Course" course homepage with editing mode on - Scenario: Unique questions are filtered - # Clicking on the second livequiz activity - When I click on "livequiz_europe_quiz" "link" in the "livequiz" activity - Then I should see "Quiz editor page" - And "Import Question" "button" should exist - # Adding a question to reuse later - And "Add Question" "button" should exist - And I click on "Add Question" "button" - Then I set the field "question_title_id" to "test 1" - Then I set the field "question_description_id" to "question text" - Then I set the field "question_explanation_id" to "explanation text" - # Adding answers to the question - Then I click on "Add Answer" "button" - And I set the field "answer_input_1" to "answer text 1" - And I click on "answer_checkbox_1" "checkbox" - Then I click on "Add Answer" "button" - And I set the field "answer_input_2" to "answer text 2" - And I click on "Save Question" "button" - Then I should see "Saved Questions" - And "test 1" "list_item" should exist - And I click on "Add Question" "button" - Then I set the field "question_title_id" to "test 1" - Then I set the field "question_description_id" to "question text" - Then I set the field "question_explanation_id" to "explanation text" - # Adding answers to the question - Then I click on "Add Answer" "button" - And I set the field with xpath "(//input[@class='answer_input'])[1]" to "answer text 1" - And I set the field with xpath "(//input[@class='answer_checkbox'])[1]" to "checked" - Then I click on "Add Answer" "button" - And I set the field with xpath "(//input[@class='answer_input'])[2]" to "answer text 2" - And I set the field with xpath "(//input[@class='answer_checkbox'])[2]" to "" - And I click on "Save Question" "button" - Then I should see "Saved Questions" - And I am on "Test Course 2" course homepage with editing mode on - When I click on "livequiz_europe_quiz_2" "link" in the "livequiz" activity - And I should see "Quiz editor page" - Then I click on "Import Question" "button" - And "livequiz_europe_quiz" "checkbox" should exist - And "test 1" "checkbox" should exist - And I click on "livequiz_europe_quiz" "checkbox" - And I click on "Import Question(s)" "button" - And I check that element "test 1" occurs only once in the list + Scenario: Deleted questions are filtered + #action-menu-toggle-2 is used because behat cannot find the correct action menu toggle + When I click on "action-menu-toggle-2" "link" in the "livequiz" activity + #We should see the default action menu options + And I click on "Delete" "link" + #We use a class selector here since behat cannot find the correct delete button with: I press + And I click on "Delete" "button" in the "[class=modal-content]" "css_element" + And I am on "Test Course 2" course homepage with editing mode on + And I click on "livequiz_africa_quiz" "link" in the "livequiz" activity + And I should see "Quiz editor page" + And I click on "Import Question" "button" + And "livequiz_europe_quiz" "checkbox" should not exist + + Scenario: Unique questions are filtered + # Clicking on the second livequiz activity + When I click on "livequiz_europe_quiz" "link" in the "livequiz" activity + Then I should see "Quiz editor page" + And "Import Question" "button" should exist + # Adding a question to reuse later + And "Add Question" "button" should exist + And I click on "Add Question" "button" + Then I set the field "question_title_id" to "test 1" + Then I set the field "question_description_id" to "question text" + Then I set the field "question_explanation_id" to "explanation text" + # Adding answers to the question + Then I click on "Add Answer" "button" + And I set the field "answer_input_1" to "answer text 1" + And I click on "answer_checkbox_1" "checkbox" + Then I click on "Add Answer" "button" + And I set the field "answer_input_2" to "answer text 2" + And I click on "Save Question" "button" + Then I should see "Saved Questions" + And "test 1" "list_item" should exist + And I click on "Add Question" "button" + Then I set the field "question_title_id" to "test 1" + Then I set the field "question_description_id" to "question text" + Then I set the field "question_explanation_id" to "explanation text" + # Adding answers to the question + Then I click on "Add Answer" "button" + And I set the field with xpath "(//input[@class='answer_input'])[1]" to "answer text 1" + And I set the field with xpath "(//input[@class='answer_checkbox'])[1]" to "checked" + Then I click on "Add Answer" "button" + And I set the field with xpath "(//input[@class='answer_input'])[2]" to "answer text 2" + And I set the field with xpath "(//input[@class='answer_checkbox'])[2]" to "" + And I click on "Save Question" "button" + Then I should see "Saved Questions" + And I am on "Test Course 2" course homepage with editing mode on + When I click on "livequiz_africa_quiz" "link" in the "livequiz" activity + And I should see "Quiz editor page" + Then I click on "Import Question" "button" + And "livequiz_europe_quiz" "checkbox" should exist + And "test 1" "checkbox" should exist + And I click on "livequiz_europe_quiz" "checkbox" + And I click on "Import Question(s)" "button" + And I check that element "test 1" occurs only once in the list Scenario: Reuse questions in livequiz - # Clicking on the second livequiz activity - When I click on "livequiz_europe_quiz" "link" in the "livequiz" activity - Then I should see "Quiz editor page" - And "Import Question" "button" should exist - # Adding a question to reuse later - And "Add Question" "button" should exist - And I click on "Add Question" "button" - Then I set the field "question_title_id" to "test 1" - Then I set the field "question_description_id" to "question text" - Then I set the field "question_explanation_id" to "explanation text" - # Adding answers to the question - Then I click on "Add Answer" "button" - And I set the field "answer_input_1" to "answer text 1" - And I click on "answer_checkbox_1" "checkbox" - Then I click on "Add Answer" "button" - And I set the field "answer_input_2" to "answer text 2" - And I click on "Save Question" "button" - Then I should see "Saved Questions" - And "test 1" "list_item" should exist - # Switching quiz - And I am on "Test Course 2" course homepage with editing mode on - When I click on "livequiz_europe_quiz_2" "link" in the "livequiz" activity - And I should see "Quiz editor page" - And "Import Question" "button" should exist - And I click on "Import Question" "button" - Then "Import Question(s)" "button" should exist - And "Cancel" "button" should exist - And I should see "Previously made Quizzes and Questions" - And "livequiz_europe_quiz_2" "checkbox" should not exist - And "livequiz_europe_quiz" "checkbox" should exist - And "test 1" "checkbox" should exist - And I click on "test 1" "checkbox" - And I click on "Import Question(s)" "button" - And I should see "Saved Questions" - And "test 1" "list_item" should exist - # Clicking on the question to see if the answers are correct - And I click on "(//li[.//span[text()='test 1']])[1]//button[contains(@class, 'edit-question-btn')]" "xpath_element" - And the field "question_title_id" matches value "test 1" - And the field "question_description_id" matches value "question text" - And the field "question_explanation_id" matches value "explanation text" - # Accessing the answers to see if they are correct - And the field with xpath "(//input[@class='answer_input'])[1]" matches value "answer text 1" - And the field with xpath "(//input[@class='answer_input'])[2]" matches value "answer text 2" - # Checking if the answers are correctly checked - And the field with xpath "(//input[@class='answer_checkbox'])[1]" matches value "checked" - And the field with xpath "(//input[@class='answer_checkbox'])[2]" matches value "" - # Testing that changes to one question does not affect the same questions from another livequiz - Then I click on "Add Answer" "button" - And I set the field with xpath "(//input[@class='answer_input'])[3]" to "answer text 3" - And I set the field with xpath "(//input[@class='answer_checkbox'])[1]" to "" - And I set the field with xpath "(//input[@class='answer_checkbox'])[2]" to "checked" - And I click on "Save Question" "button" - And I am on "Test Course" course homepage with editing mode on - Then I click on "livequiz_europe_quiz" "link" in the "livequiz" activity - And I should see "Quiz editor page" - And I should see "Saved Questions" - And I click on "(//li[.//span[text()='test 1']])[1]//button[contains(@class, 'edit-question-btn')]" "xpath_element" - And the field with xpath "(//input[@class='answer_checkbox'])[1]" matches value "checked" - And the field with xpath "(//input[@class='answer_checkbox'])[2]" matches value "" - And I should not see "answer text 3" + # Clicking on the second livequiz activity + When I click on "livequiz_europe_quiz" "link" in the "livequiz" activity + Then I should see "Quiz editor page" + And "Import Question" "button" should exist + # Adding a question to reuse later + And "Add Question" "button" should exist + And I click on "Add Question" "button" + Then I set the field "question_title_id" to "test 1" + Then I set the field "question_description_id" to "question text" + Then I set the field "question_explanation_id" to "explanation text" + # Adding answers to the question + Then I click on "Add Answer" "button" + And I set the field "answer_input_1" to "answer text 1" + And I click on "answer_checkbox_1" "checkbox" + Then I click on "Add Answer" "button" + And I set the field "answer_input_2" to "answer text 2" + And I click on "Save Question" "button" + Then I should see "Saved Questions" + And "test 1" "list_item" should exist + # Switching quiz + And I am on "Test Course 2" course homepage with editing mode on + When I click on "livequiz_africa_quiz" "link" in the "livequiz" activity + And I should see "Quiz editor page" + And "Import Question" "button" should exist + And I click on "Import Question" "button" + Then "Import Question(s)" "button" should exist + And "Cancel" "button" should exist + And I should see "Previously made Quizzes and Questions" + And "livequiz_africa_quiz" "checkbox" should not exist + And "livequiz_europe_quiz" "checkbox" should exist + And "test 1" "checkbox" should exist + And I click on "test 1" "checkbox" + And I click on "Import Question(s)" "button" + And I should see "Saved Questions" + And "test 1" "list_item" should exist + # Clicking on the question to see if the answers are correct + And I click on "(//li[.//span[text()='test 1']])[1]//button[contains(@class, 'edit-question-btn')]" "xpath_element" + And the field "question_title_id" matches value "test 1" + And the field "question_description_id" matches value "question text" + And the field "question_explanation_id" matches value "explanation text" + # Accessing the answers to see if they are correct + And the field with xpath "(//input[@class='answer_input'])[1]" matches value "answer text 1" + And the field with xpath "(//input[@class='answer_input'])[2]" matches value "answer text 2" + # Checking if the answers are correctly checked + And the field with xpath "(//input[@class='answer_checkbox'])[1]" matches value "checked" + And the field with xpath "(//input[@class='answer_checkbox'])[2]" matches value "" + # Testing that changes to one question does not affect the same questions from another livequiz + Then I click on "Add Answer" "button" + And I set the field with xpath "(//input[@class='answer_input'])[3]" to "answer text 3" + And I set the field with xpath "(//input[@class='answer_checkbox'])[1]" to "" + And I set the field with xpath "(//input[@class='answer_checkbox'])[2]" to "checked" + And I click on "Save Question" "button" + And I am on "Test Course" course homepage with editing mode on + Then I click on "livequiz_europe_quiz" "link" in the "livequiz" activity + And I should see "Quiz editor page" + And I should see "Saved Questions" + And I click on "(//li[.//span[text()='test 1']])[1]//button[contains(@class, 'edit-question-btn')]" "xpath_element" + And the field with xpath "(//input[@class='answer_checkbox'])[1]" matches value "checked" + And the field with xpath "(//input[@class='answer_checkbox'])[2]" matches value "" + And I should not see "answer text 3" diff --git a/server/moodle/mod/livequiz/tests/phpunit/lib_test.php b/server/moodle/mod/livequiz/tests/phpunit/lib_test.php index 5ec9526e9..1ac7eefeb 100644 --- a/server/moodle/mod/livequiz/tests/phpunit/lib_test.php +++ b/server/moodle/mod/livequiz/tests/phpunit/lib_test.php @@ -51,6 +51,9 @@ public function test_livequiz_add_instance(): void { $quizdata = new stdClass(); // Create a new stdClass object (empty object). $quizdata->name = 'Test Quiz'; $quizdata->intro = 'This is a test quiz.'; + $quizdata->course = 1; + $quizdata->module = 1; + $quizdata->section = 1; $id = livequiz_add_instance($quizdata); $this->assertIsInt($id); @@ -76,10 +79,12 @@ public function test_livequiz_update_instance(): void { $quizdata = new stdClass(); $quizdata->name = 'Test Quiz'; $quizdata->intro = 'This is a test quiz.'; + $quizdata->course = 1; + $quizdata->module = 1; + $quizdata->section = 1; $id = livequiz_add_instance($quizdata); $quizdata->instance = $id; $quizdata->name = 'Updated Test Quiz'; - // Execute. $result = livequiz_update_instance($quizdata); $record = $DB->get_record('livequiz', ['id' => $id]); @@ -104,6 +109,9 @@ public function test_livequiz_delete_instance(): void { $quizdata = new stdClass(); $quizdata->name = 'Test Quiz'; $quizdata->intro = 'This is a test quiz.'; + $quizdata->course = 1; + $quizdata->module = 1; + $quizdata->section = 1; $id = livequiz_add_instance($quizdata); $result = livequiz_delete_instance($id); diff --git a/server/moodle/mod/livequiz/tests/phpunit/livequiz_service_test.php b/server/moodle/mod/livequiz/tests/phpunit/livequiz_service_test.php index 99d7eec53..42e2ad764 100644 --- a/server/moodle/mod/livequiz/tests/phpunit/livequiz_service_test.php +++ b/server/moodle/mod/livequiz/tests/phpunit/livequiz_service_test.php @@ -55,6 +55,7 @@ protected function create_livequiz_for_test(): livequiz { 'introformat' => 1, 'timecreated' => time(), 'timemodified' => time(), + 'activity_id' => 1, ]; global $DB; diff --git a/server/moodle/mod/livequiz/tests/phpunit/outputclasstest/results_page_test.php b/server/moodle/mod/livequiz/tests/phpunit/outputclasstest/results_page_test.php index c0df153d8..1e6c458c0 100644 --- a/server/moodle/mod/livequiz/tests/phpunit/outputclasstest/results_page_test.php +++ b/server/moodle/mod/livequiz/tests/phpunit/outputclasstest/results_page_test.php @@ -52,6 +52,7 @@ protected function setUp(): void { 'introformat' => 1, 'timecreated' => time(), 'timemodified' => time(), + 'activity_id' => 1, ]; global $DB; diff --git a/server/moodle/mod/livequiz/tests/phpunit/student_quiz_relation_test.php b/server/moodle/mod/livequiz/tests/phpunit/student_quiz_relation_test.php index 0c57852cd..1ffb988a6 100644 --- a/server/moodle/mod/livequiz/tests/phpunit/student_quiz_relation_test.php +++ b/server/moodle/mod/livequiz/tests/phpunit/student_quiz_relation_test.php @@ -48,6 +48,7 @@ protected function create_test_data(): array { 'introformat' => 1, 'timecreated' => time(), 'timemodified' => time(), + 'activity_id' => 1, ]; global $DB; diff --git a/server/moodle/mod/livequiz/version.php b/server/moodle/mod/livequiz/version.php index a639e2a56..69232a84c 100644 --- a/server/moodle/mod/livequiz/version.php +++ b/server/moodle/mod/livequiz/version.php @@ -28,6 +28,6 @@ $plugin = new stdClass(); // Initialize $plugin as an object. -$plugin->version = 2024072549; +$plugin->version = 2024072543; $plugin->requires = 2024041600; $plugin->component = 'mod_livequiz';