@ministryofjustice/frontend 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/moj/all.jquery.min.js +7 -70
  2. package/moj/all.js +2856 -2865
  3. package/moj/components/add-another/add-another.js +135 -104
  4. package/moj/components/alert/alert.js +482 -247
  5. package/moj/components/alert/alert.spec.helper.js +30 -5
  6. package/moj/components/button-menu/button-menu.js +346 -319
  7. package/moj/components/date-picker/date-picker.js +925 -900
  8. package/moj/components/filter-toggle-button/filter-toggle-button.js +122 -91
  9. package/moj/components/form-validator/form-validator.js +399 -164
  10. package/moj/components/multi-file-upload/multi-file-upload.js +445 -210
  11. package/moj/components/multi-select/multi-select.js +106 -75
  12. package/moj/components/password-reveal/password-reveal.js +64 -33
  13. package/moj/components/rich-text-editor/rich-text-editor.js +186 -153
  14. package/moj/components/search-toggle/search-toggle.js +77 -46
  15. package/moj/components/sortable-table/sortable-table.js +167 -146
  16. package/moj/helpers/_links.scss +1 -1
  17. package/moj/helpers.js +218 -180
  18. package/moj/moj-frontend.min.js +7 -70
  19. package/moj/version.js +28 -1
  20. package/package.json +1 -1
  21. package/moj/all.spec.js +0 -24
  22. package/moj/components/add-another/add-another.spec.js +0 -165
  23. package/moj/components/alert/alert.spec.js +0 -229
  24. package/moj/components/button-menu/button-menu.spec.js +0 -360
  25. package/moj/components/date-picker/date-picker.spec.js +0 -1178
  26. package/moj/components/filter-toggle-button/filter-toggle-button.spec.js +0 -302
  27. package/moj/components/multi-file-upload/multi-file-upload.spec.js +0 -510
  28. package/moj/components/multi-select/multi-select.spec.js +0 -128
  29. package/moj/components/password-reveal/password-reveal.spec.js +0 -57
  30. package/moj/components/search-toggle/search-toggle.spec.js +0 -129
  31. package/moj/components/sortable-table/sortable-table.spec.js +0 -362
  32. package/moj/helpers.spec.js +0 -235
  33. package/moj/namespace.js +0 -2
