| | |
| | | this.controller = new window.jvbForm(); |
| | | |
| | | document.querySelectorAll('.jvb-form-block form').forEach(form => { |
| | | this.controller.registerForm(form, {autosave: true}); |
| | | this.controller.registerForm(form, {autosave: true,autoUpload: false}); |
| | | }); |
| | | |
| | | this.controller.subscribe((event, data) => { |
| | |
| | | let formData = data.fullData; |
| | | let form = formConfig.element; |
| | | |
| | | // Create FormData instead of JSON |
| | | const submitData = new FormData(); |
| | | |
| | | // Add all regular form fields |
| | | for (const [key, value] of Object.entries(formData)) { |
| | | // Skip the nonce field - we don't need it for REST API with __return_true |
| | | if (key === '_wpnonce' || key === '_wp_http_referer') { |
| | | continue; |
| | | } |
| | | if (Array.isArray(value)) { |
| | | value.forEach(v => submitData.append(`${key}[]`, v)); |
| | | } else if (typeof value === 'object' && value !== null) { |
| | | // For nested objects, you might want to JSON.stringify them |
| | | submitData.append(key, JSON.stringify(value)); |
| | | } else { |
| | | submitData.append(key, value); |
| | | } |
| | | } |
| | | |
| | | // Get uploaded files from UploadManager |
| | | if (window.jvbUploads) { |
| | | const files = await window.jvbUploads.getFilesForForm(form); |
| | | |
| | | // Append files with their field names |
| | | files.forEach(({file, fieldName, uploadId, meta}) => { |
| | | // Use fieldName[] for multiple files per field |
| | | submitData.append(`${fieldName}[]`, file); |
| | | }); |
| | | } |
| | | |
| | | |
| | | let headers = { |
| | | 'X-WP-Nonce': jvbSettings.nonce, |
| | | 'Content-Type': 'application/json' |
| | | // 'X-WP-Nonce': window.auth.getNonce() |
| | | }; |
| | | |
| | | let block = form.closest('.jvb-form-block'); |
| | |
| | | try { |
| | | const response = await fetch(`${jvbSettings.api}forms`, { |
| | | method: 'POST', |
| | | credentials: 'same-origin', |
| | | headers, |
| | | body: JSON.stringify(formData) |
| | | body: submitData // Send FormData instead of JSON |
| | | }); |
| | | const result = await response.json(); |
| | | |
| | | if (!response.ok) { |
| | | this.controller.showFormStatus(formId, 'error'); |
| | | const errorData = await response.json().catch(() => ({})); |
| | | throw new Error(errorData.message || `Request failed with status ${response.status}`); |
| | | this.controller.handleFormError(form, result); // ✓ Show error to user |
| | | return; // Stop processing |
| | | } |
| | | |
| | | this.controller.showFormStatus(formId, 'submitted'); |
| | | this.controller.showSummary(formId, '.jvb-form-block'); |
| | | |
| | | // Clean up uploaded files from IndexedDB after successful submission |
| | | if (window.jvbUploads) { |
| | | const uploadFields = form.querySelectorAll('[data-upload-field]'); |
| | | for (const field of uploadFields) { |
| | | const fieldId = window.jvbUploads.determineFieldId(field); |
| | | await window.jvbUploads.clearFieldFromStores(fieldId); |
| | | } |
| | | } |
| | | } catch (error) { |
| | | throw error; |
| | | console.error('Form submission error:', error); |
| | | this.controller.showFormStatus(formId, 'error'); |
| | | |
| | | // Show user-friendly network error - IMPROVED |
| | | this.controller.handleFormError(form, { |
| | | message: 'Network error. Please check your connection and try again.', |
| | | code: 'network_error' |
| | | }); |
| | | } finally { |
| | | this.controller.store.delete(formId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | document.addEventListener('DOMContentLoaded', function() { |
| | | new FormBlock(); |
| | | document.addEventListener('DOMContentLoaded', async function() { |
| | | window.auth.subscribe(event => { |
| | | if (event === 'auth-loaded') { |
| | | new FormBlock(); |
| | | } |
| | | }); |
| | | }); |