Commit | Line | Data |
---|---|---|
fd5e2ead SL |
1 | // This file is part of Moodle - http://moodle.org/ |
2 | // | |
3 | // Moodle is free software: you can redistribute it and/or modify | |
4 | // it under the terms of the GNU General Public License as published by | |
5 | // the Free Software Foundation, either version 3 of the License, or | |
6 | // (at your option) any later version. | |
7 | // | |
8 | // Moodle is distributed in the hope that it will be useful, | |
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | // GNU General Public License for more details. | |
12 | // | |
13 | // You should have received a copy of the GNU General Public License | |
14 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
15 | ||
16 | /** | |
17 | * A javascript module to handle question tags editing. | |
18 | * | |
1db23e81 SS |
19 | * @deprecated since Moodle 4.0 |
20 | * @todo Final deprecation on Moodle 4.4 MDL-72438 | |
fd5e2ead SL |
21 | * @module core_question/edit_tags |
22 | * @copyright 2018 Simey Lameze <simey@moodle.com> | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | define([ | |
26 | 'jquery', | |
27 | 'core/fragment', | |
28 | 'core/str', | |
29 | 'core/modal_events', | |
30 | 'core/modal_factory', | |
31 | 'core/notification', | |
32 | 'core/custom_interaction_events', | |
33 | 'core_question/repository', | |
d1db765a | 34 | 'core_question/selectors', |
fd5e2ead SL |
35 | ], |
36 | function( | |
37 | $, | |
38 | Fragment, | |
39 | Str, | |
40 | ModalEvents, | |
41 | ModalFactory, | |
42 | Notification, | |
43 | CustomEvents, | |
d1db765a SL |
44 | Repository, |
45 | QuestionSelectors | |
fd5e2ead SL |
46 | ) { |
47 | ||
fd5e2ead SL |
48 | /** |
49 | * Enable the save button in the footer. | |
50 | * | |
51 | * @param {object} root The container element. | |
52 | * @method enableSaveButton | |
53 | */ | |
54 | var enableSaveButton = function(root) { | |
d1db765a | 55 | root.find(QuestionSelectors.actions.save).prop('disabled', false); |
fd5e2ead SL |
56 | }; |
57 | ||
58 | /** | |
59 | * Disable the save button in the footer. | |
60 | * | |
61 | * @param {object} root The container element. | |
62 | * @method disableSaveButton | |
63 | */ | |
64 | var disableSaveButton = function(root) { | |
d1db765a | 65 | root.find(QuestionSelectors.actions.save).prop('disabled', true); |
fd5e2ead SL |
66 | }; |
67 | ||
68 | /** | |
69 | * Get the serialised form data. | |
70 | * | |
71 | * @method getFormData | |
72 | * @param {object} modal The modal object. | |
73 | * @return {string} serialised form data | |
74 | */ | |
75 | var getFormData = function(modal) { | |
76 | return modal.getBody().find('form').serialize(); | |
77 | }; | |
78 | ||
79 | /** | |
80 | * Set the element state to loading. | |
81 | * | |
82 | * @param {object} root The container element | |
83 | * @method startLoading | |
84 | */ | |
85 | var startLoading = function(root) { | |
d1db765a | 86 | var loadingIconContainer = root.find(QuestionSelectors.containers.loadingIcon); |
fd5e2ead SL |
87 | |
88 | loadingIconContainer.removeClass('hidden'); | |
89 | }; | |
90 | ||
91 | /** | |
92 | * Remove the loading state from the element. | |
93 | * | |
94 | * @param {object} root The container element | |
95 | * @method stopLoading | |
96 | */ | |
97 | var stopLoading = function(root) { | |
d1db765a | 98 | var loadingIconContainer = root.find(QuestionSelectors.containers.loadingIcon); |
fd5e2ead SL |
99 | |
100 | loadingIconContainer.addClass('hidden'); | |
101 | }; | |
102 | ||
e6890b11 SL |
103 | /** |
104 | * Set the context Id data attribute on the modal. | |
105 | * | |
106 | * @param {Promise} modal The modal promise. | |
107 | * @param {int} contextId The context id. | |
108 | */ | |
109 | var setContextId = function(modal, contextId) { | |
110 | modal.getBody().attr('data-contextid', contextId); | |
111 | }; | |
112 | ||
113 | /** | |
114 | * Get the context Id data attribute value from the modal body. | |
115 | * | |
116 | * @param {Promise} modal The modal promise. | |
117 | * @return {int} The context id. | |
118 | */ | |
119 | var getContextId = function(modal) { | |
120 | return modal.getBody().data('contextid'); | |
121 | }; | |
122 | ||
123 | /** | |
124 | * Set the question Id data attribute on the modal. | |
125 | * | |
126 | * @param {Promise} modal The modal promise. | |
127 | * @param {int} questionId The question Id. | |
128 | */ | |
129 | var setQuestionId = function(modal, questionId) { | |
130 | modal.getBody().attr('data-questionid', questionId); | |
131 | }; | |
132 | ||
133 | /** | |
134 | * Get the question Id data attribute value from the modal body. | |
135 | * | |
136 | * @param {Promise} modal The modal promise. | |
137 | * @return {int} The question Id. | |
138 | */ | |
139 | var getQuestionId = function(modal) { | |
140 | return modal.getBody().data('questionid'); | |
141 | }; | |
142 | ||
fd5e2ead SL |
143 | /** |
144 | * Register event listeners for the module. | |
145 | * | |
146 | * @param {object} root The calendar root element | |
147 | */ | |
148 | var registerEventListeners = function(root) { | |
149 | var modalPromise = ModalFactory.create( | |
150 | { | |
151 | type: ModalFactory.types.SAVE_CANCEL, | |
152 | large: false | |
153 | }, | |
d1db765a | 154 | [root, QuestionSelectors.actions.edittags] |
fd5e2ead SL |
155 | ).then(function(modal) { |
156 | // All of this code only executes once, when the modal is | |
157 | // first created. This allows us to add any code that should | |
158 | // only be run once, such as adding event handlers to the modal. | |
159 | Str.get_string('questiontags', 'question') | |
160 | .then(function(string) { | |
161 | modal.setTitle(string); | |
162 | return string; | |
163 | }) | |
164 | .fail(Notification.exception); | |
165 | ||
166 | modal.getRoot().on(ModalEvents.save, function(e) { | |
167 | var form = modal.getBody().find('form'); | |
168 | form.submit(); | |
169 | e.preventDefault(); | |
170 | }); | |
171 | ||
172 | modal.getRoot().on('submit', 'form', function(e) { | |
173 | save(modal, root).then(function() { | |
174 | modal.hide(); | |
c91da280 | 175 | location.reload(); |
fd5e2ead SL |
176 | return; |
177 | }).fail(Notification.exception); | |
178 | ||
179 | // Stop the form from actually submitting and prevent it's | |
180 | // propagation because we have already handled the event. | |
181 | e.preventDefault(); | |
182 | e.stopPropagation(); | |
183 | }); | |
184 | ||
185 | return modal; | |
186 | }); | |
187 | ||
188 | // We need to add an event handler to the tags link because there are | |
189 | // multiple links on the page and without adding a listener we don't know | |
190 | // which one the user clicked on the show the modal. | |
d1db765a | 191 | root.on(CustomEvents.events.activate, QuestionSelectors.actions.edittags, function(e) { |
fd5e2ead SL |
192 | var currentTarget = $(e.currentTarget); |
193 | ||
194 | var questionId = currentTarget.data('questionid'), | |
e2795e86 | 195 | canTag = !!currentTarget.data('cantag'), |
fd5e2ead SL |
196 | contextId = currentTarget.data('contextid'); |
197 | ||
198 | // This code gets called each time the user clicks the tag link | |
199 | // so we can use it to reload the contents of the tag modal. | |
200 | modalPromise.then(function(modal) { | |
201 | // Display spinner and disable save button. | |
202 | disableSaveButton(root); | |
203 | startLoading(root); | |
204 | ||
205 | var args = { | |
206 | id: questionId | |
207 | }; | |
208 | ||
209 | var tagsFragment = Fragment.loadFragment('question', 'tags_form', contextId, args); | |
210 | modal.setBody(tagsFragment); | |
211 | ||
212 | tagsFragment.then(function() { | |
213 | enableSaveButton(root); | |
214 | return; | |
215 | }) | |
216 | .always(function() { | |
217 | // Always hide the loading spinner when the request | |
218 | // has completed. | |
219 | stopLoading(root); | |
220 | return; | |
221 | }) | |
222 | .fail(Notification.exception); | |
223 | ||
224 | // Show or hide the save button depending on whether the user | |
225 | // has the capability to edit the tags. | |
e2795e86 | 226 | if (canTag) { |
d1db765a | 227 | modal.getRoot().find(QuestionSelectors.actions.save).show(); |
fd5e2ead | 228 | } else { |
d1db765a | 229 | modal.getRoot().find(QuestionSelectors.actions.save).hide(); |
fd5e2ead SL |
230 | } |
231 | ||
e6890b11 SL |
232 | setQuestionId(modal, questionId); |
233 | setContextId(modal, contextId); | |
234 | ||
fd5e2ead SL |
235 | return modal; |
236 | }).fail(Notification.exception); | |
237 | ||
238 | e.preventDefault(); | |
239 | }); | |
240 | }; | |
241 | ||
242 | /** | |
243 | * Send the form data to the server to save question tags. | |
244 | * | |
245 | * @method save | |
246 | * @param {object} modal The modal object. | |
247 | * @param {object} root The container element. | |
248 | * @return {object} A promise | |
249 | */ | |
250 | var save = function(modal, root) { | |
251 | // Display spinner and disable save button. | |
252 | disableSaveButton(root); | |
253 | startLoading(root); | |
254 | ||
255 | var formData = getFormData(modal); | |
e6890b11 SL |
256 | var questionId = getQuestionId(modal); |
257 | var contextId = getContextId(modal); | |
fd5e2ead SL |
258 | |
259 | // Send the form data to the server for processing. | |
e6890b11 | 260 | return Repository.submitTagCreateUpdateForm(questionId, contextId, formData) |
fd5e2ead SL |
261 | .always(function() { |
262 | // Regardless of success or error we should always stop | |
263 | // the loading icon and re-enable the buttons. | |
264 | stopLoading(root); | |
265 | enableSaveButton(root); | |
266 | return; | |
267 | }) | |
268 | .fail(Notification.exception); | |
269 | }; | |
270 | ||
271 | return { | |
272 | init: function(root) { | |
1db23e81 SS |
273 | window.console.warn('warn: The core_question/repository has been deprecated.' + |
274 | 'Please use qbank_tagquestion/repository instead.'); | |
fd5e2ead SL |
275 | root = $(root); |
276 | registerEventListeners(root); | |
277 | } | |
278 | }; | |
279 | }); |