Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Javascript events for the `core_form` subsystem.
18
 *
19
 * @module core_form/events
20
 * @copyright 2021 Huong Nguyen <huongnv13@gmail.com>
21
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 * @since 3.10
23
 *
24
 * @example <caption>Example of listening to a form event.</caption>
25
 * import {eventTypes as formEventTypes} from 'core_form/events';
26
 *
27
 * document.addEventListener(formEventTypes.formSubmittedByJavascript, e => {
28
 *     window.console.log(e.target); // The form that was submitted.
29
 *     window.console.log(e.detail.skipValidation); // Whether form validation was skipped.
30
 * });
31
 */
32
 
33
import {getString} from 'core/str';
34
import {dispatchEvent} from 'core/event_dispatcher';
35
 
36
let changesMadeString;
37
 
38
/**
39
 * Prevent user navigate away when upload progress still running.
40
 * @param {Event} e The event
41
 */
42
const changesMadeCheck = e => {
43
    if (e) {
44
        e.returnValue = changesMadeString;
45
    }
46
};
47
 
48
/**
49
 * Events for `core_form`.
50
 *
51
 * @constant
52
 * @property {String} formError See {@link event:core_form/error}
53
 * @property {String} formFieldValidationFailed See {@link event:core_form/fieldValidationFailed}
54
 * @property {String} formSubmittedByJavascript See {@link event:core_form/submittedByJavascript}
55
 * @property {String} uploadChanged See {@link event:core_form/uploadChanged}
56
 * @property {String} fieldStructureChanged See {@link event:core_form/fieldStructureChanged}
57
 */
58
export const eventTypes = {
59
    /**
60
     * An event triggered when a form contains an error
61
     *
62
     * @event formError
63
     * @type {CustomEvent}
64
     * @property {HTMLElement} target The form field which errored
65
     */
66
    formError: 'core_form/error',
67
 
68
    /**
69
     * An event triggered when an mform is about to be submitted via javascript.
70
     *
71
     * @event core_form/submittedByJavascript
72
     * @type {CustomEvent}
73
     * @property {HTMLElement} target The form that was submitted
74
     * @property {object} detail
75
     * @property {boolean} detail.skipValidation Whether the form was submitted without validation (i.e. via a Cancel button)
76
     * @property {boolean} detail.fallbackHandled Whether the legacy YUI event has been handled
77
     */
78
    formSubmittedByJavascript: 'core_form/submittedByJavascript',
79
 
80
    /**
81
     * An event triggered upon form field validation failure.
82
     *
83
     * @event core_form/fieldValidationFailed
84
     * @type {CustomEvent}
85
     * @property {HTMLElement} target The field that failed validation
86
     * @property {object} detail
87
     * @property {String} detail.message The message displayed upon failure
88
     */
89
    formFieldValidationFailed: 'core_form/fieldValidationFailed',
90
 
91
    /**
92
     * An event triggered when an upload is started
93
     *
94
     * @event core_form/uploadStarted
95
     * @type {CustomEvent}
96
     * @property {HTMLElement} target The location where the upload began
97
     */
98
    uploadStarted: 'core_form/uploadStarted',
99
 
100
    /**
101
     * An event triggered when an upload completes
102
     *
103
     * @event core_form/uploadCompleted
104
     * @type {CustomEvent}
105
     * @property {HTMLElement} target The location where the upload completed
106
     */
107
    uploadCompleted: 'core_form/uploadCompleted',
108
 
109
    /**
110
     * An event triggered when a file upload field has been changed.
111
     *
112
     * @event core_form/uploadChanged
113
     * @type {CustomEvent}
114
     * @property {HTMLElement} target The form field which was changed
115
     */
116
    uploadChanged: 'core_form/uploadChanged',
117
 
118
    /**
119
     * An event triggered when a form field structure has changed.
120
     *
121
     * @event core_form/fieldStructureChanged
122
     * @type {CustomEvent}
123
     * @property {HTMLElement} target The form field that has changed
124
     */
125
    fieldStructureChanged: 'core_form/fieldStructureChanged',
126
};
127
 
128
/**
129
 * Trigger an event to indicate that a form field contained an error.
130
 *
131
 * @method notifyFormError
132
 * @param {HTMLElement} field The form field causing the error
133
 * @returns {CustomEvent}
134
 * @fires formError
135
 */
136
export const notifyFormError = field => dispatchEvent(eventTypes.formError, {}, field);
137
 
138
/**
139
 * Trigger an event to indiciate that a form was submitted by Javascript.
140
 *
141
 * @method
142
 * @param {HTMLElement} form The form that was submitted
143
 * @param {Boolean} skipValidation Submit the form without validation. E.g. "Cancel".
144
 * @param {Boolean} fallbackHandled The legacy YUI event has been handled
145
 * @returns {CustomEvent}
146
 * @fires formSubmittedByJavascript
147
 */
