PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 2.1.8
JetFormBuilder — Dynamic Blocks Form Builder v2.1.8
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / assets / js / file-upload.js
jetformbuilder / assets / js Last commit date
admin 3 years ago action-localize-helper.js 3 years ago admin-package.js 3 years ago admin-vuex-package.js 3 years ago editor.js 3 years ago file-upload.js 3 years ago form-block.js 3 years ago frontend-forms.js 3 years ago import-form.js 3 years ago map-field.js 3 years ago package.js 3 years ago re-captcha-v3.js 3 years ago
file-upload.js
361 lines
1 (
2 function ( $ ) {
3
4 'use strict';
5
6 const createFileList = ( inputFileArray ) => {
7 const transfer = new DataTransfer();
8
9 for ( const file of inputFileArray ) {
10 transfer.items.add( file );
11 }
12
13 return transfer.files;
14 };
15
16 const convertFields = scope => {
17 scope.find( '.jet-form-builder-file-upload' ).each( function () {
18 const wrapper = $( this );
19 const input = wrapper.find(
20 '.jet-form-builder-file-upload__input' );
21
22 const files = wrapper.find(
23 '.jet-form-builder-file-upload__file' );
24 const urls = [];
25
26 for ( const preview of files ) {
27 const url = $( preview ).data( 'file' );
28 const removeNode = $( preview ).find(
29 '.jet-form-builder-file-upload__file-remove',
30 );
31
32 urls.push( [ url, removeNode.data( 'file-name' ) ] );
33 }
34
35 if ( !urls.length ) {
36 return;
37 }
38
39 Promise.allSettled( urls.map( ( [ url, fileName ] ) => (
40 new Promise( ( resolve, reject ) => {
41 fetch( url ).then(
42 response => response.blob(),
43 ).then(
44 blob => resolve(
45 new File( [ blob ], fileName, blob ),
46 ),
47 ).catch( reject );
48 } )
49 ) ) ).then( values => {
50 const files = values.map( ( { value } ) => value );
51
52 addFileToInput( input[ 0 ], files );
53 input.trigger( 'change.JetFormBuilderMain' );
54 } );
55 } );
56 };
57
58 const addFileToInput = ( input, newFiles ) => {
59 input.files = createFileList( [ ...newFiles ] );
60 input.jfbPrevFiles = createFileList( [ ...input.files ] );
61 };
62
63 var JetFormBuilderFileUpload = {
64
65 init: function ( event, scope ) {
66 $( '.jet-form-builder-file-upload__files', scope ).
67 sortable( {
68 items: '.jet-form-builder-file-upload__file',
69 forcePlaceholderSize: true,
70 } ).
71 bind( 'sortupdate',
72 JetFormBuilderFileUpload.onSortCallback );
73
74 convertFields( scope );
75 },
76
77 onSortCallback: function ( e, ui ) {
78 const transfer = new DataTransfer();
79 const field = $( e.target ).
80 closest( '.jet-form-builder-file-upload' );
81 const input = field.find(
82 '.jet-form-builder-file-upload__input' );
83 const { files } = input[ 0 ];
84
85 $( e.target ).
86 find( '.jet-form-builder-file-upload__file-remove' ).
87 each( function () {
88 const name = $( this ).data( 'file-name' );
89
90 for ( const file of files ) {
91 if ( file.name !== name ) {
92 continue;
93 }
94
95 transfer.items.add( file );
96 }
97
98 } );
99
100 input[ 0 ].files = transfer.files;
101 },
102
103 deleteUpload: function () {
104 const action = new DeleteAction( this );
105
106 action.remove();
107 action.showErrors();
108 },
109
110 issetMessage: function ( formId, status ) {
111 if ( !window.JetFormBuilderFileUploadConfig.errors[ formId ] ) {
112 return false;
113 }
114
115 return window.JetFormBuilderFileUploadConfig.errors[ formId ][ status ];
116 },
117
118 getMessage: function ( formId, status ) {
119 const { __ } = wp.i18n;
120 const unknown = __( 'Unknown error.', 'jet-form-builder' );
121 const message = JetFormBuilderFileUpload.issetMessage( formId,
122 status );
123
124 return message || unknown;
125 },
126
127 processUpload: function ( event ) {
128 const upload = new UploadAction( event );
129
130 upload.loadFiles();
131 upload.removeSingle();
132 upload.insertPreviews();
133 upload.sortable();
134
135 upload.showErrors();
136 },
137 };
138
139 class ChangeFiles {
140 constructor( event ) {
141 this.uploadEl = $( event.target ?? event ).
142 closest( '.jet-form-builder-file-upload' );
143 this.errorsEl = this.uploadEl.find(
144 '.jet-form-builder-file-upload__errors' );
145 this.previewsEl = this.uploadEl.find(
146 '.jet-form-builder-file-upload__files' );
147 this.settings = this.previewsEl.data( 'args' );
148 this.fields = this.getFields();
149 this.input = this.getFields().find( 'input[type="file"]' );
150 this.hasError = false;
151 }
152
153 removeSingle() {
154 if ( this.isSingle() ) {
155 this.getPreview().remove();
156 }
157 }
158
159 showErrors() {
160 this.input.removeClass( 'field-has-error' );
161 this.fields.find( '.error-message' ).remove();
162
163 if ( this.getPreview()?.length > this.settings.max_files ) {
164 this.input.addClass( 'field-has-error' );
165 this.fields.append(
166 $( `<div class="error-message">${ this.getMessage(
167 'upload_max_files' ) }</div>` ),
168 );
169
170 return;
171 }
172
173 if ( this.hasError ) {
174 this.input.addClass( 'field-has-error' );
175 this.fields.append(
176 $( `<div class="error-message">${ this.getMessage(
177 this.hasError ) }</div>` ),
178 );
179 }
180 }
181
182 getPreview() {
183 return this.previewsEl.find(
184 '.jet-form-builder-file-upload__file' );
185 }
186
187 getFields() {
188 return this.uploadEl.find(
189 '.jet-form-builder-file-upload__fields' );
190 }
191
192 getFormId() {
193 return this.uploadEl.closest( 'form.jet-form-builder' ).
194 data( 'form-id' );
195 }
196
197 getMessage( status ) {
198 return JetFormBuilderFileUpload.getMessage( this.getFormId(),
199 status );
200 }
201
202 isSingle() {
203 return (
204 !this.settings?.max_files || this.settings.max_files <= 1
205 );
206 }
207 }
208
209 class UploadAction extends ChangeFiles {
210 constructor( event ) {
211 super( event );
212
213 this.template = this.getTemplate();
214 }
215
216 loadFiles() {
217 const originalInput = this.input[ 0 ];
218 const { files } = originalInput;
219
220 this.files = createFileList( [ ...files ] );
221
222 if ( this.isSingle() ) {
223 return;
224 }
225
226 if ( !originalInput.jfbPrevFiles?.length ) {
227 originalInput.jfbPrevFiles = createFileList( [ ...files ] );
228
229 return;
230 }
231
232 originalInput.jfbPrevFiles = createFileList( [
233 ...originalInput.jfbPrevFiles,
234 ...this.files,
235 ] );
236
237 originalInput.files = createFileList( [
238 ...originalInput.jfbPrevFiles,
239 ] );
240 }
241
242 insertPreviews() {
243 this.errorsEl.html( '' ).addClass( 'is-hidden' );
244
245 const previewElements = [];
246
247 for ( const file of this.files ) {
248 const url = URL.createObjectURL( file );
249 const current = this.getFilePreview( url, file );
250
251 try {
252 this.validateImage( file, current );
253 }
254 catch ( error ) {
255 this.hasError = error;
256 current.find(
257 '.jet-form-builder-file-upload__file-invalid-marker' ).
258 show();
259 }
260
261 previewElements.push( current );
262 }
263
264 this.previewsEl.append( previewElements );
265 }
266
267 sortable() {
268 this.previewsEl.sortable( {
269 items: '.jet-form-builder-file-upload__file',
270 forcePlaceholderSize: true,
271 } ).
272 bind( 'sortupdate',
273 JetFormBuilderFileUpload.onSortCallback );
274 }
275
276 validateImage( file, current ) {
277 if ( file.size > this.settings.max_size ) {
278 throw 'upload_max_size';
279 }
280 }
281
282 getFilePreview( url, file ) {
283 let template = this.template.replace( '%file_url%', url );
284 template = $(
285 template.replace( '%file_name%', file.name ) );
286
287 if ( /^image\//.test( file.type ) ) {
288 template.prepend(
289 $( `<img src="${ url }" alt="${ file.name }">` ) );
290 }
291
292 return template;
293 }
294
295 getTemplate() {
296 return this.uploadEl.closest( '.field-type-media-field' ).
297 find( '.jet-form-builder__preview-template' ).
298 html();
299 }
300 }
301
302 class DeleteAction extends ChangeFiles {
303 constructor( event ) {
304 super( event );
305
306 this.self = $( event );
307 this.previewEl = this.self.closest(
308 '.jet-form-builder-file-upload__file' );
309 this.name = this.self.data( 'file-name' );
310 }
311
312 remove() {
313 const fieldValue = this.removeFileFromFileList();
314 this.input.trigger( 'change.JetFormBuilderMain' );
315
316 this.previewEl.trigger( 'jet-form-builder/on-remove-media-item',
317 [ fieldValue ] );
318 this.previewEl.remove();
319 }
320
321 removeFileFromFileList() {
322 const dt = new DataTransfer();
323 const originalInput = this.input[ 0 ];
324
325 const { files } = originalInput;
326 let removedFile;
327
328 for ( const file of files ) {
329 if ( this.name !== file.name ) {
330 dt.items.add( file );
331 }
332 else {
333 removedFile = file;
334 }
335 }
336
337 originalInput.files = dt.files;
338
339 if ( !dt.files.length ) {
340 delete originalInput.jfbPrevFiles;
341
342 return removedFile;
343 }
344
345 originalInput.jfbPrevFiles = createFileList( [
346 ...originalInput.files,
347 ] );
348
349 return removedFile;
350 }
351 }
352
353 $( document ).
354 on( 'jet-form-builder/init', JetFormBuilderFileUpload.init ).
355 on( 'change', '.jet-form-builder-file-upload__input',
356 JetFormBuilderFileUpload.processUpload ).
357 on( 'click', '.jet-form-builder-file-upload__file-remove',
358 JetFormBuilderFileUpload.deleteUpload );
359
360 }( jQuery )
361 );