@@ -1,219 +1,454 @@
1
- if (
2
- MOJFrontend.dragAndDropSupported() &&
3
- MOJFrontend.formDataSupported() &&
4
- MOJFrontend.fileApiSupported()
5
- ) {
6
- MOJFrontend.MultiFileUpload = function (params) {
7
- this.defaultParams = {
8
- uploadFileEntryHook: $.noop,
9
- uploadFileExitHook: $.noop,
10
- uploadFileErrorHook: $.noop,
11
- fileDeleteHook: $.noop,
12
- uploadStatusText: 'Uploading files, please wait',
13
- dropzoneHintText: 'Drag and drop files here or',
14
- dropzoneButtonText: 'Choose files'
15
- }
16
-
17
- this.params = $.extend({}, this.defaultParams, params)
18
- this.container = $(this.params.container)
19
-
20
- this.container.addClass('moj-multi-file-upload--enhanced')
21
-
22
- this.feedbackContainer = this.container.find(
23
- '.moj-multi-file__uploaded-files'
24
- )
25
- this.setupFileInput()
26
- this.setupDropzone()
27
- this.setupLabel()
28
- this.setupStatusBox()
29
- this.container.on(
30
- 'click',
31
- '.moj-multi-file-upload__delete',
32
- $.proxy(this, 'onFileDeleteClick')
33
- )
34
- }
35
-
36
- MOJFrontend.MultiFileUpload.prototype.setupDropzone = function () {
37
- this.fileInput.wrap('<div class="moj-multi-file-upload__dropzone" />')
38
- this.dropzone = this.container.find('.moj-multi-file-upload__dropzone')
39
- this.dropzone.on('dragover', $.proxy(this, 'onDragOver'))
40
- this.dropzone.on('dragleave', $.proxy(this, 'onDragLeave'))
41
- this.dropzone.on('drop', $.proxy(this, 'onDrop'))
42
- }
43
-
44
- MOJFrontend.MultiFileUpload.prototype.setupLabel = function () {
45
- this.label = $(
46
- `<label for="${this.fileInput[0].id}" class="govuk-button govuk-button--secondary">${this.params.dropzoneButtonText}</label>`
47
- )
48
- this.dropzone.append(
49
- `<p class="govuk-body">${this.params.dropzoneHintText}</p>`
50
- )
51
- this.dropzone.append(this.label)
52
- }
53
-
54
- MOJFrontend.MultiFileUpload.prototype.setupFileInput = function () {
55
- this.fileInput = this.container.find('.moj-multi-file-upload__input')
56
- this.fileInput.on('change', $.proxy(this, 'onFileChange'))
57
- this.fileInput.on('focus', $.proxy(this, 'onFileFocus'))
58
- this.fileInput.on('blur', $.proxy(this, 'onFileBlur'))
59
- }
60
-
61
- MOJFrontend.MultiFileUpload.prototype.setupStatusBox = function () {
62
- this.status = $(
63
- '<div aria-live="polite" role="status" class="govuk-visually-hidden" />'
64
- )
65
- this.dropzone.append(this.status)
66
- }
67
-
68
- MOJFrontend.MultiFileUpload.prototype.onDragOver = function (e) {
69
- e.preventDefault()
70
- this.dropzone.addClass('moj-multi-file-upload--dragover')
71
- }
72
-
73
- MOJFrontend.MultiFileUpload.prototype.onDragLeave = function () {
74
- this.dropzone.removeClass('moj-multi-file-upload--dragover')
75
- }
76
-
77
- MOJFrontend.MultiFileUpload.prototype.onDrop = function (e) {
78
- e.preventDefault()
79
- this.dropzone.removeClass('moj-multi-file-upload--dragover')
80
- this.feedbackContainer.removeClass('moj-hidden')
81
- this.status.html(this.params.uploadStatusText)
82
- this.uploadFiles(e.originalEvent.dataTransfer.files)
83
- }
84
-
85
- MOJFrontend.MultiFileUpload.prototype.uploadFiles = function (files) {
86
- for (let i = 0; i < files.length; i++) {
87
- this.uploadFile(files[i])
88
- }
89
- }
90
-
91
- MOJFrontend.MultiFileUpload.prototype.onFileChange = function (e) {
92
- this.feedbackContainer.removeClass('moj-hidden')
93
- this.status.html(this.params.uploadStatusText)
94
- this.uploadFiles(e.currentTarget.files)
95
- this.fileInput.replaceWith($(e.currentTarget).val('').clone(true))
96
- this.setupFileInput()
97
- this.fileInput.get(0).focus()
98
- }
99
-
100
- MOJFrontend.MultiFileUpload.prototype.onFileFocus = function (e) {
101
- this.label.addClass('moj-multi-file-upload--focused')
102
- }
103
-
104
- MOJFrontend.MultiFileUpload.prototype.onFileBlur = function (e) {
105
- this.label.removeClass('moj-multi-file-upload--focused')
106
- }
107
-
108
- MOJFrontend.MultiFileUpload.prototype.getSuccessHtml = function (success) {
109
- return `<span class="moj-multi-file-upload__success"> <svg class="moj-banner__icon" fill="currentColor" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" height="25" width="25"><path d="M25,6.2L8.7,23.2L0,14.1l4-4.2l4.7,4.9L21,2L25,6.2z"/></svg>${success.messageHtml}</span>`
110
- }
111
-
112
- MOJFrontend.MultiFileUpload.prototype.getErrorHtml = function (error) {
113
- return `<span class="moj-multi-file-upload__error"> <svg class="moj-banner__icon" fill="currentColor" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" height="25" width="25"><path d="M13.6,15.4h-2.3v-4.5h2.3V15.4z M13.6,19.8h-2.3v-2.2h2.3V19.8z M0,23.2h25L12.5,2L0,23.2z"/></svg>${error.message}</span>`
114
- }
115
-
116
- MOJFrontend.MultiFileUpload.prototype.getFileRowHtml = function (file) {
117
- const html = `
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define(factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MOJFrontend = factory());
5
+ })(this, (function () { 'use strict';
6
+
7
+ function getDefaultExportFromCjs (x) {
8
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
9
+ }
10
+
11
+ var _global_window_jQuery = window.jQuery;
12
+
13
+ var helpers;
14
+ var hasRequiredHelpers;
15
+
16
+ function requireHelpers () {
17
+ if (hasRequiredHelpers) return helpers;
18
+ hasRequiredHelpers = 1;
19
+ function removeAttributeValue(el, attr, value) {
20
+ let re, m;
21
+ if (el.getAttribute(attr)) {
22
+ if (el.getAttribute(attr) === value) {
23
+ el.removeAttribute(attr);
24
+ } else {
25
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
26
+ m = el.getAttribute(attr).match(re);
27
+ if (m && m.length === 3) {
28
+ el.setAttribute(
29
+ attr,
30
+ el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')
31
+ );
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ function addAttributeValue(el, attr, value) {
38
+ let re;
39
+ if (!el.getAttribute(attr)) {
40
+ el.setAttribute(attr, value);
41
+ } else {
42
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
43
+ if (!re.test(el.getAttribute(attr))) {
44
+ el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`);
45
+ }
46
+ }
47
+ }
48
+
49
+ function dragAndDropSupported() {
50
+ const div = document.createElement('div');
51
+ return typeof div.ondrop !== 'undefined'
52
+ }
53
+
54
+ function formDataSupported() {
55
+ return typeof FormData === 'function'
56
+ }
57
+
58
+ function fileApiSupported() {
59
+ const input = document.createElement('input');
60
+ input.type = 'file';
61
+ return typeof input.files !== 'undefined'
62
+ }
63
+
64
+ function nodeListForEach(nodes, callback) {
65
+ if (window.NodeList.prototype.forEach) {
66
+ return nodes.forEach(callback)
67
+ }
68
+ for (let i = 0; i < nodes.length; i++) {
69
+ callback.call(window, nodes[i], i, nodes);
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Find an elements next sibling
75
+ *
76
+ * Utility function to find an elements next sibling matching the provided
77
+ * selector.
78
+ *
79
+ * @param {HTMLElement} $element - Element to find siblings for
80
+ * @param {string} selector - selector for required sibling
81
+ */
82
+ function getNextSibling($element, selector) {
83
+ if (!$element) return
84
+ // Get the next sibling element
85
+ let $sibling = $element.nextElementSibling;
86
+
87
+ // If there's no selector, return the first sibling
88
+ if (!selector) return $sibling
89
+
90
+ // If the sibling matches our selector, use it
91
+ // If not, jump to the next sibling and continue the loop
92
+ while ($sibling) {
93
+ if ($sibling.matches(selector)) return $sibling
94
+ $sibling = $sibling.nextElementSibling;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Find an elements preceding sibling
100
+ *
101
+ * Utility function to find an elements previous sibling matching the provided
102
+ * selector.
103
+ *
104
+ * @param {HTMLElement} $element - Element to find siblings for
105
+ * @param {string} selector - selector for required sibling
106
+ */
107
+ function getPreviousSibling($element, selector) {
108
+ if (!$element) return
109
+ // Get the previous sibling element
110
+ let $sibling = $element.previousElementSibling;
111
+
112
+ // If there's no selector, return the first sibling
113
+ if (!selector) return $sibling
114
+
115
+ // If the sibling matches our selector, use it
116
+ // If not, jump to the next sibling and continue the loop
117
+ while ($sibling) {
118
+ if ($sibling.matches(selector)) return $sibling
119
+ $sibling = $sibling.previousElementSibling;
120
+ }
121
+ }
122
+
123
+ function findNearestMatchingElement($element, selector) {
124
+ // If no element or selector is provided, return null
125
+ if (!$element) return
126
+ if (!selector) return
127
+
128
+ // Start with the current element
129
+ let $currentElement = $element;
130
+
131
+ while ($currentElement) {
132
+ // First check the current element
133
+ if ($currentElement.matches(selector)) {
134
+ return $currentElement
135
+ }
136
+
137
+ // Check all previous siblings
138
+ let $sibling = $currentElement.previousElementSibling;
139
+ while ($sibling) {
140
+ // Check if the sibling itself is a heading
141
+ if ($sibling.matches(selector)) {
142
+ return $sibling
143
+ }
144
+ $sibling = $sibling.previousElementSibling;
145
+ }
146
+
147
+ // If no match found in siblings, move up to parent
148
+ $currentElement = $currentElement.parentElement;
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Move focus to element
154
+ *
155
+ * Sets tabindex to -1 to make the element programmatically focusable,
156
+ * but removes it on blur as the element doesn't need to be focused again.
157
+ *
158
+ * @param {HTMLElement} $element - HTML element
159
+ * @param {object} [options] - Handler options
160
+ * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus
161
+ * @param {function(this: HTMLElement): void} [options.onBlur] - Callback on blur
162
+ */
163
+ function setFocus($element, options = {}) {
164
+ const isFocusable = $element.getAttribute('tabindex');
165
+
166
+ if (!isFocusable) {
167
+ $element.setAttribute('tabindex', '-1');
168
+ }
169
+
170
+ /**
171
+ * Handle element focus
172
+ */
173
+ function onFocus() {
174
+ $element.addEventListener('blur', onBlur, { once: true });
175
+ }
176
+
177
+ /**
178
+ * Handle element blur
179
+ */
180
+ function onBlur() {
181
+ if (options.onBlur) {
182
+ options.onBlur.call($element);
183
+ }
184
+
185
+ if (!isFocusable) {
186
+ $element.removeAttribute('tabindex');
187
+ }
188
+ }
189
+
190
+ // Add listener to reset element on blur, after focus
191
+ $element.addEventListener('focus', onFocus, { once: true });
192
+
193
+ // Focus element
194
+ if (options.onBeforeFocus) {
195
+ options.onBeforeFocus.call($element);
196
+ }
197
+ $element.focus();
198
+ }
199
+
200
+ helpers = {
201
+ removeAttributeValue,
202
+ addAttributeValue,
203
+ dragAndDropSupported,
204
+ formDataSupported,
205
+ fileApiSupported,
206
+ nodeListForEach,
207
+ getNextSibling,
208
+ getPreviousSibling,
209
+ findNearestMatchingElement,
210
+ setFocus
211
+ };
212
+ return helpers;
213
+ }
214
+
215
+ var multiFileUpload$1;
216
+ var hasRequiredMultiFileUpload;
217
+
218
+ function requireMultiFileUpload () {
219
+ if (hasRequiredMultiFileUpload) return multiFileUpload$1;
220
+ hasRequiredMultiFileUpload = 1;
221
+ const $ = _global_window_jQuery;
222
+
223
+ const {
224
+ dragAndDropSupported,
225
+ fileApiSupported,
226
+ formDataSupported
227
+ } = requireHelpers();
228
+
229
+ function MultiFileUpload(params) {
230
+ if (!(dragAndDropSupported() && formDataSupported() && fileApiSupported())) {
231
+ return
232
+ }
233
+
234
+ this.defaultParams = {
235
+ uploadFileEntryHook: $.noop,
236
+ uploadFileExitHook: $.noop,
237
+ uploadFileErrorHook: $.noop,
238
+ fileDeleteHook: $.noop,
239
+ uploadStatusText: 'Uploading files, please wait',
240
+ dropzoneHintText: 'Drag and drop files here or',
241
+ dropzoneButtonText: 'Choose files'
242
+ };
243
+
244
+ this.params = $.extend({}, this.defaultParams, params);
245
+ this.container = $(this.params.container);
246
+
247
+ this.container.addClass('moj-multi-file-upload--enhanced');
248
+
249
+ this.feedbackContainer = this.container.find(
250
+ '.moj-multi-file__uploaded-files'
251
+ );
252
+ this.setupFileInput();
253
+ this.setupDropzone();
254
+ this.setupLabel();
255
+ this.setupStatusBox();
256
+ this.container.on(
257
+ 'click',
258
+ '.moj-multi-file-upload__delete',
259
+ $.proxy(this, 'onFileDeleteClick')
260
+ );
261
+ }
262
+
263
+ MultiFileUpload.prototype.setupDropzone = function () {
264
+ this.fileInput.wrap('<div class="moj-multi-file-upload__dropzone" />');
265
+ this.dropzone = this.container.find('.moj-multi-file-upload__dropzone');
266
+ this.dropzone.on('dragover', $.proxy(this, 'onDragOver'));
267
+ this.dropzone.on('dragleave', $.proxy(this, 'onDragLeave'));
268
+ this.dropzone.on('drop', $.proxy(this, 'onDrop'));
269
+ };
270
+
271
+ MultiFileUpload.prototype.setupLabel = function () {
272
+ this.label = $(
273
+ `<label for="${this.fileInput[0].id}" class="govuk-button govuk-button--secondary">${this.params.dropzoneButtonText}</label>`
274
+ );
275
+ this.dropzone.append(
276
+ `<p class="govuk-body">${this.params.dropzoneHintText}</p>`
277
+ );
278
+ this.dropzone.append(this.label);
279
+ };
280
+
281
+ MultiFileUpload.prototype.setupFileInput = function () {
282
+ this.fileInput = this.container.find('.moj-multi-file-upload__input');
283
+ this.fileInput.on('change', $.proxy(this, 'onFileChange'));
284
+ this.fileInput.on('focus', $.proxy(this, 'onFileFocus'));
285
+ this.fileInput.on('blur', $.proxy(this, 'onFileBlur'));
286
+ };
287
+
288
+ MultiFileUpload.prototype.setupStatusBox = function () {
289
+ this.status = $(
290
+ '<div aria-live="polite" role="status" class="govuk-visually-hidden" />'
291
+ );
292
+ this.dropzone.append(this.status);
293
+ };
294
+
295
+ MultiFileUpload.prototype.onDragOver = function (e) {
296
+ e.preventDefault();
297
+ this.dropzone.addClass('moj-multi-file-upload--dragover');
298
+ };
299
+
300
+ MultiFileUpload.prototype.onDragLeave = function () {
301
+ this.dropzone.removeClass('moj-multi-file-upload--dragover');
302
+ };
303
+
304
+ MultiFileUpload.prototype.onDrop = function (e) {
305
+ e.preventDefault();
306
+ this.dropzone.removeClass('moj-multi-file-upload--dragover');
307
+ this.feedbackContainer.removeClass('moj-hidden');
308
+ this.status.html(this.params.uploadStatusText);
309
+ this.uploadFiles(e.originalEvent.dataTransfer.files);
310
+ };
311
+
312
+ MultiFileUpload.prototype.uploadFiles = function (files) {
313
+ for (let i = 0; i < files.length; i++) {
314
+ this.uploadFile(files[i]);
315
+ }
316
+ };
317
+
318
+ MultiFileUpload.prototype.onFileChange = function (e) {
319
+ this.feedbackContainer.removeClass('moj-hidden');
320
+ this.status.html(this.params.uploadStatusText);
321
+ this.uploadFiles(e.currentTarget.files);
322
+ this.fileInput.replaceWith($(e.currentTarget).val('').clone(true));
323
+ this.setupFileInput();
324
+ this.fileInput.get(0).focus();
325
+ };
326
+
327
+ MultiFileUpload.prototype.onFileFocus = function (e) {
328
+ this.label.addClass('moj-multi-file-upload--focused');
329
+ };
330
+
331
+ MultiFileUpload.prototype.onFileBlur = function (e) {
332
+ this.label.removeClass('moj-multi-file-upload--focused');
333
+ };
334
+
335
+ MultiFileUpload.prototype.getSuccessHtml = function (success) {
336
+ return `<span class="moj-multi-file-upload__success"> <svg class="moj-banner__icon" fill="currentColor" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" height="25" width="25"><path d="M25,6.2L8.7,23.2L0,14.1l4-4.2l4.7,4.9L21,2L25,6.2z"/></svg>${success.messageHtml}</span>`
337
+ };
338
+
339
+ MultiFileUpload.prototype.getErrorHtml = function (error) {
340
+ return `<span class="moj-multi-file-upload__error"> <svg class="moj-banner__icon" fill="currentColor" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" height="25" width="25"><path d="M13.6,15.4h-2.3v-4.5h2.3V15.4z M13.6,19.8h-2.3v-2.2h2.3V19.8z M0,23.2h25L12.5,2L0,23.2z"/></svg>${error.message}</span>`
341
+ };
342
+
343
+ MultiFileUpload.prototype.getFileRowHtml = function (file) {
344
+ const html = `
118
345
  <div class="govuk-summary-list__row moj-multi-file-upload__row">;
119
346
  <div class="govuk-summary-list__value moj-multi-file-upload__message">;
120
347
  <span class="moj-multi-file-upload__filename">${file.name}</span>;
121
348
  <span class="moj-multi-file-upload__progress">0%</span>;
122
349
  </div>';
123
350
  <div class="govuk-summary-list__actions moj-multi-file-upload__actions"></div>;
124
- </div>`
125
- return html
126
- }
351
+ </div>`;
352
+ return html
353
+ };
127
354
 
128
- MOJFrontend.MultiFileUpload.prototype.getDeleteButtonHtml = function (file) {
129
- return `<button class="moj-multi-file-upload__delete govuk-button govuk-button--secondary govuk-!-margin-bottom-0" type="button" name="delete" value="${file.filename}">
355
+ MultiFileUpload.prototype.getDeleteButtonHtml = function (file) {
356
+ return `<button class="moj-multi-file-upload__delete govuk-button govuk-button--secondary govuk-!-margin-bottom-0" type="button" name="delete" value="${file.filename}">
130
357
  Delete <span class="govuk-visually-hidden">${file.originalname}</span>
131
358
  </button>`
132
- }
133
-
134
- MOJFrontend.MultiFileUpload.prototype.uploadFile = function (file) {
135
- this.params.uploadFileEntryHook(this, file)
136
- const item = $(this.getFileRowHtml(file))
137
- const formData = new FormData()
138
- formData.append('documents', file)
139
- this.feedbackContainer.find('.moj-multi-file-upload__list').append(item)
140
-
141
- $.ajax({
142
- url: this.params.uploadUrl,
143
- type: 'post',
144
- data: formData,
145
- processData: false,
146
- contentType: false,
147
- success: $.proxy(function (response) {
148
- if (response.error) {
149
- item
150
- .find('.moj-multi-file-upload__message')
151
- .html(this.getErrorHtml(response.error))
152
- this.status.html(response.error.message)
153
- } else {
154
- item
155
- .find('.moj-multi-file-upload__message')
156
- .html(this.getSuccessHtml(response.success))
157
- this.status.html(response.success.messageText)
158
- }
159
- item
160
- .find('.moj-multi-file-upload__actions')
161
- .append(this.getDeleteButtonHtml(response.file))
162
- this.params.uploadFileExitHook(this, file, response)
163
- }, this),
164
- error: $.proxy(function (jqXHR, textStatus, errorThrown) {
165
- this.params.uploadFileErrorHook(
166
- this,
167
- file,
168
- jqXHR,
169
- textStatus,
170
- errorThrown
171
- )
172
- }, this),
173
- xhr: function () {
174
- const xhr = new XMLHttpRequest()
175
- xhr.upload.addEventListener(
176
- 'progress',
177
- function (e) {
178
- if (e.lengthComputable) {
179
- let percentComplete = e.loaded / e.total
180
- percentComplete = parseInt(percentComplete * 100, 10)
181
- item
182
- .find('.moj-multi-file-upload__progress')
183
- .text(` ${percentComplete}%`)
184
- }
185
- },
186
- false
187
- )
188
- return xhr
189
- }
190
- })
191
- }
192
-
193
- MOJFrontend.MultiFileUpload.prototype.onFileDeleteClick = function (e) {
194
- e.preventDefault() // if user refreshes page and then deletes
195
- const button = $(e.currentTarget)
196
- const data = {}
197
- data[button[0].name] = button[0].value
198
- $.ajax({
199
- url: this.params.deleteUrl,
200
- type: 'post',
201
- dataType: 'json',
202
- data,
203
- success: $.proxy(function (response) {
204
- if (response.error) {
205
- // handle error
206
- } else {
207
- button.parents('.moj-multi-file-upload__row').remove()
208
- if (
209
- this.feedbackContainer.find('.moj-multi-file-upload__row')
210
- .length === 0
211
- ) {
212
- this.feedbackContainer.addClass('moj-hidden')
213
- }
214
- }
215
- this.params.fileDeleteHook(this, response)
216
- }, this)
217
- })
218
- }
219
- }
359
+ };
360
+
361
+ MultiFileUpload.prototype.uploadFile = function (file) {
362
+ this.params.uploadFileEntryHook(this, file);
363
+ const item = $(this.getFileRowHtml(file));
364
+ const formData = new FormData();
365
+ formData.append('documents', file);
366
+ this.feedbackContainer.find('.moj-multi-file-upload__list').append(item);
367
+
368
+ $.ajax({
369
+ url: this.params.uploadUrl,
370
+ type: 'post',
371
+ data: formData,
372
+ processData: false,
373
+ contentType: false,
374
+ success: $.proxy(function (response) {
375
+ if (response.error) {
376
+ item
377
+ .find('.moj-multi-file-upload__message')
378
+ .html(this.getErrorHtml(response.error));
379
+ this.status.html(response.error.message);
380
+ } else {
381
+ item
382
+ .find('.moj-multi-file-upload__message')
383
+ .html(this.getSuccessHtml(response.success));
384
+ this.status.html(response.success.messageText);
385
+ }
386
+ item
387
+ .find('.moj-multi-file-upload__actions')
388
+ .append(this.getDeleteButtonHtml(response.file));
389
+ this.params.uploadFileExitHook(this, file, response);
390
+ }, this),
391
+ error: $.proxy(function (jqXHR, textStatus, errorThrown) {
392
+ this.params.uploadFileErrorHook(
393
+ this,
394
+ file,
395
+ jqXHR,
396
+ textStatus,
397
+ errorThrown
398
+ );
399
+ }, this),
400
+ xhr: function () {
401
+ const xhr = new XMLHttpRequest();
402
+ xhr.upload.addEventListener(
403
+ 'progress',
404
+ function (e) {
405
+ if (e.lengthComputable) {
406
+ let percentComplete = e.loaded / e.total;
407
+ percentComplete = parseInt(percentComplete * 100, 10);
408
+ item
409
+ .find('.moj-multi-file-upload__progress')
410
+ .text(` ${percentComplete}%`);
411
+ }
412
+ },
413
+ false
414
+ );
415
+ return xhr
416
+ }
417
+ });
418
+ };
419
+
420
+ MultiFileUpload.prototype.onFileDeleteClick = function (e) {
421
+ e.preventDefault(); // if user refreshes page and then deletes
422
+ const button = $(e.currentTarget);
423
+ const data = {};
424
+ data[button[0].name] = button[0].value;
425
+ $.ajax({
426
+ url: this.params.deleteUrl,
427
+ type: 'post',
428
+ dataType: 'json',
429
+ data,
430
+ success: $.proxy(function (response) {
431
+ if (response.error) ; else {
432
+ button.parents('.moj-multi-file-upload__row').remove();
433
+ if (
434
+ this.feedbackContainer.find('.moj-multi-file-upload__row').length ===
435
+ 0
436
+ ) {
437
+ this.feedbackContainer.addClass('moj-hidden');
438
+ }
439
+ }
440
+ this.params.fileDeleteHook(this, response);
441
+ }, this)
442
+ });
443
+ };
444
+
445
+ multiFileUpload$1 = { MultiFileUpload };
446
+ return multiFileUpload$1;
447
+ }
448
+
449
+ var multiFileUploadExports = requireMultiFileUpload();
450
+ var multiFileUpload = /*@__PURE__*/getDefaultExportFromCjs(multiFileUploadExports);
451
+
452
+ return multiFileUpload;
453
+
454
+ }));