From ed57c386db34d8693ca75311972d0929ebe5f488 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Mon, 01 Jun 2026 22:23:19 +0000
Subject: [PATCH] =Added some more Schema classes, allowed for override of  array in outputSchema for complex schema, as for timeline post types

---
 src/forms/view.js |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 112 insertions(+), 0 deletions(-)

diff --git a/src/forms/view.js b/src/forms/view.js
new file mode 100644
index 0000000..788e929
--- /dev/null
+++ b/src/forms/view.js
@@ -0,0 +1,112 @@
+/**
+ * view.js
+ * Frontend JavaScript for the Form Block
+ * Handles form validation and submission
+ */
+/**
+ * view.js
+ * Frontend JavaScript for the Form Block
+ */
+class FormBlock {
+	constructor() {
+		this.controller = window.jvbForm;
+
+		document.querySelectorAll('.jvb-form-block form').forEach(form => {
+			this.controller.registerForm(form, {
+				cache: true,
+				autoUpload: false,
+				imageMeta: false,
+			});
+		});
+
+		this.controller.subscribe((event, data) => {
+			if (event === 'form-submit') {
+				this.handleFormSubmission(data).then(()=>{});
+			}
+		});
+	}
+
+	async handleFormSubmission(eventData) {
+		const { config, data } = eventData;
+		const form = config.element;
+
+		const submitData = new FormData();
+
+		// Add regular form fields
+		for (const [key, value] of Object.entries(data)) {
+			if (Array.isArray(value)) {
+				value.forEach(v => submitData.append(`${key}[]`, v));
+			} else if (typeof value === 'object' && value !== null) {
+				submitData.append(key, JSON.stringify(value));
+			} else {
+				submitData.append(key, value);
+			}
+		}
+		config.element.querySelectorAll('[name="form_id"],[name="form_type"],[name="timestamp"],[name="cf-turnstile-response"]').forEach(input => {
+			submitData.append(input.name, input.value);
+		});
+
+		// Add uploaded files
+		if (window.jvbUploads) {
+			try {
+				const files = await window.jvbUploads.getFilesForForm(form);
+
+				files.forEach(({ file, fieldName }) => {
+					submitData.append(`${fieldName}[]`, file);
+				});
+			} catch (error) {
+				console.error('Error getting files:', error);
+			}
+		}
+
+		this.controller.showFormStatus(config.id, 'uploading');
+
+		try {
+			const response = await fetch(`${jvbSettings.api}forms`, {
+				method: 'POST',
+				credentials: 'same-origin',
+				body: submitData
+			});
+
+			const result = await response.json();
+
+			if (!response.ok) {
+				this.controller.showFormStatus(config.id, 'error');
+				this.controller.handleFormError(form, result);
+				return;
+			}
+
+			this.controller.showFormStatus(config.id, 'submitted');
+			// this.controller.handleFormSuccess(form, result);
+			this.controller.showSummary({ changes: data, config: config });
+			window.jvbA11y.announce('Form successfully submitted!');
+
+			// Clean up uploaded files
+			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(config.id, 'error');
+			this.controller.handleFormError(form, {
+				message: 'Network error. Please check your connection and try again.',
+				code: 'network_error'
+			});
+		} finally {
+			await this.controller.store.delete(config.id);
+		}
+	}
+}
+
+document.addEventListener('DOMContentLoaded', async function() {
+	window.auth.subscribe(event => {
+		if (event === 'auth-loaded') {
+			new FormBlock();
+		}
+	});
+});

--
Gitblit v1.10.0