PageSourceSearch

https://rigny70.fr/wp-content/plugins/ninja-forms-uploads/assets/j…/controllers/fieldFile.js?ver=3.3.11

js rigny70.fr collected 2026-10-02 23:03:41 UTC 11,734 bytes, 400 lines download raw bytes

1(function( $ ) {
2	var nfRadio = Backbone.Radio;
3	var radioChannel = nfRadio.channel( 'file_upload' );
4
5	var fileModel = Backbone.Model.extend( {
6		id: 0,
7		name: '',
8		tmpName: '',
9		fieldID: 0
10	} );
11
12	var FileCollection = Backbone.Collection.extend( {
13		model: fileModel
14	} );
15
16	var fileView = Marionette.ItemView.extend( {
17		tagName: 'nf-section',
18		template: '#tmpl-nf-field-file-row',
19
20		events: {
21			'click .delete': 'clickDelete'
22		},
23
24		clickDelete: function( event ) {
25			radioChannel.trigger( 'click:deleteFile', event, this.model );
26		}
27
28	} );
29
30	var fileCollectionView = Marionette.CollectionView.extend( {
31		childView: fileView
32	} );
33
34	var uploadController = Marionette.Object.extend( {
35
36		jqXHR: [],
37		$progress_bars: [],
38
39		initialize: function() {
40			this.listenTo( radioChannel, 'init:model', this.initFile );
41			this.listenTo( radioChannel, 'render:view', this.initFileUpload );
42			this.listenTo( radioChannel, 'click:deleteFile', this.deleteFile );
43			radioChannel.reply( 'validate:required', this.validateRequired );
44			radioChannel.reply( 'get:submitData', this.getSubmitData );
45		},
46
47		initFile: function( model ) {
48			model.set( 'uploadMulti', 1 != model.get( 'upload_multi_count' ) ) ;
49		},
50
51		renderView: function( view ) {
52			var el = $( view.el ).find( '.files_uploaded' );
53			view.fileCollectionView = new fileCollectionView( {
54				el: el,
55				collection: view.model.get( 'files' ),
56				thisModel: this.model
57			} );
58
59			view.model.bind( 'change:files', this.changeCollection, view );
60
61			/*
62			 * This radio responder is only necessary if we have Multi-Part Forms active.
63			 * Thankfully, it won't fire if the add-on isn't active.
64			 *
65			 * When we change our parts in a Multi-Part Form, re-render our file collection.
66			 */
67			view.listenTo( nfRadio.channel( 'nfMP' ), 'change:part', this.changeCollection, view );
68		},
69
70		changeCollection: function() {
71			this.fileCollectionView.render();
72		},
73
74		getFieldID: function( e ) {
75			var $parent = $( e.target ).parents( '.field-wrap' );
76
77			return $parent.data( 'field-id' );
78		},
79
80		getProgressBar: function( e ) {
81			var fieldID = this.getFieldID( e );
82
83			return this.$progress_bars[ fieldID ];
84		},
85
86		resetProgress: function( e ) {
87			var self = this;
88			setTimeout( function() {
89				self.getProgressBar( e ).css( 'width', 0 );
90			}, 1500 );
91		},
92
93		checkFilesLimit: function( view, e, data ) {
94			var limit = view.model.get( 'upload_multi_count' );
95
96			if ( 1 == limit ) {
97				return true;
98			}
99
100			var files = view.model.get( 'files' );
101
102			if ( ( files && files.length >= limit ) || data.files.length > limit ) {
103				var error_msg = nf_upload.strings.file_limit.replace( '%n', limit );
104				alert( error_msg );
105				return false;
106			}
107
108			return true;
109		},
110
111		maybeSubmitFieldData: function( data ) {
112			if ( data.paramName === 'files-' + data.formData.field_id || data.paramName === 'files-' + data.formData.field_id + '[]' ) {
113				this.jqXHR[ data.formData.field_id ] = data.submit();
114			}
115		},
116
117		showError: function( error, view ) {
118			nfRadio.channel( 'fields' ).request( 'add:error', view.model.id, 'upload-file-error', error );
119		},
120
121		resetError: function( view, fieldID  ) {
122			nfRadio.channel( 'fields' ).request( 'remove:error', fieldID, 'upload-file-error' );
123			this.$progress_bars[ fieldID ].css( 'width', 0 );
124			$( view.el ).find( '.nf-fu-button-cancel' ).hide();
125			var formID = view.model.get( 'formID' );
126			nfRadio.channel( 'form-' + formID ).trigger( 'enable:submit', view.model );
127		},
128
129		cancelUpload: function( e ) {
130			var fieldID = e.data.view.model.id;
131			e.data.controller.jqXHR[ fieldID ].abort();
132			e.data.controller.resetError( e.data.view, fieldID );
133		},
134
135		isNonceValid: function( view ) {
136			var nonceExpiry = view.model.get( 'uploadNonceExpiry' );
137			if ( typeof nonceExpiry === 'undefined' || nonceExpiry === null ) {
138				return false
139			}
140
141			var now = Math.round( (new Date()).getTime() / 1000 );
142
143			return now < nonceExpiry;
144		},
145
146		getValidNonce: function( field_id ) {
147			return jQuery.post( {
148				url: nfFrontEnd.adminAjax + '?action=nf_fu_get_new_nonce',
149				type: 'POST',
150				data: {
151					'field_id': field_id
152				},
153				cache: false
154			} );
155		},
156
157		initFileUpload: function( view ) {
158			var fieldID = view.model.id;
159			var formID = view.model.get( 'formID' );
160			var nonce = view.model.get( 'uploadNonce' );
161			var $file = $( view.el ).find( '.nf-element' );
162			var $files_uploaded = $( view.el ).find( '.files_uploaded' );
163			this.$progress_bars[ fieldID ] = $( view.el ).find( '.nf-fu-progress-bar' );
164			var url = nfFrontEnd.adminAjax + '?action=nf_fu_upload';
165			var self = this;
166			var files = view.model.get( 'files' );
167
168			$( view.el ).find( 'button.nf-fu-button-cancel' ).on( 'click', { view: view, controller: self }, self.cancelUpload );
169
170			$( view.el ).find( 'button.nf-fu-fileinput-button' ).on( 'click', function() {
171				// Don't show required validation error on click of the file upload button
172				view.model.set( 'firstTouch', false );
173			} );
174
175			/*
176			 * Make sure that our files array isn't undefined.
177			 * If it is, set it to an empty array.
178			 */
179			files = files || [];
180
181			/*
182			 * If "files" isn't a collection, turn it into one.
183			 */
184			if ( ! ( files instanceof FileCollection ) ) {
185				files = new FileCollection( files );
186				view.model.set( 'files', files );
187			}
188
189			this.renderView( view );
190
191			var formData = {
192				form_id: formID,
193				field_id: fieldID,
194				nonce: nonce,
195				abort: false
196			};
197
198			$file.fileupload( {
199				url: url,
200				dataType: 'json',
201				messages: {
202					maxFileSize: nf_upload.strings.max_file_size_error.replace( '%n', view.model.get( 'max_file_size_mb' ) ),
203					minFileSize: nf_upload.strings.min_file_size_error.replace( '%n', view.model.get( 'min_file_size_mb' ) )
204				},
205				maxChunkSize: view.model.get( 'max_chunk_size' ),
206				dropZone: $( view.el ),
207				maxFileSize: view.model.get( 'max_file_size' ),
208				minFileSize: view.model.get( 'min_file_size' ),
209				add: function (e, data) {
210					$( view.el ).find( '.nf-fu-button-cancel' ).show();
211					formData.abort = false;
212					data.formData = formData;
213					if ( self.isNonceValid( view ) ) {
214						self.maybeSubmitFieldData( data );
215
216						return;
217					}
218
219					self.getValidNonce( formData.field_id ).done( function( response ) {
220						if ( !response.success ) {
221							self.showError( nf_upload.strings.upload_nonce_error, view );
222							return false;
223						}
224
225						view.model.set( 'uploadNonce', response.data.nonce );
226						view.model.set( 'uploadNonceExpiry', response.data.nonce_expiry );
227
228						data.formData.nonce = response.data.nonce;
229						self.maybeSubmitFieldData( data );
230					} );
231				},
232				change: function( e, data ) {
233					if ( !self.checkFilesLimit( view, e, data ) ) {
234						return false;
235					}
236					// Remove any errors on this field.
237					nfRadio.channel( 'fields' ).request( 'remove:error', view.model.get( 'id' ), 'required-error' );
238				},
239				drop: function( e, data ) {
240					if ( !self.checkFilesLimit( view, e, data ) ) {
241						return false;
242					}
243				},
244				done: function( e, data ) {
245					if ( !data.result || data.result === undefined ) {
246						self.showError( nf_upload.strings.unknown_upload_error, view );
247						self.resetProgress( e );
248						return;
249					}
250
251					if ( -1 === data.result ) {
252						self.showError( nf_upload.strings.upload_error, view );
253						self.resetProgress( e );
254						return;
255					}
256
257					// Check for errors
258					if ( data.result.errors.length ) {
259						$.each( data.result.errors, function( index, error ) {
260							self.showError( error, view );
261						} );
262					}
263
264					if ( data.result.data.files === undefined || !data.result.data.files.length ) {
265						self.resetProgress( e );
266
267						return;
268					}
269
270					var allowed = view.model.get( 'upload_multi_count' );
271					var limit = 1;
272
273					if ( 1 != allowed ) {
274						var uploaded = view.model.get( 'files' ).length;
275						limit = allowed - uploaded;
276
277						if ( limit <= 0 ) {
278							var error_msg = nf_upload.strings.file_limit.replace( '%n', allowed );
279							self.showError( error_msg, view );
280							self.resetProgress( e );
281							return;
282						}
283					}
284
285					$( view.el ).find( '.nf-fu-button-cancel' ).hide();
286
287					var count = 0;
288					$.each( data.result.data.files, function( index, file ) {
289						count++;
290						if ( count > limit ) {
291							return false;
292						}
293						files.add( new fileModel( { name: file.name, tmp_name: file.tmp_name, fieldID: fieldID } ) );
294					} );
295
296					view.model.set( 'files', files );
297					view.model.trigger( 'change:files', view.model );
298					view.model.set( 'value', 1 );
299
300					self.resetProgress( e );
301
302					nfRadio.channel( 'fields' ).trigger( 'change:field', view.el, view.model );
303					nfRadio.channel( 'form-' + formID ).trigger( 'enable:submit', view.model );
304				},
305				start: function() {
306					if ( 1 == view.model.get( 'upload_multi_count' ) ) {
307						// Remove the files uploaded display and reset the collection
308						$files_uploaded.empty();
309						files.reset();
310					}
311					nfRadio.channel( 'fields' ).request( 'remove:error', view.model.id, 'upload-file-error' );
312					nfRadio.channel( 'form-' + formID ).trigger( 'disable:submit', view.model );
313				},
314				progressall: function( e, data ) {
315					var progress = parseInt( data.loaded / data.total * 100, 10 );
316					self.getProgressBar( e ).css( 'width', progress + '%' );
317				}
318			} ).on( 'fileuploadprocessalways', function( e, data ) {
319				var index = data.index,
320					file = data.files[ index ];
321				if ( file.error ) {
322					nfRadio.channel( 'fields' ).request( 'add:error', view.model.id, 'upload-file-error', file.error );
323				}
324			} ).on( 'fileuploadchunkdone', function( e, data ) {
325				// Check for errors
326				if ( data.result.errors.length ) {
327					$.each( data.result.errors, function( index, error ) {
328						self.showError( error, view );
329					} );
330
331					self.jqXHR[ formData.field_id ].abort();
332					self.$progress_bars[  formData.field_id ].css( 'width', 0 );
333					formData.abort = true;
334					return;
335				}
336
337				var key = data.result.data.files[ 0 ][ 'new_tmp_key' ];
338				formData[ key ] = data.result.data.files[ 0 ][ 'tmp_name' ];
339			} ).on( "fileuploadchunksend", function( e, data ) {
340				if ( formData.abort === true ) {
341					return false;
342				}
343			} )
344				.prop( 'disabled', !$.support.fileInput )
345				.parent().addClass( $.support.fileInput ? undefined : 'disabled' );
346		},
347
348		getSubmitData: function( fieldData, field ) {
349			fieldData.files = field.get( 'files' );
350
351			return fieldData;
352		},
353
354		deleteFile: function( event, model ) {
355			event.preventDefault();
356			model.collection.remove( model );
357			// send off AJAX request to delete temp file or uploaded file
358
359			var fieldModel = nfRadio.channel( 'fields' ).request( 'get:field', model.get( 'fieldID' ) );
360			nfRadio.channel( 'fields' ).trigger( 'change:field', '', fieldModel );
361			// Remove any errors on this field.
362			nfRadio.channel( 'fields' ).request( 'remove:error', fieldModel, 'required-error' );
363		},
364
365		/**
366		 * Check files have been submitted successfully for required field check
367		 *
368		 * @param el
369		 * @param model
370		 * @returns {boolean}
371		 */
372		validateRequired: function( el, model ) {
373			if ( !model.get( 'firstTouch' ) ) {
374				model.set( 'firstTouch', true );
375				return true;
376			}
377
378			var files = model.get( 'files' );
379			if ( typeof files === 'undefined' || !files.length ) {
380				model.set( 'value', '' );
381				return false;
382			}
383
384			return true;
385		}
386
387	} );
388
389	new uploadController();
390
391	$( document ).ready( function() {
392		$( 'body' ).on( 'click', 'button.nf-fu-fileinput-button', function( e ) {
393			$( this ).parent().find( 'input.nf-element' ).click();
394		} );
395
396		$( document ).bind( 'drop dragover', function( e ) {
397			e.preventDefault();
398		} );
399	} );
400})( jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.