{1}{2}{5}';
/**
* Filer the file upload markup as it is being uploaded.
*
* @param {string} statusMarkup Markup template used to render the status of the file being uploaded.
* @param {plupload.File} file Instance of File being uploaded. See: https://www.plupload.com/docs/v2/File.
* @param {int|string} size File size.
* @param {object} strings Array of localized strings relating to the file upload UI.
* @param {string} removeFileJs JS used to remove the file when the "Cancel" link is click/pressed.
* @param {plupload.Uploader} up Instance of Uploader responsible for uploading current file. See: https://www.plupload.com/docs/v2/Uploader.
*/
statusMarkup = gform.applyFilters( 'gform_file_upload_status_markup', statusMarkup, file, size, strings, removeFileJs, up )
.gformFormat( file.id, htmlEncode( file.name ), size, strings.cancel_upload, removeFileJs, strings.cancel );
$( '#' + up.settings.filelist ).prepend( statusMarkup );
totalCount++;
});
up.refresh(); // Reposition Flash
var formElementID = "form#gform_" + formID;
var uidElementID = "input:hidden[name='gform_unique_id']";
var uidSelector = formElementID + " " + uidElementID;
var $uid = $(uidSelector);
if($uid.length==0){
$uid = $(uidElementID);
}
uniqueID = $uid.val();
if('' === uniqueID){
uniqueID = generateUniqueID();
$uid.val(uniqueID);
}
if(max > 0 && totalCount >= max){
gfMultiFileUploader.toggleDisabled(up.settings, true);
addMessage(up.settings.gf_vars.message_id, strings.max_reached)
}
up.settings.multipart_params.gform_unique_id = uniqueID;
up.start();
});
uploader.bind('UploadProgress', function(up, file) {
var html = file.percent + "%";
$('#' + file.id + ' span.gfield_fileupload_percent').html(html);
$('#' + file.id + ' span.gfield_fileupload_progressbar_progress').css('width', file.percent + '%');
});
uploader.bind('Error', function(up, err) {
if(err.code === plupload.FILE_EXTENSION_ERROR){
var extensions = typeof up.settings.filters.mime_types != 'undefined' ? up.settings.filters.mime_types[0].extensions /* plupoad 2 */ : up.settings.filters[0].extensions;
addMessage(up.settings.gf_vars.message_id, err.file.name + " - " + strings.invalid_file_extension + " " + extensions);
} else if (err.code === plupload.FILE_SIZE_ERROR) {
addMessage(up.settings.gf_vars.message_id, err.file.name + " - " + strings.file_exceeds_limit);
} else {
const errorResponse = JSON.parse( err.response );
const errorCode = errorResponse?.error?.code || err.code;
const errorMessage = errorResponse?.error?.message || err.message;
const filePart = err.file?.name ? `${ err.file.name } - ` : '';
const m = `${ filePart }${ strings.error }: ${ errorCode }, ${ strings.message }: ${ errorMessage }`;
addMessage(up.settings.gf_vars.message_id, m);
}
$('#' + err.file.id ).html('');
up.removeFile( err.file );
up.refresh(); // Reposition Flash
});
uploader.bind('ChunkUploaded', function(up, file, result) {
var response = $.secureEvalJSON(result.response);
if(response.status == "error"){
up.removeFile(file);
addMessage(up.settings.gf_vars.message_id, file.name + " - " + response.error.message);
$('#' + file.id ).html('');
} else {
up.settings.multipart_params[file.target_name] = response.data;
}
});
uploader.bind('FileUploaded', function(up, file, result) {
if (!up.getFile(file.id)) {
// The file has been removed from the queue.
return;
}
var response = $.secureEvalJSON(result.response);
if (response.status == "error") {
addMessage(up.settings.gf_vars.message_id, file.name + " - " + response.error.message);
$('#' + file.id).html('');
toggleLimitReached(up.settings);
return;
}
var uploadedName = rgars(response, 'data/uploaded_filename');
var html = '
' + htmlEncode(uploadedName) + '' + plupload.formatSize(file.size) + '';
html += '
' + file.percent + '%';
var formId = up.settings.multipart_params.form_id;
var fieldId = up.settings.multipart_params.field_id;
if (typeof gf_legacy !== 'undefined' && gf_legacy.is_legacy) {
html = "
![]()
"
+ html;
} else {
html = html + "
";
}
/**
* Allows the markup for the file to be overridden.
*
* @since 1.9
* @since 2.4.23 Added the response param.
*
* @param {string} html The HTML for the file name and delete button.
* @param {object} file The file upload properties. See: https://www.plupload.com/docs/v2/File.
* @param {object} up The uploader properties. See: https://www.plupload.com/docs/v2/Uploader.
* @param {object} strings Localized strings relating to file uploads.
* @param {string} imagesURL The base URL to the Gravity Forms images directory.
* @param {object} response The response from GFAsyncUpload.
*/
html = gform.applyFilters('gform_file_upload_markup', html, file, up, strings, imagesUrl, response);
$('#' + file.id).html(html);
$('#' + file.id + ' span.gfield_fileupload_progressbar_progress').css('width', file.percent + '%');
if (file.percent == 100) {
if (response.status && response.status == 'ok') {
response.data.id = file.id;
addFile(fieldId, response.data);
window.wp.a11y.speak( ( strings.file_uploaded ) + ': ' + uploadedName );
} else {
addMessage(up.settings.gf_vars.message_id, strings.unknown_error + ': ' + file.name);
}
}
});
uploader.bind('FilesRemoved', function (up, files) {
toggleLimitReached(up.settings);
});
function getAllFiles(){
var selector = '#gform_uploaded_files_' + formID,
$uploadedFiles = $(selector), files;
files = $uploadedFiles.val();
files = (typeof files === "undefined") || files === '' ? {} : $.parseJSON(files);
return files;
}
function getFiles(fieldID){
var allFiles = getAllFiles();
var inputName = getInputName(fieldID);
if(typeof allFiles[inputName] == 'undefined')
allFiles[inputName] = [];
return allFiles[inputName];
}
function countFiles(fieldID){
var files = getFiles(fieldID);
return files.length;
}
function addFile(fieldID, fileInfo){
var files = getFiles(fieldID);
files.unshift(fileInfo);
setUploadedFiles(fieldID, files);
}
function setUploadedFiles(fieldID, files){
var allFiles = getAllFiles();
var $uploadedFiles = $('#gform_uploaded_files_' + formID);
var inputName = getInputName(fieldID);
allFiles[inputName] = files;
$uploadedFiles.val($.toJSON(allFiles));
}
function getInputName(fieldID){
return "input_" + fieldID;
}
// fixes drag and drop in IE10
$("#" + settings.drop_element).on({
"dragenter": ignoreDrag,
"dragover": ignoreDrag
});
function ignoreDrag( e ) {
e.preventDefault();
}
}
function generateUniqueID() {
return 'xxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : r & 0x3 | 0x8;
return v.toString(16);
});
}
function htmlEncode(value){
return $('
').text(value).html();
}
}(window.gfMultiFileUploader = window.gfMultiFileUploader || {}, jQuery));
//----------------------------------------
//------ TINYMCE FUNCTIONS ---------------
//----------------------------------------
/**
* @function gformReInitTinymceInstance
* @description Reinitializes a tinymce instance bound to a gform field if found.
*
* @since 2.5
*
* @param formId {int} Required. The form id.
* @param fieldId {int} Required. The field id.
*/
function gformReInitTinymceInstance( formId, fieldId ) {
// check for required arguments
if ( ! formId || ! fieldId ) {
gform.console.error( 'gformReInitTinymceInstance requires a form and field id.' );
return;
}
// make sure we have tinymce
var tinymce = window.tinymce;
if ( ! tinymce ) {
gform.console.error( 'gformReInitTinymceInstance requires tinymce to be available.' );
return;
}
// get the editor instance by form and field id and bail if not found
var editor = tinymce.get( 'input_' + formId + '_' + fieldId );
if ( ! editor ) {
gform.console.error( 'gformReInitTinymceInstance did not find an instance for input_' + formId + '_' + fieldId + '.' );
return;
}
// get the settings, destroy the instance and reinitialize
var settings = jQuery.extend( {}, editor.settings );
editor.remove();
tinymce.init( settings );
gform.console.log( 'gformReInitTinymceInstance reinitialized TinyMCE on input_' + formId + '_' + fieldId + '.' );
}
//----------------------------------------
//------ EVENT FUNCTIONS -----------------
//----------------------------------------
var __gf_keyup_timeout;
jQuery( document ).on( 'change keyup', '.gfield input, .gfield select, .gfield textarea', function( event ) {
gf_raw_input_change( event, this );
} );
function gf_raw_input_change( event, elem ) {
// clear regardless of event type for maximum efficiency ;)
clearTimeout( __gf_keyup_timeout );
var $input = jQuery( elem ),
htmlId = $input.attr( 'id' ),
fieldId = gf_get_input_id_by_html_id( htmlId ),
formId = gf_get_form_id_by_html_id( htmlId ),
/**
* Filter the field meta generated by a raw input change.
*
* @since 2.4.1
*
* @param object fieldMeta An object containing the field ID and form ID of the triggering Gravity Forms field.
* @param object $input The jQuery object for the triggering field element.
* @param object event The raw JS event.
*/
fieldMeta = gform.applyFilters( 'gform_field_meta_raw_input_change', { fieldId: fieldId, formId: formId }, $input, event );
fieldId = fieldMeta.fieldId;
formId = fieldMeta.formId;
if( ! fieldId ) {
return;
}
var isChangeElem = $input.is( ':checkbox' ) || $input.is( ':radio' ) || $input.is( 'select' ),
isKeyupElem = ! isChangeElem || $input.is( 'textarea' );
if( event.type == 'keyup' && ! isKeyupElem ) {
return;
} else if( event.type == 'change' && ! isChangeElem && ! isKeyupElem ) {
return;
}
if( event.type == 'keyup' ) {
__gf_keyup_timeout = setTimeout( function() {
gf_input_change( elem, formId, fieldId );
}, 300 );
} else {
gf_input_change( elem, formId, fieldId );
}
}
/**
* Get the input id from a form element's HTML id.
*
* @param {string} htmlId The HTML id of a form element.
*
* @returns {string} inputId The input id.
*/
function gf_get_input_id_by_html_id( htmlId ) {
var ids = gf_get_ids_by_html_id( htmlId ),
id = ids[ ids.length - 1 ];
if ( ids.length == 3 ) {
ids.shift();
id = ids.join( '.' );
}
return id;
}
/**
* Get the form id from a form element's HTML id.
*
* @param {string} htmlId The HTML id of a form element.
*
* @returns {string} formId The form id.
*/
function gf_get_form_id_by_html_id( htmlId ) {
var ids = gf_get_ids_by_html_id( htmlId );
return ids[0];
}
/**
* Get the form, field, and input id by a form elements HTML id.
*
* Note: Only multi-input fields will be return an input ID.
*
* @param {string} htmlId The HTML id of a form element.
*
* @returns {array} ids An array contain the form, field and input id.
*/
function gf_get_ids_by_html_id( htmlId ) {
var ids = htmlId ? htmlId.split( '_' ) : [];
for( var i = ids.length - 1; i >= 0; i-- ) {
if ( ! gform.utils.isNumber( ids[ i ] ) ) {
ids.splice( i, 1 );
}
}
return ids;
}
function gf_input_change( elem, formId, fieldId ) {
gform.doAction( 'gform_input_change', elem, formId, fieldId );
}
function gformExtractFieldId( inputId ) {
var fieldId = parseInt( inputId.toString().split( '.' )[0],10 );
return ! fieldId ? inputId : fieldId;
}
function gformExtractInputIndex( inputId ) {
var inputIndex = parseInt( inputId.toString().split( '.' )[1],10 );
return ! inputIndex ? false : inputIndex;
}
//----------------------------------------
//------ HELPER FUNCTIONS ----------------
//----------------------------------------
if( ! window['rgars'] ) {
function rgars( array, prop ) {
var props = prop.split( '/' ),
value = array;
for( var i = 0; i < props.length; i++ ) {
value = rgar( value, props[ i ] );
}
return value;
}
}
if( ! window['rgar'] ) {
function rgar( array, prop ) {
if ( typeof array[ prop ] != 'undefined' ) {
return array[ prop ];
}
return '';
}
}
if ( ! String.prototype.gformFormat ) {
String.prototype.gformFormat = function() {
var args = arguments;
return this.replace( /{(\d+)}/g, function( match, number ) {
return typeof args[ number ] != 'undefined' ? args[ number ] : match;
} );
};
}
/**
* Toggle the dropdown submenus in the form editor menu bar.
*
* @since 2.5
*/
jQuery( document ).ready( function() {
jQuery( '#gform-form-toolbar__menu' )
.on( 'mouseenter focus', '> li',function() {
jQuery( this ).find( '.gform-form-toolbar__submenu' ).toggleClass( 'open' );
jQuery( this ).find( '.has_submenu' ).toggleClass( 'submenu-open' );
} );
jQuery( '#gform-form-toolbar__menu' )
.on( 'mouseleave blur', '> li',function() {
jQuery( '.gform-form-toolbar__submenu.open' ).removeClass( 'open' );
jQuery( '.has_submenu.submenu-open' ).removeClass( 'submenu-open' );
} );
jQuery( '#gform-form-toolbar__menu .has_submenu' )
.on( 'click', function( e ) {
e.preventDefault();
} );
} );
/**
* Add a containing class to fields with multiple inputs that we want to display inline.
*
* @since 2.5
*/
jQuery( document ).ready( function() {
var settingsFields = jQuery( '.gform-settings-field' );
settingsFields.each( function() {
if ( jQuery( this ).find( '> .gform-settings-input__container' ).length > 1 ) {
jQuery( this ).addClass( 'gform-settings-field--multiple-inputs' );
}
} );
} );
jQuery( function() {
gform.tools.trigger( 'gform_main_scripts_loaded' );
} );