Commit | Line | Data |
---|---|---|
8e355853 MG |
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 | * AJAX helper for the tag management page. | |
18 | * | |
19 | * @module core/tag | |
20 | * @package core_tag | |
21 | * @copyright 2015 Marina Glancy | |
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
23 | * @since 3.0 | |
24 | */ | |
65cac800 JP |
25 | define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str', 'core/modal_factory', 'core/modal_events'], |
26 | function($, ajax, templates, notification, str, ModalFactory, ModalEvents) { | |
8e355853 MG |
27 | return /** @alias module:core/tag */ { |
28 | ||
29 | /** | |
c026a28d | 30 | * Initialises tag index page. |
8e355853 | 31 | * |
131b78b9 | 32 | * @method initTagindexPage |
c026a28d | 33 | */ |
131b78b9 | 34 | initTagindexPage: function() { |
c026a28d MG |
35 | // Click handler for changing tag type. |
36 | $('body').delegate('.tagarea[data-ta] a[data-quickload=1]', 'click', function(e) { | |
37 | e.preventDefault(); | |
35be5826 | 38 | var target = $(this), |
eb3839df | 39 | query = target[0].search.replace(/^\?/, ''), |
c026a28d | 40 | tagarea = target.closest('.tagarea[data-ta]'), |
c96f55e6 DP |
41 | args = query.split('&').reduce(function(s, c) { |
42 | var t = c.split('='); | |
43 | s[t[0]] = decodeURIComponent(t[1]); | |
44 | return s; | |
45 | }, {}); | |
c026a28d MG |
46 | |
47 | var promises = ajax.call([{ | |
48 | methodname: 'core_tag_get_tagindex', | |
9f5f3dcc | 49 | args: {tagindex: args} |
c026a28d MG |
50 | }], true); |
51 | ||
52 | $.when.apply($, promises) | |
35be5826 | 53 | .done(function(data) { |
c026a28d MG |
54 | templates.render('core_tag/index', data).done(function(html) { |
55 | tagarea.replaceWith(html); | |
56 | }); | |
57 | }); | |
58 | }); | |
59 | }, | |
60 | ||
61 | /** | |
62 | * Initialises tag management page. | |
63 | * | |
131b78b9 | 64 | * @method initManagePage |
8e355853 | 65 | */ |
131b78b9 | 66 | initManagePage: function() { |
8e355853 | 67 | |
21d9596c MG |
68 | // Set cell 'time modified' to 'now' when any of the element is updated in this row. |
69 | $('body').on('updated', '[data-inplaceeditable]', function(e) { | |
39e14b23 AN |
70 | str.get_string('selecttag', 'core_tag', e.ajaxreturn.value) |
71 | .then(function(s) { | |
72 | return $('label[for="tagselect' + e.ajaxreturn.itemid + '"]').html(s); | |
73 | }) | |
74 | .fail(notification.exception); | |
21d9596c MG |
75 | str.get_string('now').done(function(s) { |
76 | $(e.target).closest('tr').find('td.col-timemodified').html(s); | |
77 | }); | |
78 | if (e.ajaxreturn.itemtype === 'tagflag') { | |
79 | var row = $(e.target).closest('tr'); | |
80 | if (e.ajaxreturn.value === '0') { | |
81 | row.removeClass('flagged-tag'); | |
82 | } else { | |
83 | row.addClass('flagged-tag'); | |
84 | } | |
8e355853 | 85 | } |
8e355853 MG |
86 | }); |
87 | ||
88 | // Confirmation for single tag delete link. | |
89 | $('.tag-management-table').delegate('a.tagdelete', 'click', function(e) { | |
90 | e.preventDefault(); | |
91 | var href = $(this).attr('href'); | |
92 | str.get_strings([ | |
35be5826 DP |
93 | {key: 'delete'}, |
94 | {key: 'confirmdeletetag', component: 'tag'}, | |
95 | {key: 'yes'}, | |
96 | {key: 'no'}, | |
8e355853 MG |
97 | ]).done(function(s) { |
98 | notification.confirm(s[0], s[1], s[2], s[3], function() { | |
99 | window.location.href = href; | |
100 | }); | |
101 | } | |
102 | ); | |
103 | }); | |
104 | ||
105 | // Confirmation for bulk tag delete button. | |
35be5826 | 106 | $("#tag-management-delete").click(function(e) { |
8e355853 MG |
107 | var form = $(this).closest('form').get(0), |
108 | cnt = $(form).find("input[type=checkbox]:checked").length; | |
109 | if (!cnt) { | |
5602dc17 | 110 | return; |
8e355853 | 111 | } |
0d202789 | 112 | var tempElement = $("<input type='hidden'/>").attr('name', this.name); |
8e355853 MG |
113 | e.preventDefault(); |
114 | str.get_strings([ | |
35be5826 DP |
115 | {key: 'delete'}, |
116 | {key: 'confirmdeletetags', component: 'tag'}, | |
117 | {key: 'yes'}, | |
118 | {key: 'no'}, | |
8e355853 MG |
119 | ]).done(function(s) { |
120 | notification.confirm(s[0], s[1], s[2], s[3], function() { | |
0d202789 | 121 | tempElement.appendTo(form); |
8e355853 MG |
122 | form.submit(); |
123 | }); | |
124 | } | |
125 | ); | |
126 | }); | |
0d202789 MG |
127 | |
128 | // Confirmation for bulk tag combine button. | |
35be5826 | 129 | $("#tag-management-combine").click(function(e) { |
0d202789 MG |
130 | e.preventDefault(); |
131 | var form = $(this).closest('form').get(0), | |
132 | tags = $(form).find("input[type=checkbox]:checked"); | |
133 | if (tags.length <= 1) { | |
134 | str.get_strings([ | |
35be5826 DP |
135 | {key: 'combineselected', component: 'tag'}, |
136 | {key: 'selectmultipletags', component: 'tag'}, | |
137 | {key: 'ok'}, | |
0d202789 MG |
138 | ]).done(function(s) { |
139 | notification.alert(s[0], s[1], s[2]); | |
140 | } | |
141 | ); | |
5602dc17 | 142 | return; |
0d202789 MG |
143 | } |
144 | var tempElement = $("<input type='hidden'/>").attr('name', this.name); | |
65cac800 JP |
145 | var saveButtonText = ''; |
146 | var tagOptions = []; | |
147 | tags.each(function() { | |
148 | var tagid = $(this).val(), | |
149 | tagname = $('.inplaceeditable[data-itemtype=tagname][data-itemid=' + tagid + ']').attr('data-value'); | |
150 | tagOptions.push({ | |
151 | id: tagid, | |
152 | name: tagname | |
153 | }); | |
154 | }); | |
155 | ||
0d202789 | 156 | str.get_strings([ |
35be5826 | 157 | {key: 'combineselected', component: 'tag'}, |
65cac800 JP |
158 | {key: 'continue'} |
159 | ]).then(function(langStrings) { | |
160 | var modalTitle = langStrings[0]; | |
161 | saveButtonText = langStrings[1]; | |
162 | var templateContext = { | |
163 | tags: tagOptions | |
164 | }; | |
165 | return ModalFactory.create({ | |
166 | title: modalTitle, | |
167 | body: templates.render('core_tag/combine_tags', templateContext), | |
168 | type: ModalFactory.types.SAVE_CANCEL | |
0d202789 | 169 | }); |
65cac800 JP |
170 | }).then(function(modal) { |
171 | modal.setSaveButtonText(saveButtonText); | |
172 | ||
173 | // Handle save event. | |
174 | modal.getRoot().on(ModalEvents.save, function(e) { | |
175 | e.preventDefault(); | |
176 | ||
177 | // Append this temp element in the form in the tags list, not the form in the modal. Confusing, right?!? | |
178 | tempElement.appendTo(form); | |
179 | // Get the selected tag from the modal. | |
180 | var maintag = $('input[name=maintag]:checked', '#combinetags_form').val(); | |
181 | // Append this in the tags list form. | |
182 | $("<input type='hidden'/>").attr('name', 'maintag').attr('value', maintag).appendTo(form); | |
183 | // Submit the tags list form. | |
184 | form.submit(); | |
0d202789 | 185 | }); |
65cac800 JP |
186 | |
187 | // Handle hidden event. | |
188 | modal.getRoot().on(ModalEvents.hidden, function() { | |
189 | // Destroy when hidden. | |
190 | modal.destroy(); | |
191 | }); | |
192 | ||
193 | modal.show(); | |
194 | // Tick the first option. | |
195 | $('#combinetags_form input[type=radio]').first().focus().prop('checked', true); | |
196 | ||
197 | return; | |
198 | ||
199 | }).catch(notification.exception); | |
0d202789 MG |
200 | }); |
201 | ||
202 | // When user changes tag name to some name that already exists suggest to combine the tags. | |
203 | $('body').on('updatefailed', '[data-inplaceeditable][data-itemtype=tagname]', function(e) { | |
204 | var exception = e.exception; // The exception object returned by the callback. | |
205 | var newvalue = e.newvalue; // The value that user tried to udpated the element to. | |
206 | var tagid = $(e.target).attr('data-itemid'); | |
207 | if (exception.errorcode === 'namesalreadybeeingused') { | |
208 | e.preventDefault(); // This will prevent default error dialogue. | |
209 | str.get_strings([ | |
35be5826 DP |
210 | {key: 'nameuseddocombine', component: 'tag'}, |
211 | {key: 'yes'}, | |
212 | {key: 'cancel'}, | |
0d202789 MG |
213 | ]).done(function(s) { |
214 | notification.confirm(e.message, s[0], s[1], s[2], function() { | |
215 | window.location.href = window.location.href + "&newname=" + encodeURIComponent(newvalue) + | |
216 | "&tagid=" + encodeURIComponent(tagid) + | |
217 | '&action=renamecombine&sesskey=' + M.cfg.sesskey; | |
218 | }); | |
219 | }); | |
220 | } | |
221 | }); | |
1e34257e MG |
222 | |
223 | // Form for adding standard tags. | |
224 | $('body').on('click', 'a[data-action=addstandardtag]', function(e) { | |
225 | e.preventDefault(); | |
65cac800 JP |
226 | |
227 | var saveButtonText = ''; | |
1e34257e | 228 | str.get_strings([ |
35be5826 | 229 | {key: 'addotags', component: 'tag'}, |
65cac800 JP |
230 | {key: 'continue'} |
231 | ]).then(function(langStrings) { | |
232 | var modalTitle = langStrings[0]; | |
233 | saveButtonText = langStrings[1]; | |
234 | var templateContext = { | |
235 | actionurl: window.location.href, | |
236 | sesskey: M.cfg.sesskey | |
237 | }; | |
238 | return ModalFactory.create({ | |
239 | title: modalTitle, | |
240 | body: templates.render('core_tag/add_tags', templateContext), | |
241 | type: ModalFactory.types.SAVE_CANCEL | |
242 | }); | |
243 | }).then(function(modal) { | |
244 | modal.setSaveButtonText(saveButtonText); | |
245 | ||
246 | // Handle save event. | |
247 | modal.getRoot().on(ModalEvents.save, function(e) { | |
248 | var tagsInput = $(e.currentTarget).find('#id_tagslist'); | |
249 | var name = tagsInput.val().trim(); | |
250 | ||
251 | // Set the text field's value to the trimmed value. | |
252 | tagsInput.val(name); | |
253 | ||
254 | // Add submit event listener to the form. | |
255 | var tagsForm = $('#addtags_form'); | |
256 | tagsForm.on('submit', function(e) { | |
257 | // Validate the form. | |
258 | var form = $('#addtags_form'); | |
259 | if (form[0].checkValidity() === false) { | |
260 | e.preventDefault(); | |
261 | e.stopPropagation(); | |
262 | } | |
263 | form.addClass('was-validated'); | |
264 | ||
265 | // BS2 compatibility. | |
266 | $('[data-region="tagslistinput"]').addClass('error'); | |
267 | var errorMessage = $('#id_tagslist_error_message'); | |
268 | errorMessage.removeAttr('hidden'); | |
269 | errorMessage.addClass('help-block'); | |
e7ecb4a9 | 270 | }); |
65cac800 JP |
271 | |
272 | // Try to submit the form. | |
273 | tagsForm.submit(); | |
274 | ||
275 | return false; | |
1e34257e | 276 | }); |
65cac800 JP |
277 | |
278 | // Handle hidden event. | |
279 | modal.getRoot().on(ModalEvents.hidden, function() { | |
280 | // Destroy when hidden. | |
281 | modal.destroy(); | |
282 | }); | |
283 | ||
284 | modal.show(); | |
285 | ||
286 | return; | |
287 | ||
288 | }).catch(notification.exception); | |
1e34257e | 289 | }); |
131b78b9 MG |
290 | }, |
291 | ||
292 | /** | |
293 | * Initialises tag collection management page. | |
294 | * | |
295 | * @method initManageCollectionsPage | |
296 | */ | |
297 | initManageCollectionsPage: function() { | |
298 | $('body').on('updated', '[data-inplaceeditable]', function(e) { | |
352bfbf5 | 299 | var ajaxreturn = e.ajaxreturn, |
352bfbf5 | 300 | areaid, collid, isenabled; |
131b78b9 | 301 | if (ajaxreturn.component === 'core_tag' && ajaxreturn.itemtype === 'tagareaenable') { |
352bfbf5 | 302 | areaid = $(this).attr('data-itemid'); |
63e4df60 | 303 | $(".tag-collections-table ul[data-collectionid] li[data-areaid=" + areaid + "]").hide(); |
352bfbf5 | 304 | isenabled = ajaxreturn.value; |
131b78b9 MG |
305 | if (isenabled === '1') { |
306 | $(this).closest('tr').removeClass('dimmed_text'); | |
352bfbf5 | 307 | collid = $(this).closest('tr').find('[data-itemtype="tagareacollection"]').attr("data-value"); |
63e4df60 | 308 | $(".tag-collections-table ul[data-collectionid=" + collid + "] li[data-areaid=" + areaid + "]").show(); |
131b78b9 MG |
309 | } else { |
310 | $(this).closest('tr').addClass('dimmed_text'); | |
311 | } | |
312 | } | |
313 | if (ajaxreturn.component === 'core_tag' && ajaxreturn.itemtype === 'tagareacollection') { | |
352bfbf5 | 314 | areaid = $(this).attr('data-itemid'); |
63e4df60 | 315 | $(".tag-collections-table ul[data-collectionid] li[data-areaid=" + areaid + "]").hide(); |
352bfbf5 MG |
316 | collid = $(this).attr('data-value'); |
317 | isenabled = $(this).closest('tr').find('[data-itemtype="tagareaenable"]').attr("data-value"); | |
131b78b9 | 318 | if (isenabled === "1") { |
63e4df60 | 319 | $(".tag-collections-table ul[data-collectionid=" + collid + "] li[data-areaid=" + areaid + "]").show(); |
131b78b9 MG |
320 | } |
321 | } | |
352bfbf5 MG |
322 | }); |
323 | ||
324 | $('body').on('click', '.addtagcoll > a', function(e) { | |
325 | e.preventDefault(); | |
65cac800 JP |
326 | var keys = [ |
327 | { | |
328 | key: 'addtagcoll', | |
329 | component: 'tag' | |
330 | }, | |
331 | { | |
332 | key: 'create' | |
352bfbf5 | 333 | } |
65cac800 JP |
334 | ]; |
335 | ||
336 | var href = $(this).attr('data-url'); | |
337 | var saveButtonText = ''; | |
338 | str.get_strings(keys).then(function(langStrings) { | |
339 | var modalTitle = langStrings[0]; | |
340 | saveButtonText = langStrings[1]; | |
341 | var templateContext = { | |
342 | actionurl: href, | |
343 | sesskey: M.cfg.sesskey | |
344 | }; | |
345 | return ModalFactory.create({ | |
346 | title: modalTitle, | |
347 | body: templates.render('core_tag/add_tag_collection', templateContext), | |
348 | type: ModalFactory.types.SAVE_CANCEL | |
349 | }); | |
350 | }).then(function(modal) { | |
351 | modal.setSaveButtonText(saveButtonText); | |
352 | ||
353 | // Handle save event. | |
354 | modal.getRoot().on(ModalEvents.save, function(e) { | |
355 | var collectionInput = $(e.currentTarget).find('#addtagcoll_name'); | |
356 | var name = collectionInput.val().trim(); | |
357 | // Set the text field's value to the trimmed value. | |
358 | collectionInput.val(name); | |
359 | ||
360 | // Add submit event listener to the form. | |
361 | var form = $('#addtagcoll_form'); | |
362 | form.on('submit', function(e) { | |
363 | // Validate the form. | |
364 | if (form[0].checkValidity() === false) { | |
365 | e.preventDefault(); | |
366 | e.stopPropagation(); | |
367 | } | |
368 | form.addClass('was-validated'); | |
369 | ||
370 | // BS2 compatibility. | |
371 | $('[data-region="addtagcoll_nameinput"]').addClass('error'); | |
372 | var errorMessage = $('#id_addtagcoll_name_error_message'); | |
373 | errorMessage.removeAttr('hidden'); | |
374 | errorMessage.addClass('help-block'); | |
375 | }); | |
376 | ||
377 | // Try to submit the form. | |
378 | form.submit(); | |
379 | ||
380 | return false; | |
381 | }); | |
382 | ||
383 | // Handle hidden event. | |
384 | modal.getRoot().on(ModalEvents.hidden, function() { | |
385 | // Destroy when hidden. | |
386 | modal.destroy(); | |
387 | }); | |
388 | ||
389 | modal.show(); | |
390 | ||
391 | return; | |
352bfbf5 | 392 | |
65cac800 | 393 | }).catch(notification.exception); |
352bfbf5 MG |
394 | }); |
395 | ||
396 | $('body').on('click', '.tag-collections-table .action_delete', function(e) { | |
397 | e.preventDefault(); | |
398 | var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey; | |
399 | str.get_strings([ | |
35be5826 | 400 | {key: 'delete'}, |
9f5f3dcc | 401 | {key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname')}, |
35be5826 DP |
402 | {key: 'yes'}, |
403 | {key: 'no'}, | |
352bfbf5 MG |
404 | ]).done(function(s) { |
405 | notification.confirm(s[0], s[1], s[2], s[3], function() { | |
406 | window.location.href = href; | |
407 | }); | |
408 | } | |
409 | ); | |
410 | }); | |
8e355853 MG |
411 | } |
412 | }; | |
c96f55e6 | 413 | }); |