mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
MDL-61133 core_question: add new question tags modal
This commit is contained in:
parent
7f4b6dfe70
commit
fd5e2ead95
@ -269,6 +269,7 @@ $string['questionsinuse'] = '(* Questions marked by an asterisk are already in u
|
||||
$string['questionsmovedto'] = 'Questions still in use moved to "{$a}" in the parent course category.';
|
||||
$string['questionsrescuedfrom'] = 'Questions saved from context {$a}.';
|
||||
$string['questionsrescuedfrominfo'] = 'These questions (some of which may be hidden) were saved when context {$a} was deleted because they are still used by some quizzes or other activities.';
|
||||
$string['questiontags'] = 'Question tags';
|
||||
$string['questiontype'] = 'Question type';
|
||||
$string['questionuse'] = 'Use question in this activity';
|
||||
$string['questionvariant'] = 'Question variant';
|
||||
|
1
question/amd/build/edit_tags.min.js
vendored
Normal file
1
question/amd/build/edit_tags.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/fragment","core/str","core/modal_events","core/modal_factory","core/notification","core/custom_interaction_events","core_question/repository"],function(a,b,c,d,e,f,g,h){var i={TAGS_LINK:'[data-action="edittags"]',SAVE_BUTTON:'[data-action="save"]',LOADING_ICON:'[data-region="overlay-icon-container"]'},j=function(a){a.find(i.SAVE_BUTTON).prop("disabled",!1)},k=function(a){a.find(i.SAVE_BUTTON).prop("disabled",!0)},l=function(a){return a.getBody().find("form").serialize()},m=function(a){var b=a.find(i.LOADING_ICON);b.removeClass("hidden")},n=function(a){var b=a.find(i.LOADING_ICON);b.addClass("hidden")},o=function(h){var l=e.create({type:e.types.SAVE_CANCEL,large:!1},[h,i.TAGS_LINK]).then(function(a){return c.get_string("questiontags","question").then(function(b){return a.setTitle(b),b}).fail(f.exception),a.getRoot().on(d.save,function(b){var c=a.getBody().find("form");c.submit(),b.preventDefault()}),a.getRoot().on("submit","form",function(b){p(a,h).then(function(){a.hide()}).fail(f.exception),b.preventDefault(),b.stopPropagation()}),a});h.on(g.events.activate,i.TAGS_LINK,function(c){var d=a(c.currentTarget),e=d.data("questionid"),g=!!d.data("canedit"),o=d.data("contextid");l.then(function(a){k(h),m(h);var c={id:e},d=b.loadFragment("question","tags_form",o,c);return a.setBody(d),d.then(function(){j(h)}).always(function(){n(h)}).fail(f.exception),g?a.getRoot().find(i.SAVE_BUTTON).show():a.getRoot().find(i.SAVE_BUTTON).hide(),a}).fail(f.exception),c.preventDefault()})},p=function(a,b){k(b),m(b);var c=l(a);return h.submitTagCreateUpdateForm(c).always(function(){n(b),j(b)}).fail(f.exception)};return{init:function(b){b=a(b),o(b)}}});
|
1
question/amd/build/repository.min.js
vendored
Normal file
1
question/amd/build/repository.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/ajax"],function(a,b){var c=function(a){var c={methodname:"core_question_submit_tags_form",args:{formdata:a}};return b.call([c])[0]};return{submitTagCreateUpdateForm:c}});
|
233
question/amd/src/edit_tags.js
Normal file
233
question/amd/src/edit_tags.js
Normal file
@ -0,0 +1,233 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* A javascript module to handle question tags editing.
|
||||
*
|
||||
* @module core_question/edit_tags
|
||||
* @copyright 2018 Simey Lameze <simey@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define([
|
||||
'jquery',
|
||||
'core/fragment',
|
||||
'core/str',
|
||||
'core/modal_events',
|
||||
'core/modal_factory',
|
||||
'core/notification',
|
||||
'core/custom_interaction_events',
|
||||
'core_question/repository',
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Fragment,
|
||||
Str,
|
||||
ModalEvents,
|
||||
ModalFactory,
|
||||
Notification,
|
||||
CustomEvents,
|
||||
Repository
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
TAGS_LINK: '[data-action="edittags"]',
|
||||
SAVE_BUTTON: '[data-action="save"]',
|
||||
LOADING_ICON: '[data-region="overlay-icon-container"]',
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable the save button in the footer.
|
||||
*
|
||||
* @param {object} root The container element.
|
||||
* @method enableSaveButton
|
||||
*/
|
||||
var enableSaveButton = function(root) {
|
||||
root.find(SELECTORS.SAVE_BUTTON).prop('disabled', false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable the save button in the footer.
|
||||
*
|
||||
* @param {object} root The container element.
|
||||
* @method disableSaveButton
|
||||
*/
|
||||
var disableSaveButton = function(root) {
|
||||
root.find(SELECTORS.SAVE_BUTTON).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(SELECTORS.LOADING_ICON);
|
||||
|
||||
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(SELECTORS.LOADING_ICON);
|
||||
|
||||
loadingIconContainer.addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Register event listeners for the module.
|
||||
*
|
||||
* @param {object} root The calendar root element
|
||||
*/
|
||||
var registerEventListeners = function(root) {
|
||||
var modalPromise = ModalFactory.create(
|
||||
{
|
||||
type: ModalFactory.types.SAVE_CANCEL,
|
||||
large: false
|
||||
},
|
||||
[root, SELECTORS.TAGS_LINK]
|
||||
).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;
|
||||
})
|
||||
.fail(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();
|
||||
return;
|
||||
}).fail(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;
|
||||
});
|
||||
|
||||
// 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, SELECTORS.TAGS_LINK, function(e) {
|
||||
var currentTarget = $(e.currentTarget);
|
||||
|
||||
var questionId = currentTarget.data('questionid'),
|
||||
canEdit = !!currentTarget.data('canedit'),
|
||||
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;
|
||||
})
|
||||
.fail(Notification.exception);
|
||||
|
||||
// Show or hide the save button depending on whether the user
|
||||
// has the capability to edit the tags.
|
||||
if (canEdit) {
|
||||
modal.getRoot().find(SELECTORS.SAVE_BUTTON).show();
|
||||
} else {
|
||||
modal.getRoot().find(SELECTORS.SAVE_BUTTON).hide();
|
||||
}
|
||||
|
||||
return modal;
|
||||
}).fail(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);
|
||||
|
||||
// Send the form data to the server for processing.
|
||||
return Repository.submitTagCreateUpdateForm(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;
|
||||
})
|
||||
.fail(Notification.exception);
|
||||
};
|
||||
|
||||
return {
|
||||
init: function(root) {
|
||||
root = $(root);
|
||||
registerEventListeners(root);
|
||||
}
|
||||
};
|
||||
});
|
48
question/amd/src/repository.js
Normal file
48
question/amd/src/repository.js
Normal file
@ -0,0 +1,48 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* A javascript module to handle question ajax actions.
|
||||
*
|
||||
* @module core_question/repository
|
||||
* @class repository
|
||||
* @package core_question
|
||||
* @copyright 2017 Simey Lameze <lameze@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery', 'core/ajax'], function($, Ajax) {
|
||||
|
||||
/**
|
||||
* Submit the form data for the question tags form.
|
||||
*
|
||||
* @method submitTagCreateUpdateForm
|
||||
* @param {string} formdata The URL encoded values from the form
|
||||
* @return {promise}
|
||||
*/
|
||||
var submitTagCreateUpdateForm = function(formdata) {
|
||||
var request = {
|
||||
methodname: 'core_question_submit_tags_form',
|
||||
args: {
|
||||
formdata: formdata
|
||||
}
|
||||
};
|
||||
|
||||
return Ajax.call([request])[0];
|
||||
};
|
||||
|
||||
return {
|
||||
submitTagCreateUpdateForm: submitTagCreateUpdateForm
|
||||
};
|
||||
});
|
@ -480,6 +480,8 @@ class view {
|
||||
$this->baseurl, $cat, $this->cm,
|
||||
null, $page, $perpage, $showhidden, $showquestiontext,
|
||||
$this->contexts->having_cap('moodle/question:add'));
|
||||
|
||||
$PAGE->requires->js_call_amd('core_question/edit_tags', 'init', ['#questionscontainer']);
|
||||
}
|
||||
|
||||
protected function print_choose_category_message($categoryandcontext) {
|
||||
@ -701,7 +703,7 @@ class view {
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
echo \html_writer::input_hidden_params($this->baseurl);
|
||||
|
||||
echo '<div class="categoryquestionscontainer">';
|
||||
echo '<div class="categoryquestionscontainer" id="questionscontainer">';
|
||||
$this->start_table();
|
||||
$rowcount = 0;
|
||||
foreach ($questions as $question) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user