148
export const notifyFormSubmittedByJavascript = (form, skipValidation = false, fallbackHandled = false) => {
149
    if (skipValidation) {
150
        window.skipClientValidation = true;
151
    }
152
 
153
    const customEvent = dispatchEvent(
154
        eventTypes.formSubmittedByJavascript,
155
        {
156
            skipValidation,
157
            fallbackHandled,
158
        },
159
        form
160
    );
161
 
162
    if (skipValidation) {
163
        window.skipClientValidation = false;
164
    }
165
 
166
    return customEvent;
167
};
168
 
169
/**
170
 * Trigger an event to indicate that a form field contained an error.
171
 *
172
 * @method notifyFieldValidationFailure
173
 * @param {HTMLElement} field The field which failed validation
174
 * @param {String} message The message displayed
175
 * @returns {CustomEvent}
176
 * @fires formFieldValidationFailed
177
 */
178
export const notifyFieldValidationFailure = (field, message) => dispatchEvent(
179
    eventTypes.formFieldValidationFailed,
180
    {
181
        message,
182
    },
183
    field,
184
    {
185
        cancelable: true
186
    }
187
);
188
 
189
/**
190
 * Trigger an event to indicate that an upload was started.
191
 *
192
 * @method
193
 * @param {String} elementId The element which was uploaded to
194
 * @returns {CustomEvent}
195
 * @fires uploadStarted
196
 */
197
export const notifyUploadStarted = async elementId => {
198
    // Add an additional check for changes made.
199
    changesMadeString = await getString('changesmadereallygoaway', 'moodle');
200
    window.addEventListener('beforeunload', changesMadeCheck);
201
 
202
    return dispatchEvent(
203
        eventTypes.uploadStarted,
204
        {},
205
        document.getElementById(elementId),
206
        {
207
            bubbles: true,
208
            cancellable: false,
209
        }
210
    );
211
};
212
 
213
/**
214
 * Trigger an event to indicate that an upload was completed.
215
 *
216
 * @method
217
 * @param {String} elementId The element which was uploaded to
218
 * @returns {CustomEvent}
219
 * @fires uploadCompleted
220
 */
221
export const notifyUploadCompleted = elementId => {
222
    // Remove the additional check for changes made.
223
    window.removeEventListener('beforeunload', changesMadeCheck);
224
 
225
    return dispatchEvent(
226
        eventTypes.uploadCompleted,
227
        {},
228
        document.getElementById(elementId),
229
        {
230
            bubbles: true,
231
            cancellable: false,
232
        }
233
    );
234
};
235
 
236
/**
237
 * Trigger upload start event.
238
 *
239
 * @method
240
 * @param {String} elementId
241
 * @returns {CustomEvent}
242
 * @fires uploadStarted
243
 * @deprecated Since Moodle 4.0 See {@link module:core_form/events.notifyUploadStarted notifyUploadStarted}
244
 */
245
export const triggerUploadStarted = notifyUploadStarted;
246
 
247
/**
248
 * Trigger upload complete event.
249
 *
250
 * @method
251
 * @param {String} elementId
252
 * @returns {CustomEvent}
253
 * @fires uploadCompleted
254
 * @deprecated Since Moodle 4.0 See {@link module:core_form/events.notifyUploadCompleted notifyUploadCompleted}
255
 */
256
export const triggerUploadCompleted = notifyUploadCompleted;
257
 
258
/**
259
 * List of the events.
260
 *
261
 * @deprecated since Moodle 4.0. See {@link module:core_form/events.eventTypes eventTypes} instead.
262
 **/
263
export const types = {
264
    uploadStarted: 'core_form/uploadStarted',
265
    uploadCompleted: 'core_form/uploadCompleted',
266
};
267
 
268
/**
269
 * Trigger an event to notify the file upload field has been changed.
270
 *
271
 * @method
272
 * @param {string} elementId The element which was changed
273
 * @returns {CustomEvent}
274
 * @fires uploadChanged
275
 */
276
export const notifyUploadChanged = elementId => dispatchEvent(
277
    eventTypes.uploadChanged,
278
    {},
279
    document.getElementById(elementId),
280
    {
281
        bubbles: true,
282
        cancellable: false,
283
    }
284
);
285
 
286
/**
287
 * Trigger an event to notify the field structure has changed.
288
 *
289
 * @method
290
 * @param {string} elementId The element which was changed
291
 * @returns {CustomEvent}
292
 * @fires fieldStructureChanged
293
 */
294
export const notifyFieldStructureChanged = elementId => dispatchEvent(
295
    eventTypes.fieldStructureChanged,
296
    {},
297
    document.getElementById(elementId),
298
    {
299
        bubbles: true,
300
        cancellable: false,
301
    }
302
);