MDL-60590 enrol_manual: Fix for race condition in button calculation
[moodle.git] / enrol / manual / amd / src / quickenrolment.js
CommitLineData
a60e8ba5
DW
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 * Quick enrolment AMD module.
18 *
19 * @module enrol_manual/quickenrolment
20 * @copyright 2016 Damyon Wiese <damyon@moodle.com>
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23define(['core/templates',
24 'jquery',
25 'core/str',
26 'core/config',
27 'core/notification',
28 'core/modal_factory',
29 'core/modal_events',
30 'core/fragment',
31 ],
32 function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment) {
33
9b0f2923
MN
34 /** @type {Object} The list of selectors for the quick enrolment modal. */
35 var SELECTORS = {
36 COHORTSELECT: "#id_cohortlist",
37 TRIGGERBUTTONS: ".enrolusersbutton.enrol_manual_plugin [type='submit']",
38 UNWANTEDHIDDENFIELDS: ":input[value='_qf__force_multiselect_submission']"
39 };
40
a60e8ba5
DW
41 /**
42 * Constructor
43 *
2e1615f2 44 * @param {Object} options Object containing options. The only valid option at this time is contextid.
a60e8ba5
DW
45 * Each call to templates.render gets it's own instance of this class.
46 */
47 var QuickEnrolment = function(options) {
48 this.contextid = options.contextid;
49
50 this.initModal();
51 };
52 // Class variables and functions.
53
54 /** @var {number} courseid - */
55 QuickEnrolment.prototype.courseid = 0;
56
57 /** @var {Modal} modal */
58 QuickEnrolment.prototype.modal = null;
59
60 /**
61 * Private method
62 *
63 * @method initModal
64 * @private
65 */
66 QuickEnrolment.prototype.initModal = function() {
9b0f2923 67 var triggerButtons = $(SELECTORS.TRIGGERBUTTONS);
a60e8ba5 68
e759c9ed
AN
69 $.when(
70 Str.get_strings([
71 {key: 'enroluserscohorts', component: 'enrol_manual'},
72 {key: 'enrolusers', component: 'enrol_manual'},
73 ]),
74 ModalFactory.create({
75 type: ModalFactory.types.SAVE_CANCEL,
76 large: true,
77 }, triggerButtons)
78 )
79 .then(function(strings, modal) {
b05f2cd7
AN
80 this.modal = modal;
81
e759c9ed
AN
82 modal.setTitle(strings[1]);
83 modal.setSaveButtonText(strings[1]);
84
85 modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));
86 modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));
9b0f2923 87
e759c9ed
AN
88 // We want the reset the form every time it is opened.
89 modal.getRoot().on(ModalEvents.hidden, function() {
90 modal.setBody('');
9b0f2923
MN
91 });
92
e759c9ed
AN
93 modal.getRoot().on(ModalEvents.shown, function() {
94 var bodyPromise = this.getBody();
95 bodyPromise.then(function(html) {
96 var stringIndex = $(html).find(SELECTORS.COHORTSELECT).length ? 0 : 1;
97 modal.setSaveButtonText(strings[stringIndex]);
b05f2cd7 98
e759c9ed
AN
99 return;
100 })
101 .fail(Notification.exception);
b05f2cd7 102
e759c9ed
AN
103 modal.setBody(bodyPromise);
104 }.bind(this));
b05f2cd7 105
e759c9ed 106 return;
b05f2cd7
AN
107 }.bind(this))
108 .fail(Notification.exception);
a60e8ba5
DW
109 };
110
111 /**
112 * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.
113 *
114 * @method submitForm
2e1615f2 115 * @param {Event} e Form submission event.
a60e8ba5
DW
116 * @private
117 */
118 QuickEnrolment.prototype.submitForm = function(e) {
119 e.preventDefault();
120 this.modal.getRoot().find('form').submit();
121 };
122
123 /**
124 * Private method
125 *
126 * @method submitForm
127 * @private
2e1615f2 128 * @param {Event} e Form submission event.
a60e8ba5
DW
129 */
130 QuickEnrolment.prototype.submitFormAjax = function(e) {
131 // We don't want to do a real form submission.
132 e.preventDefault();
133
7a963e92
SL
134 var form = this.modal.getRoot().find('form');
135
136 // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.
137 // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.
9b0f2923 138 var hidden = form.find(SELECTORS.UNWANTEDHIDDENFIELDS);
e759c9ed 139 hidden.each(function() {
7a963e92
SL
140 this.remove();
141 });
142
143 var formData = form.serialize();
a60e8ba5
DW
144
145 this.modal.hide();
146
147 var settings = {
148 type: 'GET',
149 processData: false,
150 contentType: "application/json"
151 };
152
153 var script = Config.wwwroot + '/enrol/manual/ajax.php?' + formData;
154 $.ajax(script, settings)
155 .then(function(response) {
156
157 if (response.error) {
158 Notification.addNotification({
159 message: response.error,
160 type: "error"
161 });
162 } else {
163 // Reload the page, don't show changed data warnings.
164 if (typeof window.M.core_formchangechecker !== "undefined") {
165 window.M.core_formchangechecker.reset_form_dirty_state();
166 }
167 window.location.reload();
168 }
2e1615f2 169 return;
a60e8ba5
DW
170 })
171 .fail(Notification.exception);
172 };
173
174 /**
175 * Private method
176 *
177 * @method getBody
178 * @private
2e1615f2 179 * @return {Promise}
a60e8ba5
DW
180 */
181 QuickEnrolment.prototype.getBody = function() {
182 return Fragment.loadFragment('enrol_manual', 'enrol_users_form', this.contextid, {}).fail(Notification.exception);
183 };
184
185 /**
186 * Private method
187 *
188 * @method getFooter
189 * @private
2e1615f2 190 * @return {Promise}
a60e8ba5
DW
191 */
192 QuickEnrolment.prototype.getFooter = function() {
193 return Template.render('enrol_manual/enrol_modal_footer', {});
194 };
195
196 return /** @alias module:enrol_manual/quickenrolment */ {
197 // Public variables and functions.
198 /**
199 * Every call to init creates a new instance of the class with it's own event listeners etc.
200 *
201 * @method init
202 * @public
203 * @param {object} config - config variables for the module.
204 */
205 init: function(config) {
206 (new QuickEnrolment(config));
207 }
208 };
209});