311 lines
No EOL
11 KiB
JavaScript
311 lines
No EOL
11 KiB
JavaScript
/**
|
|
* Direct Dropzone Initialization for XHR Forms
|
|
*
|
|
* This script directly targets Form plugin's Dropzone initialization mechanisms
|
|
*/
|
|
(function() {
|
|
'use strict';
|
|
|
|
// Enable debugging logs
|
|
const DEBUG = false;
|
|
|
|
// Helper function for logging
|
|
function log(message, type = 'log') {
|
|
if (!DEBUG) return;
|
|
|
|
const prefix = '[Dropzone Direct Init]';
|
|
|
|
if (type === 'error') {
|
|
console.error(prefix, message);
|
|
} else if (type === 'warn') {
|
|
console.warn(prefix, message);
|
|
} else {
|
|
console.log(prefix, message);
|
|
}
|
|
}
|
|
|
|
// Flag to prevent multiple initializations
|
|
let isInitializing = false;
|
|
|
|
// Function to directly initialize Dropzone
|
|
function initializeDropzone(element) {
|
|
if (isInitializing) {
|
|
log('Initialization already in progress, skipping');
|
|
return false;
|
|
}
|
|
|
|
if (!element || element.classList.contains('dz-clickable')) {
|
|
return false;
|
|
}
|
|
|
|
log('Starting direct Dropzone initialization for element:', element);
|
|
isInitializing = true;
|
|
|
|
// First, let's try to find the FilesField constructor in the global scope
|
|
if (typeof FilesField === 'function') {
|
|
log('Found FilesField constructor, trying direct instantiation');
|
|
|
|
try {
|
|
new FilesField({
|
|
container: element,
|
|
options: {}
|
|
});
|
|
|
|
log('Successfully initialized Dropzone using FilesField constructor');
|
|
isInitializing = false;
|
|
return true;
|
|
} catch (e) {
|
|
log(`Error using FilesField constructor: ${e.message}`, 'error');
|
|
// Continue with other methods
|
|
}
|
|
}
|
|
|
|
// Second approach: Look for the Form plugin's initialization code in the page
|
|
const dropzoneInit = findFunctionOnWindow('addNode') ||
|
|
window.addNode ||
|
|
findFunctionOnWindow('initDropzone');
|
|
|
|
if (dropzoneInit) {
|
|
log('Found Form plugin initialization function, calling it directly');
|
|
|
|
try {
|
|
dropzoneInit(element);
|
|
log('Successfully called Form plugin initialization function');
|
|
isInitializing = false;
|
|
return true;
|
|
} catch (e) {
|
|
log(`Error calling Form plugin initialization function: ${e.message}`, 'error');
|
|
// Continue with other methods
|
|
}
|
|
}
|
|
|
|
// Third approach: Try to invoke Dropzone directly if it's globally available
|
|
if (typeof Dropzone === 'function') {
|
|
log('Found global Dropzone constructor, trying direct instantiation');
|
|
|
|
try {
|
|
// Extract settings from the element
|
|
const settingsAttr = element.getAttribute('data-grav-file-settings');
|
|
if (!settingsAttr) {
|
|
log('No settings found for element', 'warn');
|
|
isInitializing = false;
|
|
return false;
|
|
}
|
|
|
|
const settings = JSON.parse(settingsAttr);
|
|
const optionsAttr = element.getAttribute('data-dropzone-options');
|
|
const options = optionsAttr ? JSON.parse(optionsAttr) : {};
|
|
|
|
// Configure Dropzone options
|
|
const dropzoneOptions = {
|
|
url: element.getAttribute('data-file-url-add') || window.location.href,
|
|
maxFiles: settings.limit || null,
|
|
maxFilesize: settings.filesize || 10,
|
|
acceptedFiles: settings.accept ? settings.accept.join(',') : null
|
|
};
|
|
|
|
// Merge with any provided options
|
|
Object.assign(dropzoneOptions, options);
|
|
|
|
// Create new Dropzone instance
|
|
new Dropzone(element, dropzoneOptions);
|
|
|
|
log('Successfully initialized Dropzone using global constructor');
|
|
isInitializing = false;
|
|
return true;
|
|
} catch (e) {
|
|
log(`Error using global Dropzone constructor: ${e.message}`, 'error');
|
|
// Continue to final approach
|
|
}
|
|
}
|
|
|
|
// Final approach: Force reloading of Form plugin's JavaScript
|
|
log('Attempting to force reload Form plugin JavaScript');
|
|
|
|
// Look for Form plugin's JS files
|
|
const formVendorScript = document.querySelector('script[src*="form.vendor.js"]');
|
|
const formScript = document.querySelector('script[src*="form.min.js"]');
|
|
|
|
if (formVendorScript || formScript) {
|
|
log('Found Form plugin scripts, attempting to reload them');
|
|
|
|
// Create new script elements
|
|
if (formVendorScript) {
|
|
const newVendorScript = document.createElement('script');
|
|
newVendorScript.src = formVendorScript.src.split('?')[0] + '?t=' + new Date().getTime();
|
|
newVendorScript.async = true;
|
|
newVendorScript.onload = function() {
|
|
log('Reloaded Form vendor script');
|
|
|
|
// Trigger event after script loads
|
|
setTimeout(function() {
|
|
const event = new CustomEvent('mutation._grav', {
|
|
detail: { target: element }
|
|
});
|
|
document.body.dispatchEvent(event);
|
|
}, 100);
|
|
};
|
|
document.head.appendChild(newVendorScript);
|
|
}
|
|
|
|
if (formScript) {
|
|
const newFormScript = document.createElement('script');
|
|
newFormScript.src = formScript.src.split('?')[0] + '?t=' + new Date().getTime();
|
|
newFormScript.async = true;
|
|
newFormScript.onload = function() {
|
|
log('Reloaded Form script');
|
|
|
|
// Trigger event after script loads
|
|
setTimeout(function() {
|
|
const event = new CustomEvent('mutation._grav', {
|
|
detail: { target: element }
|
|
});
|
|
document.body.dispatchEvent(event);
|
|
}, 100);
|
|
};
|
|
document.head.appendChild(newFormScript);
|
|
}
|
|
}
|
|
|
|
// As a final resort, trigger the mutation event
|
|
log('Triggering mutation._grav event as final resort');
|
|
const event = new CustomEvent('mutation._grav', {
|
|
detail: { target: element }
|
|
});
|
|
document.body.dispatchEvent(event);
|
|
|
|
isInitializing = false;
|
|
return false;
|
|
}
|
|
|
|
// Helper function to find a function on the window object by name pattern
|
|
function findFunctionOnWindow(pattern) {
|
|
for (const key in window) {
|
|
if (typeof window[key] === 'function' && key.includes(pattern)) {
|
|
return window[key];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Function to check all Dropzone elements
|
|
function checkAllDropzones() {
|
|
const dropzones = document.querySelectorAll('.dropzone.files-upload:not(.dz-clickable)');
|
|
|
|
if (dropzones.length === 0) {
|
|
log('No uninitialized Dropzone elements found');
|
|
return;
|
|
}
|
|
|
|
log(`Found ${dropzones.length} uninitialized Dropzone elements`);
|
|
|
|
// Try to initialize each one
|
|
dropzones.forEach(function(element) {
|
|
initializeDropzone(element);
|
|
});
|
|
}
|
|
|
|
// Hook into form submission to reinitialize after XHR updates
|
|
function setupFormSubmissionHook() {
|
|
// First check if the XHR submit function is available
|
|
if (window.GravFormXHR && typeof window.GravFormXHR.submit === 'function') {
|
|
log('Found GravFormXHR.submit, attaching hook');
|
|
|
|
// Store the original function
|
|
const originalSubmit = window.GravFormXHR.submit;
|
|
|
|
// Override it with our version
|
|
window.GravFormXHR.submit = function(form) {
|
|
log(`XHR form submission detected for form: ${form?.id || 'unknown'}`);
|
|
|
|
// Call the original function
|
|
const result = originalSubmit.apply(this, arguments);
|
|
|
|
// Set up checks for after the submission completes
|
|
[500, 1000, 2000, 3000].forEach(function(delay) {
|
|
setTimeout(checkAllDropzones, delay);
|
|
});
|
|
|
|
return result;
|
|
};
|
|
|
|
log('Successfully hooked into GravFormXHR.submit');
|
|
}
|
|
|
|
// Also add a direct event listener for standard form submissions
|
|
document.addEventListener('submit', function(event) {
|
|
if (event.target.tagName === 'FORM') {
|
|
log(`Standard form submission detected for form: ${event.target.id || 'unknown'}`);
|
|
|
|
// Schedule checks after submission
|
|
[1000, 2000, 3000].forEach(function(delay) {
|
|
setTimeout(checkAllDropzones, delay);
|
|
});
|
|
}
|
|
});
|
|
|
|
log('Form submission hooks set up');
|
|
}
|
|
|
|
// Monitor for AJAX responses
|
|
function setupAjaxMonitoring() {
|
|
if (window.jQuery) {
|
|
log('Setting up jQuery AJAX response monitoring');
|
|
|
|
jQuery(document).ajaxComplete(function(event, xhr, settings) {
|
|
log('AJAX request completed, checking if form-related');
|
|
|
|
// Check if this looks like a form request
|
|
const url = settings.url || '';
|
|
if (url.includes('form') ||
|
|
url.includes('task=') ||
|
|
url.includes('file-upload') ||
|
|
url.includes('file-uploader')) {
|
|
|
|
log('Form-related AJAX request detected, will check for Dropzones');
|
|
|
|
// Schedule checks with delays
|
|
[300, 800, 1500].forEach(function(delay) {
|
|
setTimeout(checkAllDropzones, delay);
|
|
});
|
|
}
|
|
});
|
|
|
|
log('jQuery AJAX monitoring set up');
|
|
}
|
|
}
|
|
|
|
// Create global function for manual reinitialization
|
|
window.reinitializeDropzones = function() {
|
|
log('Manual reinitialization triggered');
|
|
checkAllDropzones();
|
|
return 'Reinitialization check triggered. See console for details.';
|
|
};
|
|
|
|
// Main initialization function
|
|
function initialize() {
|
|
log('Initializing Dropzone direct initialization system');
|
|
|
|
// Set up submission hook
|
|
setupFormSubmissionHook();
|
|
|
|
// Set up AJAX monitoring
|
|
setupAjaxMonitoring();
|
|
|
|
// Do an initial check for any uninitialized Dropzones
|
|
setTimeout(checkAllDropzones, 500);
|
|
|
|
log('Initialization complete. Use window.reinitializeDropzones() for manual reinitialization.');
|
|
}
|
|
|
|
// Start when the DOM is ready
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Delay to allow other scripts to load
|
|
setTimeout(initialize, 100);
|
|
});
|
|
} else {
|
|
// DOM already loaded, delay slightly
|
|
setTimeout(initialize, 100);
|
|
}
|
|
})(); |