£Á°èZ¨Ä…–K§‚«“ô4“ÒÙ´dîfUÙÃÅ WKbyʦ•ꎅȮFÒ¿ÊÎóCozá¬S@6{Í:›œêZÌ:Š•_%:¢¾¾~;‘Ã~芩ÊÇí`ÔÑ©ú뙵'5I¿fš×WO%ø9¾«¾DK|€ùÍD”Ýs]nHÕ¶ê×Ӽ㞪éUWŸÈË%DÒÕ¬ï‘]/Åcx ‰ï2ß]ä6G[]S£Ôϯrs{úëóµmÒï#UQxo·õÞCe]"±/aÙ&Eã4ú9Jé_ÞåëdãöKë)AÞ ¯¹ægƒÛowÐø^d™ý½ßB7áyMä9ÜÖUã !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // the semi-colon before function invocation is a safety net against concatenated // scripts and/or other plugins which may not be closed properly. ;// noinspection JSUnusedLocalSymbols (function ($, window, document, undefined) { "use strict"; // undefined is used here as the undefined global variable in ECMAScript 3 is // mutable (ie. it can be changed by someone else). undefined isn't really being // passed in so we can ensure the value of it is truly undefined. In ES5, undefined // can no longer be modified. // window and document are passed through as local variables rather than global // as this (slightly) quickens the resolution process and can be more efficiently // minified (especially when both are regularly referenced in your plugin). // Create the defaults once var pluginName = "forminatorFrontMultiFile", defaults = {}, uploadRequests = [], uploadCompleted = []; // The actual plugin constructor function ForminatorFrontMultiFile(element, options) { this.element = element; this.$el = $(this.element); // jQuery has an extend method which merges the contents of two or // more objects, storing the result in the first object. The first object // is generally empty as we don't want to alter the default options for // future instances of the plugin this.form = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.form_id = 0; this.uploader = this.$el; this.element = this.uploader.data('element'); this.init(); } // Avoid Plugin.prototype conflicts $.extend(ForminatorFrontMultiFile.prototype, { init: function () { var self = this, fileList = [], ajax_request = []; if (this.form.find('input[name=form_id]').length > 0) { this.form_id = this.form.find('input[name=form_id]').val(); } uploadRequests[this.form_id] = uploadRequests[this.form_id] || 0; uploadCompleted[this.form_id] = uploadCompleted[this.form_id] || 0; this.uploader.on("drag dragstart dragend dragover dragenter dragleave drop", function(e) { e.preventDefault(); e.stopPropagation(); }); this.uploader.on("dragover dragenter", function(a) { $(this).addClass("forminator-dragover"); }); this.uploader.on("dragleave dragend drop", function(a) { $(this).removeClass("forminator-dragover"); }); this.uploader.find( ".forminator-upload-file--forminator-field-" + this.element ).on("click", function(e) { self.form.find( '.forminator-field-' + self.element + '-' + self.form_id ).click(); }); this.uploader.on("drop", function(e) { document.querySelector( '.forminator-field-' + self.element + '-' + self.form_id ).files = e.originalEvent.dataTransfer.files; self.form.find( '.forminator-field-' + self.element + '-' + self.form_id ).change(); }); this.uploader.on("click", function(e) { if ( e.target === e.currentTarget ) { self.form.find( '.forminator-field-' + self.element + '-' + self.form_id ).click(); } }); this.uploader.find('.forminator-multi-upload-message, .forminator-multi-upload-message p, .forminator-multi-upload-message .forminator-icon-upload').on("click", function(e) { if ( e.target === e.currentTarget ) { self.form.find( '.forminator-field-' + self.element + '-' + self.form_id ).click(); } }); this.form.on("forminator:form:submit:success", function(e) { fileList = []; }); this.form.on('forminator.front.pagination.buttons.updated', function (e) { // Disable the submit button if there are files being uploaded. if ( self.form.find( '.forminator-button-submit' ).length > 0 && uploadRequests[self.form_id] !== uploadCompleted[self.form_id]) { self.form.find('.forminator-button-submit').attr( 'disabled', true ).attr( 'data-uploading', true ); } else if ( self.form.find( '.forminator-button-next' ).length > 0 && self.form.find( '.forminator-button-next' ).attr('data-uploading') === 'true' ) { self.form.find('.forminator-button-next').attr( 'disabled', false ).removeAttr( 'data-uploading' ); } }); this.form.find( '.forminator-field-' + self.element + '-' + self.form_id ).on("change", function(e) { if( ! self.uploadingFile ){ self.uploadingFile = 1; var $this = $(this), param = this.files, uploadParam = []; $.when().then(function(){ $this.closest('.forminator-field').removeClass('forminator-has_error'); for ( var i = 0; i < param.length; i++ ) { uploadParam.push( param[ i ] ); fileList.push( param[ i ] ); } ajax_request = self.handleChangeCallback( uploadParam, $this, ajax_request ); var file_list = Array.prototype.slice.call( fileList ); if ( file_list.length > 0 ) { param = self.FileObjectItem(file_list); if ( 'submission' === $this.data( 'method' ) ) { $this.prop( 'files', param ); } } }).done(function(){ self.uploadingFile = null; }); } }); this.delete_files( fileList, ajax_request ); }, /** * Upload Ajax call * * @param param * @param $this * @param ajax_request */ handleChangeCallback: function ( param, $this, ajax_request ) { var self = this, uploadData = new FormData, nonce = this.form.find('input[name="forminator_nonce"]').val(), method = $this.data('method'), elementId = self.element; elementId = elementId.split('_')[0]; uploadData.append( "action", "forminator_multiple_file_upload" ); uploadData.append( "form_id", this.form_id ); uploadData.append( "element_id", elementId ); uploadData.append( "nonce", nonce ); $.each( param, function ( i, item ) { var unique_id = self.progress_bar( item, method ), totalFile = self.form.find('.upload-container-' + self.element + ' li').length, fileType = 'undefined' !== typeof $this.data('filetype') ? $this.data('filetype') : '', file_reg = new RegExp("(.*?)\.("+ fileType +")$"), itemName = item.name.toLowerCase(); if ( 'undefined' !== typeof $this.data('size') && $this.data('size') <= item.size ) { error_messsage = $this.data('size-message'); self.upload_fail_response( unique_id, error_messsage ); return; } else if( ! file_reg.test( itemName ) ) { var ext = itemName.split('.').pop(); error_messsage = '.' + ext + ' ' + $this.data('filetype-message'); self.upload_fail_response( unique_id, error_messsage ); return; } if( 'ajax' === method ) { uploadData.delete( self.element ); uploadData.delete( 'totalFiles' ); uploadData.append( "totalFiles", totalFile ); uploadData.append( elementId, item ); ajax_request.push( $.ajax({ xhr: function () { var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function (evt) { if (evt.lengthComputable) { var percentComplete = ( ( evt.loaded / evt.total ) * 100 ); if( 90 > percentComplete ) { self.form.find('#' + unique_id + ' .progress-percentage') .html(Math.round(percentComplete) + '% of '); } } }, false); return xhr; }, type: 'POST', url: window.ForminatorFront.ajaxUrl, data: uploadData, cache: false, contentType: false, processData: false, beforeSend: function () { self.form.find('.forminator-button-submit').attr( 'disabled', true ).attr( 'data-uploading', true ); self.$el.trigger('before:forminator:multiple:upload', uploadData); uploadRequests[self.form_id]++; }, success: function (data) { var element = self.element, current_file = { success: data.success, message: 'undefined' !== data.data.message ? data.data.message : '', file_id: unique_id, file_name: 'undefined' !== typeof data.data.file_url ? data.data.file_url.replace(/^.*[\\\/]/, '') : item.name, mime_type: item.type, }; self.add_upload_file( element, current_file ); if ( true === data.success && true === data.data.success && 'undefined' !== typeof data.data ) { self.upload_success_response( unique_id ); self.$el.trigger('success:forminator:multiple:upload', uploadData); } else { self.upload_fail_response( unique_id, data.data.message ); if( 'undefined' !== typeof data.data.error_type && 'limit' === data.data.error_type ) { self.form.find('#' + unique_id).addClass('forminator-upload-limit_error'); } self.$el.trigger('fail:forminator:multiple:upload', uploadData); } }, complete: function (xhr, status) { uploadCompleted[self.form_id]++; if ( uploadRequests[self.form_id] === uploadCompleted[self.form_id] ) { self.form.find('.forminator-button-submit').attr( 'disabled', false ).removeAttr( 'data-uploading' ); } self.$el.trigger('complete:forminator:multiple:upload', uploadData); self.$el.find('input[type="file"]').trigger('forminator.change', 'forminator_emulate_trigger' ); }, error: function (err) { self.upload_fail_response( unique_id, window.ForminatorFront.cform.process_error ); } })) } else { var has_error = true, error_messsage = window.ForminatorFront.cform.process_error; if( 'undefined' !== typeof $this.data('limit') && $this.data('limit') < totalFile ) { has_error = false; self.form.find('#' + unique_id).addClass('forminator-upload-limit_error'); error_messsage = $this.data('limit-message'); } if( ! has_error ) { self.upload_fail_response( unique_id, error_messsage ); } else { self.upload_success_response( unique_id ); } self.$el.find('input[type="file"]').trigger('forminator.change', 'forminator_emulate_trigger' ); } }); return ajax_request; }, /** * Ajax fail response * * @param unique_id * @param message */ upload_fail_response: function( unique_id, message ) { this.form.trigger( 'validation:error' ); this.form.find('#' + unique_id).addClass('forminator-has_error'); this.form.find('#' + unique_id).find('.forminator-uploaded-file--size [class*="forminator-icon-"]') .addClass('forminator-icon-warning') .removeClass('forminator-icon-loader') .removeClass('forminator-loading'); this.form.find('#' + unique_id + ' .progress-percentage').html('0% of '); this.form.find('#' + unique_id + ' .forminator-uploaded-file--content') .after('
'); }, /** * Ajax success response * * @param unique_id */ upload_success_response: function( unique_id ) { this.form.find('#' + unique_id + ' .progress-percentage').html('100% of '); this.form.find('#' + unique_id + ' .forminator-uploaded-file--size [class*="forminator-icon-"]').remove(); this.form.find('#' + unique_id + ' .progress-percentage').remove(); }, /** * Show progress bar * * @param file * @param method */ progress_bar: function( file, method ) { var self = this, uniqueID = Math.random().toString( 36 ).substr( 2, 7 ), uniqueId = 'upload-process-' + uniqueID, filename = file.name, filesize = self.bytes_to_size( file.size, 2 ), wrapper = this.uploader.closest( '.forminator-field' ).find( '.forminator-uploaded-files' ), markup = '' ; this.progress_image_preview( file, uniqueId ); function getFileExtension( element ) { var parts = element.split( '.' ); return parts[ parts.length - 1 ]; } function isImage( element ) { var ext = getFileExtension( element ); switch ( ext.toLowerCase() ) { case 'jpg': case 'jpe': case 'jpeg': case 'png': case 'gif': case 'ico': return true; } return false; } /** * File Preview Markup. * * Get the icon file or replace it with image preview. */ var preview = ''; if ( isImage( filename ) ) { preview = ''; } /** * File Name. * * Get the name of the uploaded file (extension included). */ var name = '' + filename.replace( /[<>:"/\\|?*]+/g, '_' ) + '
'; /** * File Size. * * Depending on the state of the file user will get a: * - Loading Icon: When file is still being uploaded. * This will be accompanied by percent amount. * - Warning Icon: When file finished loading but an * error happened. * - File Size. */ var size = '' + '' + '29% of ' + filesize + '
'; /** * File Delete Button. * * This icon button will have the ability to remove * the uploaded file. */ var trash = ''; /** * Markup. */ markup += '