/**
|
* view.js
|
* Frontend JavaScript for the Form Block
|
* Handles form validation and submission
|
*/
|
class FormBlock {
|
constructor() {
|
this.controller = new window.jvbForm();
|
|
document.querySelectorAll('.jvb-form-block form').forEach(form => {
|
this.controller.registerForm(form, {autosave: true,autoUpload: false});
|
});
|
|
this.controller.subscribe((event, data) => {
|
if (event === 'form-submit') {
|
this.handleFormSubmission(data);
|
}
|
});
|
}
|
|
async handleFormSubmission(data) {
|
let formId = data.formId;
|
let formConfig = data.config;
|
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': window.auth.getNonce()
|
};
|
|
let block = form.closest('.jvb-form-block');
|
this.controller.showFormStatus(formId, 'uploading');
|
|
try {
|
const response = await fetch(`${jvbSettings.api}forms`, {
|
method: 'POST',
|
credentials: 'same-origin',
|
headers,
|
body: submitData // Send FormData instead of JSON
|
});
|
const result = await response.json();
|
|
if (!response.ok) {
|
this.controller.showFormStatus(formId, 'error');
|
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) {
|
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', async function() {
|
window.auth.subscribe(event => {
|
if (event === 'auth-loaded') {
|
new FormBlock();
|
}
|
});
|
});
|