MDL-68464 enrol_manual: Reload participants table after enroling
[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 */
e0e7b19f 23import * as DynamicTable from 'core_table/dynamic';
c50f5af2 24import * as Str from 'core/str';
e0e7b19f
AN
25import * as Toast from 'core/toast';
26import Config from 'core/config';
c50f5af2
AN
27import Fragment from 'core/fragment';
28import ModalEvents from 'core/modal_events';
29import ModalFactory from 'core/modal_factory';
30import Notification from 'core/notification';
e0e7b19f
AN
31import jQuery from 'jquery';
32import Prefetch from 'core/prefetch';
c50f5af2
AN
33
34const Selectors = {
35 cohortSelector: "#id_cohortlist",
36 triggerButtons: ".enrolusersbutton.enrol_manual_plugin [type='submit']",
e0e7b19f
AN
37 unwantedHiddenFields: "input[value='_qf__force_multiselect_submission']",
38 buttonWrapper: '[data-region="wrapper"]',
39};
40
41/**
42 * Get the content of the body for the specified context.
43 *
44 * @param {Number} contextId
45 * @returns {Promise}
46 */
47const getBodyForContext = contextId => {
48 return Fragment.loadFragment('enrol_manual', 'enrol_users_form', contextId, {});
c50f5af2
AN
49};
50
e0e7b19f
AN
51/**
52 * Get the dynamic table for the button.
53 *
54 * @param {HTMLElement} element
55 * @returns {HTMLElement}
56 */
57const getDynamicTableForElement = element => {
58 const wrapper = element.closest(Selectors.buttonWrapper);
59
60 return DynamicTable.getTableFromId(wrapper.dataset.tableUniqueid);
61};
62
63/**
64 * Register the event listeners for this contextid.
65 *
66 * @param {Number} contextId
67 */
68const registerEventListeners = contextId => {
69 document.addEventListener('click', e => {
70 if (e.target.closest(Selectors.triggerButtons)) {
71 e.preventDefault();
72
73 showModal(getDynamicTableForElement(e.target), contextId);
b05f2cd7 74
e759c9ed 75 return;
e0e7b19f
AN
76 }
77 });
78};
79
80/**
81 * Display the modal for this contextId.
82 *
83 * @param {HTMLElement} dynamicTable The table to beb refreshed when changes are made
84 * @param {Number} contextId
85 * @returns {Promise}
86 */
87const showModal = (dynamicTable, contextId) => {
88 return ModalFactory.create({
89 type: ModalFactory.types.SAVE_CANCEL,
90 large: true,
91 title: Str.get_string('enrolusers', 'enrol_manual'),
92 body: getBodyForContext(contextId),
93 })
94 .then(modal => {
95 modal.getRoot().on(ModalEvents.save, e => {
96 // Trigger a form submission, so that any mform elements can do final tricks before the form submission
97 // is processed.
98 // The actual submit even tis captured in the next handler.
99
100 e.preventDefault();
101 modal.getRoot().find('form').submit();
102 });
103
104 modal.getRoot().on('submit', 'form', e => {
105 e.preventDefault();
106
107 submitFormAjax(dynamicTable, modal);
108 });
109
110 modal.getRoot().on(ModalEvents.hidden, () => {
111 modal.destroy();
7a963e92
SL
112 });
113
e0e7b19f
AN
114 return modal;
115 })
116 .then(modal => {
117 modal.show();
118
119 return modal;
120 })
121 .then(modal => {
122 modal.setSaveButtonText(Str.get_string('enrolusers', 'enrol_manual'));
123
124 modal.getBodyPromise().then(body => {
125 if (body.get(0).querySelector(Selectors.cohortSelector)) {
126 modal.setSaveButtonText(Str.get_string('enroluserscohorts', 'enrol_manual'));
127 }
128
129 return body;
130 })
131 .catch();
132
133 return modal;
134 })
135 .catch(Notification.exception);
136};
137
138/**
139 * Submit the form via ajax.
140 *
141 * @param {HTMLElement} dynamicTable
142 * @param {Object} modal
143 */
144const submitFormAjax = (dynamicTable, modal) => {
145 // Note: We use a jQuery object here so that we can use its serialize functionality.
146 const form = modal.getRoot().find('form');
147
148 // Before send the data through AJAX, we need to parse and remove some unwanted hidden fields.
149 // This hidden fields are added automatically by mforms and when it reaches the AJAX we get an error.
150 form.get(0).querySelectorAll(Selectors.unwantedHiddenFields).forEach(hiddenField => hiddenField.remove());
a60e8ba5 151
e0e7b19f
AN
152 modal.hide();
153 modal.destroy();
a60e8ba5 154
e0e7b19f
AN
155 jQuery.ajax(
156 `${Config.wwwroot}/enrol/manual/ajax.php?${form.serialize()}`,
157 {
a60e8ba5
DW
158 type: 'GET',
159 processData: false,
e0e7b19f
AN
160 contentType: "application/json",
161 }
162 )
163 .then(response => {
164 if (response.error) {
165 throw new Error(response.error);
166 }
167
168 DynamicTable.refreshTableContent(dynamicTable);
169 return Str.get_string('totalenrolledusers', 'enrol', response.count);
170 })
171 .then(notificationBody => Toast.add(notificationBody))
172 .catch(error => {
173 Notification.addNotification({
174 message: error.message,
175 type: 'error',
176 });
177 });
c50f5af2
AN
178};
179
e0e7b19f
AN
180/**
181 * Set up quick enrolment for the manual enrolment plugin.
182 *
183 * @param {Number} contextid The context id to setup for
184 */
c50f5af2 185export const init = ({contextid}) => {
e0e7b19f
AN
186 registerEventListeners(contextid);
187
188 Prefetch.prefetchStrings('enrol_manual', [
189 'enrolusers',
190 'enroluserscohorts',
191 ]);
192
193 Prefetch.prefetchString('enrol', 'totalenrolledusers');
c50f5af2 194};