1 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
17 * Add policy consent modal to the page
19 * @module tool_policy/acceptmodal
20 * @copyright 2018 Marina Glancy
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 'core/modal_save_cancel',
31 'core_form/changechecker',
48 * @param {int} contextid
50 * Each call to init gets it's own instance of this class.
52 var AcceptOnBehalf = function(contextid) {
53 this.contextid = contextid;
61 AcceptOnBehalf.prototype.modal = null;
64 * @var {int} contextid
67 AcceptOnBehalf.prototype.contextid = -1;
70 * @var {object} currentTrigger The triggered HTML jQuery object
73 AcceptOnBehalf.prototype.currentTrigger = null;
76 * @var {object} triggers The trigger selectors
79 AcceptOnBehalf.prototype.triggers = {
80 SINGLE: 'a[data-action=acceptmodal]',
81 BULK: 'input[data-action=acceptmodal]'
85 * Initialise the class.
89 AcceptOnBehalf.prototype.init = function() {
90 // Initialise for links accepting policies for individual users.
91 $(this.triggers.SINGLE).on('click', function(e) {
93 this.currentTrigger = $(e.currentTarget);
94 var href = $(e.currentTarget).attr('href'),
95 formData = href.slice(href.indexOf('?') + 1);
96 this.showFormModal(formData);
99 // Initialise for multiple users acceptance form.
100 $(this.triggers.BULK).on('click', function(e) {
102 this.currentTrigger = $(e.currentTarget);
103 var form = $(e.currentTarget).closest('form');
104 if (form.find('input[type=checkbox][name="userids[]"]:checked').length) {
105 var formData = form.serialize();
106 this.showFormModal(formData);
110 {key: 'selectusersforconsent', component: 'tool_policy'},
112 ]).then(function(strings) {
113 Notification.alert(strings[0], strings[1], strings[2]);
115 }).fail(Notification.exception);
121 * Show modal with a form
123 * @param {String} formData
125 AcceptOnBehalf.prototype.showFormModal = function(formData) {
127 var params = formData.split('&');
128 for (var i = 0; i < params.length; i++) {
129 var pair = params[i].split('=');
130 if (pair[0] == 'action') {
134 // Fetch the title string.
136 {key: 'statusformtitleaccept', component: 'tool_policy'},
137 {key: 'iagreetothepolicy', component: 'tool_policy'},
138 {key: 'statusformtitlerevoke', component: 'tool_policy'},
139 {key: 'irevokethepolicy', component: 'tool_policy'},
140 {key: 'statusformtitledecline', component: 'tool_policy'},
141 {key: 'declinethepolicy', component: 'tool_policy'}
142 ]).then(function(strings) {
145 if (action == 'accept') {
147 saveText = strings[1];
148 } else if (action == 'revoke') {
150 saveText = strings[3];
151 } else if (action == 'decline') {
153 saveText = strings[5];
156 return ModalSaveCancel.create({
159 }).then(function(modal) {
161 this.setupFormModal(formData, saveText);
164 .catch(Notification.exception);
168 * Setup form inside a modal
170 * @param {String} formData
171 * @param {String} saveText
173 AcceptOnBehalf.prototype.setupFormModal = function(formData, saveText) {
174 var modal = this.modal;
178 modal.setSaveButtonText(saveText);
180 // We want to reset the form every time it is opened.
181 modal.getRoot().on(ModalEvents.hidden, this.destroy.bind(this));
183 modal.setBody(this.getBody(formData));
185 // We catch the modal save event, and use it to submit the form inside the modal.
186 // Triggering a form submission will give JS validation scripts a chance to check for errors.
187 modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));
188 // We also catch the form submit event and use it to submit the form with ajax.
189 modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));
195 * Load the body of the modal (contains the form)
199 * @param {String} formData
202 AcceptOnBehalf.prototype.getBody = function(formData) {
203 if (typeof formData === "undefined") {
206 // Get the content of the modal.
207 var params = {jsonformdata: JSON.stringify(formData)};
208 return Fragment.loadFragment('tool_policy', 'accept_on_behalf', this.contextid, params);
212 * Submit the form inside the modal via AJAX request
214 * @method submitFormAjax
216 * @param {Event} e Form submission event.
218 AcceptOnBehalf.prototype.submitFormAjax = function(e) {
219 // We don't want to do a real form submission.
222 // Convert all the form elements values to a serialised string.
223 var formData = this.modal.getRoot().find('form').serialize();
225 var requests = Ajax.call([{
226 methodname: 'tool_policy_submit_accept_on_behalf',
227 args: {jsonformdata: JSON.stringify(formData)}
229 requests[0].done(function(data) {
230 if (data.validationerrors) {
231 this.modal.setBody(this.getBody(formData));
235 }.bind(this)).fail(Notification.exception);
239 * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.
242 * @param {Event} e Form submission event.
245 AcceptOnBehalf.prototype.submitForm = function(e) {
247 this.modal.getRoot().find('form').submit();
253 AcceptOnBehalf.prototype.close = function() {
255 document.location.reload();
261 AcceptOnBehalf.prototype.destroy = function() {
262 FormChangeChecker.resetAllFormDirtyStates();
263 this.modal.destroy();
264 this.currentTrigger.focus();
267 return /** @alias module:tool_policy/acceptmodal */ {
268 // Public variables and functions.
270 * Attach event listeners to initialise this module.
273 * @param {int} contextid The contextid for the course.
274 * @return {AcceptOnBehalf}
276 getInstance: function(contextid) {
277 return new AcceptOnBehalf(contextid);