ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ.// This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . /** * A javascript module to handle question tags editing. * * @deprecated since Moodle 4.0 * @todo Final deprecation on Moodle 4.4 MDL-72438 * @module core_question/edit_tags * @copyright 2018 Simey Lameze * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define([ 'jquery', 'core/fragment', 'core/str', 'core/modal_events', 'core/modal_save_cancel', 'core/notification', 'core/custom_interaction_events', 'core_question/repository', 'core_question/selectors', ], function( $, Fragment, Str, ModalEvents, ModalSaveCancel, Notification, CustomEvents, Repository, QuestionSelectors ) { /** * Enable the save button in the footer. * * @param {object} root The container element. * @method enableSaveButton */ var enableSaveButton = function(root) { root.find(QuestionSelectors.actions.save).prop('disabled', false); }; /** * Disable the save button in the footer. * * @param {object} root The container element. * @method disableSaveButton */ var disableSaveButton = function(root) { root.find(QuestionSelectors.actions.save).prop('disabled', true); }; /** * Get the serialised form data. * * @method getFormData * @param {object} modal The modal object. * @return {string} serialised form data */ var getFormData = function(modal) { return modal.getBody().find('form').serialize(); }; /** * Set the element state to loading. * * @param {object} root The container element * @method startLoading */ var startLoading = function(root) { var loadingIconContainer = root.find(QuestionSelectors.containers.loadingIcon); loadingIconContainer.removeClass('hidden'); }; /** * Remove the loading state from the element. * * @param {object} root The container element * @method stopLoading */ var stopLoading = function(root) { var loadingIconContainer = root.find(QuestionSelectors.containers.loadingIcon); loadingIconContainer.addClass('hidden'); }; /** * Set the context Id data attribute on the modal. * * @param {Promise} modal The modal promise. * @param {int} contextId The context id. */ var setContextId = function(modal, contextId) { modal.getBody().attr('data-contextid', contextId); }; /** * Get the context Id data attribute value from the modal body. * * @param {Promise} modal The modal promise. * @return {int} The context id. */ var getContextId = function(modal) { return modal.getBody().data('contextid'); }; /** * Set the question Id data attribute on the modal. * * @param {Promise} modal The modal promise. * @param {int} questionId The question Id. */ var setQuestionId = function(modal, questionId) { modal.getBody().attr('data-questionid', questionId); }; /** * Get the question Id data attribute value from the modal body. * * @param {Promise} modal The modal promise. * @return {int} The question Id. */ var getQuestionId = function(modal) { return modal.getBody().data('questionid'); }; /** * Register event listeners for the module. * * @param {object} root The calendar root element */ var registerEventListeners = function(root) { var modalPromise = ModalSaveCancel.create({ large: false, }).then(function(modal) { // All of this code only executes once, when the modal is // first created. This allows us to add any code that should // only be run once, such as adding event handlers to the modal. Str.get_string('questiontags', 'question') .then(function(string) { modal.setTitle(string); return string; }) .catch(Notification.exception); modal.getRoot().on(ModalEvents.save, function(e) { var form = modal.getBody().find('form'); form.submit(); e.preventDefault(); }); modal.getRoot().on('submit', 'form', function(e) { save(modal, root).then(function() { modal.hide(); location.reload(); return; }).catch(Notification.exception); // Stop the form from actually submitting and prevent it's // propagation because we have already handled the event. e.preventDefault(); e.stopPropagation(); }); return modal; }); root.on('click', QuestionSelectors.actions.edittags, function(e) { e.preventDefault(); // eslint-disable-next-line promise/catch-or-return modalPromise.then((modal) => modal.show()); }); // We need to add an event handler to the tags link because there are // multiple links on the page and without adding a listener we don't know // which one the user clicked on the show the modal. root.on(CustomEvents.events.activate, QuestionSelectors.actions.edittags, function(e) { var currentTarget = $(e.currentTarget); var questionId = currentTarget.data('questionid'), canTag = !!currentTarget.data('cantag'), contextId = currentTarget.data('contextid'); // This code gets called each time the user clicks the tag link // so we can use it to reload the contents of the tag modal. modalPromise.then(function(modal) { // Display spinner and disable save button. disableSaveButton(root); startLoading(root); var args = { id: questionId }; var tagsFragment = Fragment.loadFragment('question', 'tags_form', contextId, args); modal.setBody(tagsFragment); tagsFragment.then(function() { enableSaveButton(root); return; }) .always(function() { // Always hide the loading spinner when the request // has completed. stopLoading(root); return; }) .catch(Notification.exception); // Show or hide the save button depending on whether the user // has the capability to edit the tags. if (canTag) { modal.getRoot().find(QuestionSelectors.actions.save).show(); } else { modal.getRoot().find(QuestionSelectors.actions.save).hide(); } setQuestionId(modal, questionId); setContextId(modal, contextId); return modal; }).catch(Notification.exception); e.preventDefault(); }); }; /** * Send the form data to the server to save question tags. * * @method save * @param {object} modal The modal object. * @param {object} root The container element. * @return {object} A promise */ var save = function(modal, root) { // Display spinner and disable save button. disableSaveButton(root); startLoading(root); var formData = getFormData(modal); var questionId = getQuestionId(modal); var contextId = getContextId(modal); // Send the form data to the server for processing. return Repository.submitTagCreateUpdateForm(questionId, contextId, formData) .always(function() { // Regardless of success or error we should always stop // the loading icon and re-enable the buttons. stopLoading(root); enableSaveButton(root); return; }) .catch(Notification.exception); }; return { init: function(root) { window.console.warn('warn: The core_question/repository has been deprecated.' + 'Please use qbank_tagquestion/repository instead.'); root = $(root); registerEventListeners(root); } }; });