MDL-62746 tag: Make forms in tag modals use proper BS classes
[moodle.git] / lib / amd / src / tag.js
CommitLineData
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 */
e7ecb4a9
DP
25define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str', 'core/yui'],
26 function($, ajax, templates, notification, str, Y) {
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);
145 str.get_strings([
35be5826
DP
146 {key: 'combineselected', component: 'tag'},
147 {key: 'selectmaintag', component: 'tag'},
148 {key: 'continue'},
149 {key: 'cancel'},
0d202789 150 ]).done(function(s) {
d7ae1a92
JP
151 var el = $('<div><form id="combinetags_form">' +
152 '<div class="description"></div><div class="form-group options"></div>' +
153 '<div class="form-group">' +
154 ' <input type="submit" class="btn btn-primary" id="combinetags_submit"/>' +
155 ' <input type="button" class="btn btn-secondary" id="combinetags_cancel"/>' +
156 '</div>' +
0d202789
MG
157 '</form></div>');
158 el.find('.description').html(s[1]);
159 el.find('#combinetags_submit').attr('value', s[2]);
160 el.find('#combinetags_cancel').attr('value', s[3]);
161 var fldset = el.find('.options');
162 tags.each(function() {
163 var tagid = $(this).val(),
35be5826 164 tagname = $('.inplaceeditable[data-itemtype=tagname][data-itemid=' + tagid + ']').attr('data-value');
d7ae1a92
JP
165 var option = '<div class="form-check">' +
166 ' <input type="radio" class="form-check-input" name="maintag" ' +
167 ' id="combinetags_maintag_' + tagid + '" value="' + tagid + '"/>' +
168 ' <label class="form-check-label" for="combinetags_maintag_' + tagid + '">' + tagname + '</label>' +
169 '</div>';
170 fldset.append($(option));
0d202789 171 });
e7ecb4a9
DP
172 // TODO: MDL-57778 Convert to core/modal.
173 Y.use('moodle-core-notification-dialogue', function() {
174 var panel = new M.core.dialogue({
175 draggable: true,
176 modal: true,
177 closeButton: true,
178 headerContent: s[0],
179 bodyContent: el.html()
180 });
181 panel.show();
182 $('#combinetags_form input[type=radio]').first().focus().prop('checked', true);
183 $('#combinetags_form #combinetags_cancel').on('click', function() {
184 panel.destroy();
185 });
186 $('#combinetags_form').on('submit', function() {
187 tempElement.appendTo(form);
188 var maintag = $('input[name=maintag]:checked', '#combinetags_form').val();
189 $("<input type='hidden'/>").attr('name', 'maintag').attr('value', maintag).appendTo(form);
190 form.submit();
191 return false;
192 });
0d202789
MG
193 });
194 });
195 });
196
197 // When user changes tag name to some name that already exists suggest to combine the tags.
198 $('body').on('updatefailed', '[data-inplaceeditable][data-itemtype=tagname]', function(e) {
199 var exception = e.exception; // The exception object returned by the callback.
200 var newvalue = e.newvalue; // The value that user tried to udpated the element to.
201 var tagid = $(e.target).attr('data-itemid');
202 if (exception.errorcode === 'namesalreadybeeingused') {
203 e.preventDefault(); // This will prevent default error dialogue.
204 str.get_strings([
35be5826
DP
205 {key: 'nameuseddocombine', component: 'tag'},
206 {key: 'yes'},
207 {key: 'cancel'},
0d202789
MG
208 ]).done(function(s) {
209 notification.confirm(e.message, s[0], s[1], s[2], function() {
210 window.location.href = window.location.href + "&newname=" + encodeURIComponent(newvalue) +
211 "&tagid=" + encodeURIComponent(tagid) +
212 '&action=renamecombine&sesskey=' + M.cfg.sesskey;
213 });
214 });
215 }
216 });
1e34257e
MG
217
218 // Form for adding standard tags.
219 $('body').on('click', 'a[data-action=addstandardtag]', function(e) {
220 e.preventDefault();
221 str.get_strings([
35be5826
DP
222 {key: 'addotags', component: 'tag'},
223 {key: 'inputstandardtags', component: 'tag'},
224 {key: 'continue'},
225 {key: 'cancel'},
1e34257e 226 ]).done(function(s) {
d7ae1a92 227 var el = $('<div><form id="addtags_form" method="POST">' +
1e34257e
MG
228 '<input type="hidden" name="action" value="addstandardtag"/>' +
229 '<input type="hidden" name="sesskey" value="' + M.cfg.sesskey + '"/>' +
d7ae1a92
JP
230 '<div class="form-group">' +
231 ' <label for="id_tagslist">' + s[1] + '</label>' +
232 ' <input type="text" id="id_tagslist" class="form-control" name="tagslist"/>' +
233 '</div>' +
234 '<div class="form-group">' +
235 ' <input type="submit" class="btn btn-primary" id="addtags_submit"/>' +
236 ' <input type="button" class="btn btn-secondary" id="addtags_cancel"/>' +
237 '</div>' +
1e34257e
MG
238 '</form></div>');
239 el.find('#addtags_form').attr('action', window.location.href);
240 el.find('#addtags_submit').attr('value', s[2]);
241 el.find('#addtags_cancel').attr('value', s[3]);
e7ecb4a9
DP
242 // TODO: MDL-57778 Convert to core/modal.
243 Y.use('moodle-core-notification-dialogue', function() {
244 var panel = new M.core.dialogue({
245 draggable: true,
246 modal: true,
247 closeButton: true,
248 headerContent: s[0],
249 bodyContent: el.html()
250 });
251 panel.show();
252 $('#addtags_form input[type=text]').focus();
253 $('#addtags_form #addtags_cancel').on('click', function() {
254 panel.destroy();
255 });
1e34257e
MG
256 });
257 });
258 });
131b78b9
MG
259 },
260
261 /**
262 * Initialises tag collection management page.
263 *
264 * @method initManageCollectionsPage
265 */
266 initManageCollectionsPage: function() {
267 $('body').on('updated', '[data-inplaceeditable]', function(e) {
352bfbf5 268 var ajaxreturn = e.ajaxreturn,
352bfbf5 269 areaid, collid, isenabled;
131b78b9 270 if (ajaxreturn.component === 'core_tag' && ajaxreturn.itemtype === 'tagareaenable') {
352bfbf5 271 areaid = $(this).attr('data-itemid');
63e4df60 272 $(".tag-collections-table ul[data-collectionid] li[data-areaid=" + areaid + "]").hide();
352bfbf5 273 isenabled = ajaxreturn.value;
131b78b9
MG
274 if (isenabled === '1') {
275 $(this).closest('tr').removeClass('dimmed_text');
352bfbf5 276 collid = $(this).closest('tr').find('[data-itemtype="tagareacollection"]').attr("data-value");
63e4df60 277 $(".tag-collections-table ul[data-collectionid=" + collid + "] li[data-areaid=" + areaid + "]").show();
131b78b9
MG
278 } else {
279 $(this).closest('tr').addClass('dimmed_text');
280 }
281 }
282 if (ajaxreturn.component === 'core_tag' && ajaxreturn.itemtype === 'tagareacollection') {
352bfbf5 283 areaid = $(this).attr('data-itemid');
63e4df60 284 $(".tag-collections-table ul[data-collectionid] li[data-areaid=" + areaid + "]").hide();
352bfbf5
MG
285 collid = $(this).attr('data-value');
286 isenabled = $(this).closest('tr').find('[data-itemtype="tagareaenable"]').attr("data-value");
131b78b9 287 if (isenabled === "1") {
63e4df60 288 $(".tag-collections-table ul[data-collectionid=" + collid + "] li[data-areaid=" + areaid + "]").show();
131b78b9
MG
289 }
290 }
352bfbf5
MG
291 });
292
293 $('body').on('click', '.addtagcoll > a', function(e) {
294 e.preventDefault();
295 var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey;
296 str.get_strings([
35be5826
DP
297 {key: 'addtagcoll', component: 'tag'},
298 {key: 'name'},
299 {key: 'searchable', component: 'tag'},
300 {key: 'create'},
301 {key: 'cancel'},
352bfbf5 302 ]).done(function(s) {
d7ae1a92
JP
303 var el = $('<div><form id="addtagcoll_form">' +
304 '<div class="form-group">' +
305 ' <label for="addtagcoll_name"></label> ' +
306 ' <input id="addtagcoll_name" type="text" class="form-control"/> ' +
307 '</div>' +
308 '<div class="form-group form-check">' +
309 ' <input id="addtagcoll_searchable" type="checkbox" value="1" checked class="form-check-input"/>' +
310 ' <label for="addtagcoll_searchable" class="form-check-label"></label>' +
311 '</div>' +
312 '<div class="form-group">' +
313 ' <input type="submit" class="btn btn-primary" id="addtagcoll_submit"/>' +
314 ' <input type="button" class="btn btn-secondary" id="addtagcoll_cancel"/>' +
315 '</div>' +
352bfbf5
MG
316 '</form></div>');
317 el.find('label[for="addtagcoll_name"]').html(s[1]);
318 el.find('label[for="addtagcoll_searchable"]').html(s[2]);
319 el.find('#addtagcoll_submit').attr('value', s[3]);
320 el.find('#addtagcoll_cancel').attr('value', s[4]);
e7ecb4a9
DP
321 // TODO: MDL-57778 Convert to core/modal.
322 Y.use('moodle-core-notification-dialogue', function() {
323 var panel = new M.core.dialogue({
324 draggable: true,
325 modal: true,
326 closeButton: true,
327 headerContent: s[0],
328 bodyContent: el.html()
329 });
330 panel.show();
331 $('#addtagcoll_form #addtagcoll_name').focus();
332 $('#addtagcoll_form #addtagcoll_cancel').on('click', function() {
333 panel.destroy();
334 });
335 $('#addtagcoll_form').on('submit', function() {
336 var name = $('#addtagcoll_form #addtagcoll_name').val();
337 var searchable = $('#addtagcoll_form #addtagcoll_searchable').prop('checked') ? 1 : 0;
338 if (String(name).length > 0) {
339 window.location.href = href + "&name=" + encodeURIComponent(name) + "&searchable=" + searchable;
340 }
341 return false;
342 });
352bfbf5
MG
343 });
344 }
345 );
346
347 });
348
349 $('body').on('click', '.tag-collections-table .action_delete', function(e) {
350 e.preventDefault();
351 var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey;
352 str.get_strings([
35be5826 353 {key: 'delete'},
9f5f3dcc 354 {key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname')},
35be5826
DP
355 {key: 'yes'},
356 {key: 'no'},
352bfbf5
MG
357 ]).done(function(s) {
358 notification.confirm(s[0], s[1], s[2], s[3], function() {
359 window.location.href = href;
360 });
361 }
362 );
363 });
8e355853
MG
364 }
365 };
c96f55e6 366});