Jake Vanderwerf
2026-01-01 8d0e2130627497b55b1a61cbe374bfb309ef2f27
src/forms/view.js
@@ -3,12 +3,19 @@
 * Frontend JavaScript for the Form Block
 * Handles form validation and submission
 */
/**
 * view.js
 * Frontend JavaScript for the Form Block
 */
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.registerForm(form, {
            autosave: true,
            autoUpload: false
         });
      });
      this.controller.subscribe((event, data) => {
@@ -19,68 +26,57 @@
   }
   async handleFormSubmission(data) {
      let formId = data.formId;
      let formConfig = data.config;
      let formData = data.fullData;
      let form = formConfig.element;
      const { formId, config: formConfig, fullData: formData } = data;
      const form = formConfig.element;
      // Create FormData instead of JSON
      const submitData = new FormData();
      // Add all regular form fields
      // Add 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 (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
      // Add uploaded files
      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);
         });
         try {
            const files = await window.jvbUploads.getFilesForForm(form);
            files.forEach(({ file, fieldName }) => {
               submitData.append(`${fieldName}[]`, file);
            });
         } catch (error) {
            console.error('Error getting files:', error);
         }
      }
      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
            body: submitData
         });
         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.handleFormError(form, result);
            return;
         }
         this.controller.showFormStatus(formId, 'submitted');
         this.controller.showSummary(formId, '.jvb-form-block');
         // Clean up uploaded files from IndexedDB after successful submission
         // Clean up uploaded files
         if (window.jvbUploads) {
            const uploadFields = form.querySelectorAll('[data-upload-field]');
            for (const field of uploadFields) {
@@ -88,17 +84,16 @@
               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);
         await this.controller.store.delete(formId);
      }
   }
}