Proyectos de Subversion Moodle

Rev

Rev 11 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

{"version":3,"file":"modal_add_random_question.min.js","sources":["../src/modal_add_random_question.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Contain the logic for the add random question modal.\n *\n * @module     mod_quiz/modal_add_random_question\n * @copyright  2018 Ryan Wyllie <ryan@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Modal from './add_question_modal';\nimport * as Notification from 'core/notification';\nimport * as Fragment from 'core/fragment';\nimport * as Templates from 'core/templates';\nimport * as FormChangeChecker from 'core_form/changechecker';\nimport {call as fetchMany} from 'core/ajax';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n    ANCHOR: 'a[href]',\n    EXISTING_CATEGORY_CONTAINER: '[data-region=\"existing-category-container\"]',\n    EXISTING_CATEGORY_TAB: '#id_existingcategoryheader',\n    NEW_CATEGORY_CONTAINER: '[data-region=\"new-category-container\"]',\n    NEW_CATEGORY_TAB: '#id_newcategoryheader',\n    TAB_CONTENT: '[data-region=\"tab-content\"]',\n    ADD_ON_PAGE_FORM_ELEMENT: '[name=\"addonpage\"]',\n    ADD_RANDOM_BUTTON: 'input[type=\"submit\"][name=\"addrandom\"]',\n    ADD_NEW_CATEGORY_BUTTON: 'input[type=\"submit\"][name=\"newcategory\"]',\n    SUBMIT_BUTTON_ELEMENT: 'input[type=\"submit\"][name=\"addrandom\"], '\n        + 'input[type=\"submit\"][name=\"newcategory\"], '\n        + 'input[type=\"submit\"][name=\"update\"]',\n    FORM_HEADER: 'legend',\n    SELECT_NUMBER_TO_ADD: '#menurandomcount',\n    NEW_CATEGORY_ELEMENT: '#categoryname',\n    PARENT_CATEGORY_ELEMENT: '#parentcategory',\n    FILTER_CONDITION_ELEMENT: '[data-filtercondition]',\n    FORM_ELEMENT: '#add_random_question_form',\n    MESSAGE_INPUT: '[name=\"message\"]',\n    SWITCH_TO_OTHER_BANK: 'button[data-action=\"switch-question-bank\"]',\n    NEW_BANKMOD_ID: 'data-newmodid',\n    BANK_SEARCH: '#searchbanks',\n    GO_BACK_BUTTON: 'button[data-action=\"go-back\"]',\n    UPDATE_FILTER_BUTTON: 'input[type=\"submit\"][name=\"update\"]',\n};\n\nexport default class ModalAddRandomQuestion extends Modal {\n    static TYPE = 'mod_quiz-quiz-add-random-question';\n    static TEMPLATE = 'mod_quiz/modal_add_random_question';\n\n    /**\n     * Create the add random question modal.\n     *\n     * @param  {Number} contextId Current context id.\n     * @param  {Number} bankCmId Current question bank course module id.\n     * @param  {string} category Category id and category context id comma separated.\n     * @param  {string} returnUrl URL to return to after form submission.\n     * @param  {Number} quizCmId Current quiz course module id.\n     * @param  {boolean} showNewCategory Display the New category tab when selecting random questions.\n     */\n    static init(\n        contextId,\n        bankCmId,\n        category,\n        returnUrl,\n        quizCmId,\n        showNewCategory = true\n    ) {\n        const selector = '.menu [data-action=\"addarandomquestion\"], [data-action=\"editrandomquestion\"]';\n        document.addEventListener('click', (e) => {\n            const trigger = e.target.closest(selector);\n            if (!trigger) {\n                return;\n            }\n            e.preventDefault();\n\n            if (trigger.dataset.slotid) {\n                showNewCategory = false;\n            }\n\n            ModalAddRandomQuestion.create({\n                contextId,\n                bankCmId,\n                category,\n                returnUrl,\n                quizCmId,\n                showNewCategory,\n                title: trigger.dataset.header,\n                addOnPage: trigger.dataset.addonpage,\n                slotId: trigger.dataset.slotid,\n                templateContext: {\n                    hidden: showNewCategory,\n                },\n            });\n        });\n    }\n\n    /**\n     * Constructor for the Modal.\n     *\n     * @param {object} root The root jQuery element for the modal\n     */\n    constructor(root) {\n        super(root);\n        this.category = null;\n        this.returnUrl = null;\n        this.quizCmId = null;\n        this.loadedForm = false;\n        this.slotId = 0;\n        this.savedFilterCondition = null;\n    }\n\n    configure(modalConfig) {\n        modalConfig.removeOnClose = true;\n\n        this.setCategory(modalConfig.category);\n        this.setReturnUrl(modalConfig.returnUrl);\n        this.showNewCategory = modalConfig.showNewCategory;\n        this.setSlotId(modalConfig.slotId ?? 0);\n        this.setSavedFilterCondition(modalConfig.savedFilterCondition ?? null);\n\n        super.configure(modalConfig);\n    }\n\n    /**\n     * Set the id of the page that the question should be added to\n     * when the user clicks the add to quiz link.\n     *\n     * @method setAddOnPageId\n     * @param {int} id\n     */\n    setAddOnPageId(id) {\n        super.setAddOnPageId(id);\n        this.getBody().find(SELECTORS.ADD_ON_PAGE_FORM_ELEMENT).val(id);\n    }\n\n    /**\n     * Set the category for this form. The category is a comma separated\n     * category id and category context id.\n     *\n     * @method setCategory\n     * @param {string} category\n     */\n    setCategory(category) {\n        this.category = category;\n    }\n\n    /**\n     * Returns the saved category.\n     *\n     * @method getCategory\n     * @return {string}\n     */\n    getCategory() {\n        return this.category;\n    }\n\n    /**\n     * Set the return URL for the form.\n     *\n     * @method setReturnUrl\n     * @param {string} url\n     */\n    setReturnUrl(url) {\n        this.returnUrl = url;\n    }\n\n    /**\n     * Returns the return URL for the form.\n     *\n     * @method getReturnUrl\n     * @return {string}\n     */\n    getReturnUrl() {\n        return this.returnUrl;\n    }\n\n    /**\n     * Set the ID of the quiz slot, if we are editing an existing random question.\n     *\n     * @param {Number} slotId\n     */\n    setSlotId(slotId) {\n        this.slotId = slotId;\n    }\n\n    /**\n     * Get the current slot ID.\n     *\n     * @return {Number}\n     */\n    getSlotId() {\n        return this.slotId;\n    }\n\n    /**\n     * Store the current filterCondition JSON string.\n     *\n     * @param {String} filterCondition\n     */\n    setSavedFilterCondition(filterCondition) {\n        this.savedFilterCondition = filterCondition;\n    }\n\n    /**\n     * Return the saved filterCondition JSON string.\n     *\n     * @return {String}\n     */\n    getSavedFilterCondition() {\n        return this.savedFilterCondition;\n    }\n\n    /**\n     * Moves a given form element inside (a child of) a given tab element.\n     *\n     * Hides the 'legend' (e.g. header) element of the form element because the\n     * tab has the name.\n     *\n     * Moves the submit button into a footer element at the bottom of the form\n     * element for styling purposes.\n     *\n     * @method moveContentIntoTab\n     * @param  {jquery} tabContent The form element to move into the tab.\n     * @param  {jquey} tabElement The tab element for the form element to move into.\n     */\n    moveContentIntoTab(tabContent, tabElement) {\n        // Hide the header because the tabs show us which part of the form we're\n        // looking at.\n        tabContent.find(SELECTORS.FORM_HEADER).addClass('hidden');\n        // Move the element inside a tab.\n        tabContent.wrap(tabElement);\n    }\n\n    /**\n     * Empty the tab content container and move all tabs from the form into the\n     * tab container element.\n     *\n     * @method moveTabsIntoTabContent\n     * @param  {jquery} form The form element.\n     */\n    moveTabsIntoTabContent(form) {\n        // Empty it to remove the loading icon.\n        const tabContent = this.getBody().find(SELECTORS.TAB_CONTENT).empty();\n        // Make sure all tabs are inside the tab content element.\n        form.find('[role=\"tabpanel\"]').wrapAll(tabContent);\n    }\n\n    /**\n     * Make sure all of the tabs have a cancel button in their fotter to sit along\n     * side the submit button.\n     *\n     * @method moveCancelButtonToTabs\n     * @param  {jquey} form The form element.\n     */\n    moveCancelButtonToTabs(form) {\n        const cancelButton = form.find(SELECTORS.CANCEL_BUTTON_ELEMENT).addClass('ms-1');\n        const tabFooters = form.find('[data-region=\"footer\"]');\n        // Remove the buttons container element.\n        cancelButton.closest(SELECTORS.BUTTON_CONTAINER).remove();\n        cancelButton.clone().appendTo(tabFooters);\n    }\n\n    /**\n     * Load the add random question form in a fragement and perform some transformation\n     * on the HTML to convert it into tabs for rendering in the modal.\n     *\n     * @method loadForm\n     * @return {promise} Resolved with form HTML and JS.\n     */\n    loadForm() {\n        const addonpage = this.getAddOnPageId();\n        const returnurl = this.getReturnUrl();\n        const quizcmid = this.quizCmId;\n        const bankcmid = this.bankCmId;\n        const savedfiltercondition = this.getSavedFilterCondition();\n        this.setSavedFilterCondition(null);\n\n        return Fragment.loadFragment(\n            'mod_quiz',\n            'add_random_question_form',\n            this.getContextId(),\n            {\n                addonpage: addonpage ?? null,\n                returnurl,\n                quizcmid,\n                bankcmid,\n                slotid: this.getSlotId(),\n                savedfiltercondition,\n            }\n        )\n            .then((html, js) => {\n                const form = $(html);\n                if (!this.getSlotId()) {\n                    const existingCategoryTabContent = form.find(SELECTORS.EXISTING_CATEGORY_TAB);\n                    const existingCategoryTab = this.getBody().find(SELECTORS.EXISTING_CATEGORY_CONTAINER);\n                    const newCategoryTabContent = form.find(SELECTORS.NEW_CATEGORY_TAB);\n                    const newCategoryTab = this.getBody().find(SELECTORS.NEW_CATEGORY_CONTAINER);\n\n                    // Transform the form into tabs for better rendering in the modal.\n                    this.moveContentIntoTab(existingCategoryTabContent, existingCategoryTab);\n                    this.moveContentIntoTab(newCategoryTabContent, newCategoryTab);\n                    this.moveTabsIntoTabContent(form);\n                }\n\n                Templates.replaceNode(this.getBody().find(SELECTORS.TAB_CONTENT), form, js);\n                return;\n            })\n            .then(() => {\n                // Make sure the form change checker is disabled otherwise it'll stop the user from navigating away from the\n                // page once the modal is hidden.\n                FormChangeChecker.disableAllChecks();\n\n                // Add question to quiz.\n                this.getBody()[0].addEventListener('click', (e) => {\n                    const button = e.target.closest(SELECTORS.SUBMIT_BUTTON_ELEMENT);\n                    if (!button) {\n                        return;\n                    }\n                    e.preventDefault();\n\n                    // Intercept the submission to adjust the POST params so that the quiz mod id is set and not the bank module id.\n                    document.querySelector('#questionscontainer input[name=\"cmid\"]').setAttribute('name', this.quizCmId);\n\n                    // Add Random questions if the add random button was clicked.\n                    const addRandomButton = e.target.closest(SELECTORS.ADD_RANDOM_BUTTON);\n                    if (addRandomButton) {\n                        const randomcount = document.querySelector(SELECTORS.SELECT_NUMBER_TO_ADD).value;\n                        const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition;\n\n                        this.addQuestions(quizcmid, addonpage, randomcount, filtercondition, '', '');\n                        return;\n                    }\n                    // Update the filter condition for the slot if the update button was clicked.\n                    const updateFilterButton = e.target.closest(SELECTORS.UPDATE_FILTER_BUTTON);\n                    if (updateFilterButton) {\n                        const filtercondition = document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition;\n                        this.updateFilterCondition(quizcmid, this.getSlotId(), filtercondition);\n                        return;\n                    }\n                    // Add new category if the add category button was clicked.\n                    const addCategoryButton = e.target.closest(SELECTORS.ADD_NEW_CATEGORY_BUTTON);\n                    if (addCategoryButton) {\n                        this.addQuestions(\n                            quizcmid,\n                            addonpage,\n                            1,\n                            '',\n                            document.querySelector(SELECTORS.NEW_CATEGORY_ELEMENT).value,\n                            document.querySelector(SELECTORS.PARENT_CATEGORY_ELEMENT).value\n                        );\n                        return;\n                    }\n                });\n\n                this.getModal().on('click', SELECTORS.SWITCH_TO_OTHER_BANK, () => {\n                    this.setSavedFilterCondition(\n                        document.querySelector(SELECTORS.FILTER_CONDITION_ELEMENT).dataset?.filtercondition\n                    );\n                    this.handleSwitchBankContentReload(SELECTORS.BANK_SEARCH)\n                        .then(function(ModalQuizQuestionBank) {\n                            $(SELECTORS.BANK_SEARCH)?.on('change', (e) => {\n                                const bankCmId = $(e.currentTarget).val();\n                                // Have to recreate the modal as we have already used the body for the switch bank content.\n                                if (bankCmId > 0) {\n                                    ModalAddRandomQuestion.create({\n                                        'contextId': ModalQuizQuestionBank.getContextId(),\n                                        'bankCmId': bankCmId,\n                                        'category': ModalQuizQuestionBank.getCategory(),\n                                        'returnUrl': ModalQuizQuestionBank.getReturnUrl(),\n                                        'quizCmId': ModalQuizQuestionBank.quizCmId,\n                                        'title': ModalQuizQuestionBank.originalTitle,\n                                        'addOnPage': ModalQuizQuestionBank.getAddOnPageId(),\n                                        'templateContext': {hidden: ModalQuizQuestionBank.showNewCategory},\n                                        'showNewCategory': ModalQuizQuestionBank.showNewCategory,\n                                        'slotId': ModalQuizQuestionBank.getSlotId(),\n                                    })\n                                    .then(ModalQuizQuestionBank.destroy())\n                                    .catch(Notification.exception);\n                                }\n                            });\n                            return ModalQuizQuestionBank;\n                        });\n                });\n\n                this.getModal().on('click', SELECTORS.GO_BACK_BUTTON, (e) => {\n                    const anchorElement = $(e.currentTarget);\n                    // Have to recreate the modal as we have already used the body for the switch bank content.\n                    ModalAddRandomQuestion.create({\n                        'contextId': this.getContextId(),\n                        'bankCmId': anchorElement.attr('value'),\n                        'category': this.getCategory(),\n                        'returnUrl': this.getReturnUrl(),\n                        'quizCmId': this.quizCmId,\n                        'title': this.originalTitle,\n                        'addOnPage': this.getAddOnPageId(),\n                        'templateContext': {hidden: this.showNewCategory},\n                        'showNewCategory': this.showNewCategory,\n                        'savedFilterCondition': this.getSavedFilterCondition(),\n                        'slotId': this.getSlotId(),\n                    }).then(this.destroy()).catch(Notification.exception);\n                });\n\n                this.getModal().on('click', SELECTORS.ANCHOR, (e) => {\n                    const anchorElement = $(e.currentTarget);\n                    // Have to recreate the modal as we have already used the body for the switch bank content.\n                    if (anchorElement.closest('a[' + SELECTORS.NEW_BANKMOD_ID + ']').length) {\n                        ModalAddRandomQuestion.create({\n                            'contextId': this.getContextId(),\n                            'bankCmId': anchorElement.attr(SELECTORS.NEW_BANKMOD_ID),\n                            'category': this.getCategory(),\n                            'returnUrl': this.getReturnUrl(),\n                            'quizCmId': this.quizCmId,\n                            'title': this.originalTitle,\n                            'addOnPage': this.getAddOnPageId(),\n                            'templateContext': {hidden: this.showNewCategory},\n                            'showNewCategory': this.showNewCategory,\n                            'slotId': this.getSlotId(),\n                        }).then(this.destroy()).catch(Notification.exception);\n                    }\n                });\n            })\n            .catch(Notification.exception);\n    }\n\n    /**\n     * Call web service function to add random questions\n     *\n     * @param {number} quizcmid the course module id of the quiz to add questions to.\n     * @param {number} addonpage the page where random questions will be added to\n     * @param {number} randomcount Number of random questions\n     * @param {string} filtercondition Filter condition\n     * @param {string} newcategory add new category\n     * @param {string} parentcategory parent category of new category\n     */\n    async addQuestions(\n        quizcmid,\n        addonpage,\n        randomcount,\n        filtercondition,\n        newcategory,\n        parentcategory\n    ) {\n        // We do not need to resolve this Pending because the form submission will result in a page redirect.\n        new Pending('mod-quiz/modal_add_random_questions');\n        const call = {\n            methodname: 'mod_quiz_add_random_questions',\n            args: {\n                cmid: quizcmid,\n                addonpage,\n                randomcount,\n                filtercondition,\n                newcategory,\n                parentcategory,\n            }\n        };\n        try {\n            const response = await fetchMany([call])[0];\n            const form = document.querySelector(SELECTORS.FORM_ELEMENT);\n            const messageInput = form.querySelector(SELECTORS.MESSAGE_INPUT);\n            messageInput.value = response.message;\n            form.submit();\n        } catch (e) {\n            Notification.exception(e);\n        }\n    }\n\n    /**\n     * Call web service function to update the filter condition for an existing slot.\n     *\n     * @param {number} quizcmid the course module id of the quiz.\n     * @param {number} slotid The slot the random question is in.\n     * @param {string} filtercondition The new filter condition.\n     */\n    async updateFilterCondition(\n        quizcmid,\n        slotid,\n        filtercondition,\n    ) {\n        // We do not need to resolve this Pending because the form submission will result in a page redirect.\n        new Pending('mod-quiz/modal_add_random_questions');\n        const call = {\n            methodname: 'mod_quiz_update_filter_condition',\n            args: {\n                cmid: quizcmid,\n                slotid,\n                filtercondition,\n            }\n        };\n        try {\n            const response = await fetchMany([call])[0];\n            const form = document.querySelector(SELECTORS.FORM_ELEMENT);\n            const messageInput = form.querySelector(SELECTORS.MESSAGE_INPUT);\n            messageInput.value = response.message;\n            form.submit();\n        } catch (e) {\n            Notification.exception(e);\n        }\n    }\n\n    /**\n     * Override the modal show function to load the form when this modal is first\n     * shown.\n     *\n     * @method show\n     */\n    show() {\n        super.show(this);\n\n        if (!this.loadedForm) {\n            this.tabHtml = this.getBody();\n            this.loadForm(window.location.search);\n            this.loadedForm = true;\n        }\n    }\n}\n\nModalAddRandomQuestion.registerModalType();\n"],"names":["SELECTORS","ANCHOR","EXISTING_CATEGORY_CONTAINER","EXISTING_CATEGORY_TAB","NEW_CATEGORY_CONTAINER","NEW_CATEGORY_TAB","TAB_CONTENT","ADD_ON_PAGE_FORM_ELEMENT","ADD_RANDOM_BUTTON","ADD_NEW_CATEGORY_BUTTON","SUBMIT_BUTTON_ELEMENT","FORM_HEADER","SELECT_NUMBER_TO_ADD","NEW_CATEGORY_ELEMENT","PARENT_CATEGORY_ELEMENT","FILTER_CONDITION_ELEMENT","FORM_ELEMENT","MESSAGE_INPUT","SWITCH_TO_OTHER_BANK","NEW_BANKMOD_ID","BANK_SEARCH","GO_BACK_BUTTON","UPDATE_FILTER_BUTTON","ModalAddRandomQuestion","Modal","contextId","bankCmId","category","returnUrl","quizCmId","showNewCategory","document","addEventListener","e","trigger","target","closest","preventDefault","dataset","slotid","create","title","header","addOnPage","addonpage","slotId","templateContext","hidden","constructor","root","loadedForm","savedFilterCondition","configure","modalConfig","removeOnClose","setCategory","setReturnUrl","setSlotId","setSavedFilterCondition","setAddOnPageId","id","getBody","find","val","getCategory","this","url","getReturnUrl","getSlotId","filterCondition","getSavedFilterCondition","moveContentIntoTab","tabContent","tabElement","addClass","wrap","moveTabsIntoTabContent","form","empty","wrapAll","moveCancelButtonToTabs","cancelButton","CANCEL_BUTTON_ELEMENT","tabFooters","BUTTON_CONTAINER","remove","clone","appendTo","loadForm","getAddOnPageId","returnurl","quizcmid","bankcmid","savedfiltercondition","Fragment","loadFragment","getContextId","then","html","js","existingCategoryTabContent","existingCategoryTab","newCategoryTabContent","newCategoryTab","Templates","replaceNode","FormChangeChecker","disableAllChecks","querySelector","setAttribute","randomcount","value","filtercondition","_document$querySelect","addQuestions","_document$querySelect2","updateFilterCondition","getModal","on","_document$querySelect3","handleSwitchBankContentReload","ModalQuizQuestionBank","currentTarget","originalTitle","destroy","catch","Notification","exception","anchorElement","attr","length","newcategory","parentcategory","Pending","call","methodname","args","cmid","response","message","submit","show","tabHtml","window","location","search","registerModalType"],"mappings":"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"}