From 552d48a1424417da160c4952650ea6f4a3d7bafa Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 04 Jan 2026 20:18:23 +0000
Subject: [PATCH] =Taxonomy Selector and Creator refactor

---
 assets/js/concise/PopulateForm.js |  728 ++++++++++++++++++++++++++++---------------------------
 1 files changed, 374 insertions(+), 354 deletions(-)

diff --git a/assets/js/concise/PopulateForm.js b/assets/js/concise/PopulateForm.js
index 8cef082..74dda58 100644
--- a/assets/js/concise/PopulateForm.js
+++ b/assets/js/concise/PopulateForm.js
@@ -1,25 +1,78 @@
 /**********************************************
  PopulateForm extracts saved data and populates the form field accordingly
-**********************************************/
+ **********************************************/
 class PopulateForm {
-	constructor(form, fieldData = {}, imageData = {}, options = {}) {
-		for (let [fieldName, fieldValue] of Object.entries(fieldData)) {
+	constructor(form, itemDataOrFields = {}, legacyImages = {}, options = {}) {
+		// Support both old signature (fields, images) and new signature (item object)
+		this.item = this.normalizeItemData(itemDataOrFields, legacyImages);
+		this.form = form;
+		this.options = options;
+
+		// Populate all fields
+		for (let [fieldName, fieldValue] of Object.entries(this.item.fields)) {
 			let wrapper = form.querySelector(`[data-field="${fieldName}"]`);
 			if (wrapper) {
-				this.populateField(wrapper, fieldName, fieldValue, imageData, options);
+				this.populateField(wrapper, fieldName, fieldValue);
 			}
 		}
 	}
 
 	/**
-	 * Populate a single field with its value
-	 * @param {HTMLElement} fieldWrapper - The field wrapper element
-	 * @param {string} fieldName - Field name
-	 * @param {*} fieldValue - Field value
-	 * @param {Object} imagesData - Image metadata
-	 * @param {Object} options - Additional options
+	 * Normalize data to consistent structure
+	 * Supports both new format (item object) and legacy format (fields, images)
 	 */
-	populateField(fieldWrapper, fieldName, fieldValue, imagesData = {}, options = {}) {
+	normalizeItemData(itemDataOrFields, legacyImages) {
+		// Check if this is the new format (has a fields property) or legacy format
+		if (itemDataOrFields && typeof itemDataOrFields === 'object' && 'fields' in itemDataOrFields) {
+			// New format - already structured
+			return {
+				fields: itemDataOrFields.fields || {},
+				images: itemDataOrFields.images || {},
+				taxonomies: itemDataOrFields.taxonomies || {}
+			};
+		} else {
+			// Legacy format - fields and images passed separately
+			return {
+				fields: itemDataOrFields || {},
+				images: legacyImages || {},
+				taxonomies: {}
+			};
+		}
+	}
+
+	/**
+	 * Check if a field is a taxonomy field
+	 */
+	isTaxonomyField(fieldName) {
+		return Object.hasOwn(this.item.taxonomies, fieldName) &&
+			Object.keys(this.item.taxonomies[fieldName]).length > 0;
+	}
+
+	/**
+	 * Check if a value references image data
+	 */
+	isImageField(value) {
+		if (!this.item.images || Object.keys(this.item.images).length === 0) {
+			return false;
+		}
+
+		const ids = this.splitIDs(value);
+		return ids.some(id => Object.keys(this.item.images).includes(String(id)));
+	}
+
+	/**
+	 * Split comma-separated IDs into array of integers
+	 */
+	splitIDs(value) {
+		return String(value).split(',')
+			.map(v => parseInt(v.trim()))
+			.filter(v => !isNaN(v) && v > 0);
+	}
+
+	/**
+	 * Populate a single field with its value
+	 */
+	populateField(fieldWrapper, fieldName, fieldValue, options = {}) {
 		if (!fieldWrapper || fieldValue === undefined || fieldValue === null) {
 			return;
 		}
@@ -31,11 +84,11 @@
 			case 'upload':
 			case 'gallery':
 			case 'image':
-				this.populateUploadField(fieldWrapper, fieldName, fieldValue, imagesData);
+				this.populateUploadField(fieldWrapper, fieldName, fieldValue);
 				break;
 
 			case 'repeater':
-				this.populateRepeaterField(fieldWrapper, fieldName, fieldValue, options);
+				this.populateRepeaterField(fieldWrapper, fieldName, fieldValue);
 				break;
 
 			case 'taxonomy':
@@ -73,6 +126,7 @@
 			case 'number':
 				this.populateNumberField(fieldWrapper, fieldName, fieldValue);
 				break;
+
 			case 'textarea':
 				if (fieldWrapper.querySelector('.editor-container')) {
 					this.populateEditorField(fieldWrapper, fieldName, fieldValue);
@@ -93,21 +147,315 @@
 	}
 
 	/**
-	 * Determine field type from wrapper element
-	 * @param {HTMLElement} fieldWrapper - Field wrapper element
-	 * @returns {string} Field type
+	 * Populate taxonomy fields with visual display
 	 */
+	populateTaxonomyField(fieldWrapper, fieldName, fieldValue) {
+		// Handle different value formats
+		let termIds = [];
+
+		if (Array.isArray(fieldValue)) {
+			termIds = fieldValue.map(v => String(v));
+		} else if (typeof fieldValue === 'string') {
+			try {
+				const parsed = JSON.parse(fieldValue);
+				termIds = Array.isArray(parsed) ? parsed.map(v => String(v)) : [String(parsed)];
+			} catch (e) {
+				termIds = fieldValue.split(',').map(v => v.trim()).filter(v => v);
+			}
+		} else if (fieldValue) {
+			termIds = [String(fieldValue)];
+		}
+
+		if (termIds.length === 0) {
+			return;
+		}
+
+		// Update hidden input
+		const hiddenInput = fieldWrapper.querySelector(`input[type="hidden"][name="${fieldName}"]`);
+		if (hiddenInput) {
+			hiddenInput.value = termIds.join(',');
+
+			// Trigger TaxonomySelector to update visual display
+			const toggle = fieldWrapper.querySelector('.taxonomy-toggle');
+			if (toggle && toggle.dataset.fieldId && window.jvbTaxonomy) {
+				// Use requestAnimationFrame to ensure DOM is ready
+				requestAnimationFrame(() => {
+					window.jvbTaxonomy.updateFieldFromInput(toggle.dataset.fieldId);
+				});
+			}
+		}
+	}
+
+	/**
+	 * Populate upload fields (images, videos, files)
+	 */
+	populateUploadField(fieldWrapper, fieldName, fieldValue) {
+		// Check if this is a timeline gallery
+		const isTimeline = fieldWrapper.dataset.subtype === 'timeline' || fieldName === 'timeline';
+
+		if (isTimeline) {
+			this.populateTimelineGallery(fieldWrapper, fieldName, fieldValue);
+			return;
+		}
+
+		if (!fieldValue) {
+			return;
+		}
+
+		// Handle comma-separated IDs or single ID
+		const itemIds = this.splitIDs(fieldValue);
+		if (itemIds.length === 0) {
+			return;
+		}
+
+		// Update hidden input
+		const hiddenInput = fieldWrapper.querySelector(`input[type="hidden"][name="${fieldName}"]`);
+		if (hiddenInput) {
+			hiddenInput.value = itemIds.join(',');
+		}
+
+		// Update display grid
+		const grid = fieldWrapper.querySelector('.item-grid');
+		const uploadContainer = fieldWrapper.querySelector('.file-upload-container');
+
+		// Clear existing items first
+		if (grid) {
+			window.removeChildren(grid);
+		}
+
+		fieldWrapper.querySelector('.progress')?.remove();
+
+		if (grid) {
+			itemIds.forEach(itemId => {
+				const template = window.getTemplate('uploadItem');
+				if (!template) {
+					console.warn('uploadItem template not found');
+					return;
+				}
+
+				this.populateUploadItem(template, itemId);
+				grid.append(template);
+			});
+
+			// Hide upload container if items exist
+			if (itemIds.length > 0 && uploadContainer) {
+				uploadContainer.hidden = true;
+			}
+		}
+	}
+
+	/**
+	 * Populate a single upload item
+	 */
+	populateUploadItem(template, itemId) {
+		let input = template.querySelector('input[name="select-item"]');
+		let label = template.querySelector('label[for="select-item"]');
+
+		template.dataset.id = itemId;
+		input.name = `select-item-${itemId}`;
+		input.id = input.name;
+		label.htmlFor = input.name;
+
+		const img = template.querySelector('img');
+		template.querySelector('video')?.remove();
+
+		// Populate with data from item.images
+		if (this.item.images[itemId]) {
+			const data = this.item.images[itemId];
+			if (img) {
+				img.src = data.medium || data.small || data.large || '';
+				img.alt = data['image-alt-text'] || data.alt || '';
+			}
+
+			// Populate metadata fields
+			const titleInput = template.querySelector('[name="image-title"]');
+			const altInput = template.querySelector('[name="image-alt-text"]');
+			const captionInput = template.querySelector('[name="image-caption"]');
+
+			if (titleInput) titleInput.value = data['image-title'] || data.title || '';
+			if (altInput) altInput.value = data['image-alt-text'] || data.alt || '';
+			if (captionInput) captionInput.value = data['image-caption'] || data.caption || '';
+		} else {
+			console.warn(`No image data found for ID: ${itemId}`);
+		}
+
+		// Remove hint if present
+		template.querySelector('details .upload-meta > .hint')?.remove();
+	}
+
+	/**
+	 * Populate timeline gallery - FIXED iteration
+	 */
+	populateTimelineGallery(fieldWrapper, fieldName, fieldValue) {
+		console.log('Populating Timeline Gallery', fieldValue);
+
+		if (!fieldValue || !Array.isArray(fieldValue)) {
+			console.warn('Timeline field value must be an array');
+			return;
+		}
+
+		if (fieldValue.length === 0) {
+			return;
+		}
+
+		const grid = fieldWrapper.querySelector('.item-grid');
+		const uploadContainer = fieldWrapper.querySelector('.file-upload-container');
+
+		// Clear existing items
+		if (grid) {
+			window.removeChildren(grid);
+		}
+
+		fieldWrapper.querySelector('.progress')?.remove();
+
+		if (!grid) return;
+
+		// FIX: Iterate directly over array, not Object.entries
+		for (let itemData of fieldValue) {
+			const template = window.getTemplate('timelineItem');
+			if (!template) {
+				console.warn('timelineItem template not found');
+				continue;
+			}
+
+			const imageId = itemData.post_thumbnail;
+			const postId = itemData.id;
+
+			// Set template data attributes
+			template.dataset.id = imageId;
+			template.dataset.postId = postId;
+
+			// Update selection controls
+			let input = template.querySelector('input[name="select-item"]');
+			let label = template.querySelector('label[for="select-item"]');
+			if (input && label) {
+				input.name = `select-item-${imageId}`;
+				input.id = input.name;
+				label.htmlFor = input.name;
+			}
+
+			// Remove unnecessary elements
+			template.querySelector('video')?.remove();
+			template.querySelector('.select-item span')?.remove();
+
+			// Populate main image
+			const img = template.querySelector('img');
+			const imgData = this.item.images[imageId];
+			if (img && imgData) {
+				img.src = imgData.medium || imgData.small || imgData.large || '';
+				img.title = imgData['image-title'] || '';
+				img.alt = imgData['image-alt-text'] || '';
+			}
+
+			// Populate all fields within the template
+			const fields = template.querySelectorAll('.field');
+			fields.forEach(field => {
+				if (field.classList.contains('group')) {
+					return;
+				}
+
+				const input = field.querySelector('input:not([type="file"]), textarea');
+				if (!input) return;
+
+				const label = field.querySelector('label');
+				const fieldName = input.name.replace('upload_data::', '').replace(/^\[.*?\]/, '');
+
+				// Get value from itemData or imgData
+				let value = itemData[fieldName];
+				if (value === undefined && imgData) {
+					value = imgData[fieldName];
+				}
+
+				// Populate the field using our standard method
+				if (value !== undefined && value !== null) {
+					this.populateField(field, fieldName, value);
+				}
+
+				// Update field identifiers to include post ID
+				const newName = `[${postId}]${fieldName}`;
+				const newId = newName;
+				input.name = newName;
+				input.id = newId;
+				if (label) label.htmlFor = newId;
+			});
+
+			grid.append(template);
+		}
+
+		// Hide upload container if items exist
+		if (fieldValue.length > 0 && uploadContainer) {
+			uploadContainer.hidden = true;
+		}
+	}
+
+	populateTextField(fieldWrapper, fieldName, fieldValue) {
+		const input = fieldWrapper.querySelector(`[name="${fieldName}"], input, textarea`);
+		if (input && input.type !== 'file') {
+			input.value = String(fieldValue || '');
+
+			if (input.dataset.limit) {
+				const counter = fieldWrapper.querySelector('.char-count .current');
+				if (counter) {
+					counter.textContent = input.value.length;
+				}
+			}
+		}
+	}
+
+	populateTextareaField(fieldWrapper, fieldName, fieldValue) {
+		const textarea = fieldWrapper.querySelector(`textarea[name="${fieldName}"]`) ||
+			fieldWrapper.querySelector('textarea:not([data-editor="true"])');
+
+		if (textarea) {
+			textarea.value = String(fieldValue || '');
+			textarea.dispatchEvent(new Event('change', { bubbles: true }));
+
+			if (textarea.dataset.limit) {
+				const counter = fieldWrapper.querySelector('.char-count .current');
+				if (counter) {
+					counter.textContent = textarea.value.length;
+					const limit = parseInt(textarea.dataset.limit, 10);
+					fieldWrapper.classList.toggle('reached', textarea.value.length >= limit);
+				}
+			}
+		}
+	}
+
+	populateEditorField(fieldWrapper, fieldName, fieldValue) {
+		const textarea = fieldWrapper.querySelector(`textarea[name="${fieldName}"][data-editor="true"]`);
+		if (!textarea) return;
+
+		textarea.value = String(fieldValue || '');
+		const editorContainer = fieldWrapper.querySelector('.editor');
+		const content = fieldValue || '<p><br></p>';
+
+		if (editorContainer) {
+			let quillInstance = editorContainer.__quill;
+
+			if (!quillInstance && window.Quill) {
+				for (let instance of (window.Quill.instances || [])) {
+					if (instance.container === editorContainer) {
+						quillInstance = instance;
+						break;
+					}
+				}
+			}
+
+			if (quillInstance) {
+				quillInstance.root.innerHTML = content;
+				editorContainer.__quill = quillInstance;
+			} else {
+				editorContainer.innerHTML = content;
+			}
+		}
+
+		textarea.dispatchEvent(new Event('change', { bubbles: true }));
+	}
+
 	getFieldType(fieldWrapper) {
-		// Check dataset first (most reliable for our use case)
-		if (fieldWrapper.dataset.fieldType) {
-			return fieldWrapper.dataset.fieldType;
-		}
+		if (fieldWrapper.dataset.fieldType) return fieldWrapper.dataset.fieldType;
+		if (fieldWrapper.dataset.type) return fieldWrapper.dataset.type;
 
-		if (fieldWrapper.dataset.type) {
-			return fieldWrapper.dataset.type;
-		}
-
-		// Check for specific field classes
 		const typeClasses = [
 			'upload', 'repeater', 'taxonomy', 'user', 'location',
 			'set', 'checkbox', 'select', 'radio', 'true_false', 'date',
@@ -121,7 +469,6 @@
 			}
 		}
 
-		// Check input type
 		const input = fieldWrapper.querySelector('input, select, textarea');
 		if (input) {
 			if (input.tagName === 'TEXTAREA') {
@@ -136,64 +483,6 @@
 	}
 
 	/**
-	 * Populate text-based fields
-	 */
-	populateTextField(fieldWrapper, fieldName, fieldValue) {
-		const input = fieldWrapper.querySelector(`[name="${fieldName}"], input, textarea`);
-		// Skip file inputs - browsers don't allow setting their values programmatically
-		if (input && input.type === 'file') {
-			return;
-		}
-		if (input) {
-
-			input.value = String(fieldValue || '');
-
-			// Update character counter if present
-			if (input.dataset.limit) {
-				const counter = fieldWrapper.querySelector('.char-count .current');
-				if (counter) {
-					counter.textContent = input.value.length;
-				}
-			}
-		}
-	}
-
-	/**
-	 * Populate textarea fields
-	 */
-	populateTextareaField(fieldWrapper, fieldName, fieldValue) {
-		const textarea = fieldWrapper.querySelector(`textarea[name="${fieldName}"]`) ||
-			fieldWrapper.querySelector('textarea:not([data-editor="true"])');
-
-		if (textarea) {
-			textarea.value = String(fieldValue || '');
-
-			// Trigger change event to update any dependencies
-			textarea.dispatchEvent(new Event('change', { bubbles: true }));
-
-			// Update character counter if present
-			if (textarea.dataset.limit) {
-				const counter = fieldWrapper.querySelector('.char-count .current');
-				if (counter) {
-					counter.textContent = textarea.value.length;
-
-					// Check if limit is reached
-					const limit = parseInt(textarea.dataset.limit, 10);
-					if (textarea.value.length >= limit) {
-						fieldWrapper.classList.add('reached');
-					} else {
-						fieldWrapper.classList.remove('reached');
-					}
-				}
-			}
-		} else {
-			console.warn(`No textarea found for field ${fieldName} in wrapper:`, fieldWrapper);
-		}
-	}
-
-
-
-	/**
 	 * Populate number fields
 	 */
 	populateNumberField(fieldWrapper, fieldName, fieldValue) {
@@ -294,71 +583,6 @@
 	}
 
 	/**
-	 * Populate editor fields (Quill)
-	 */
-	populateEditorField(fieldWrapper, fieldName, fieldValue) {
-		const textarea = fieldWrapper.querySelector(`textarea[name="${fieldName}"]`) ||
-			fieldWrapper.querySelector('textarea[data-editor="true"]') ||
-			fieldWrapper.querySelector('textarea');
-
-		if (!textarea) {
-			console.warn(`Editor field ${fieldName}: textarea not found`);
-			return;
-		}
-
-		const content = String(fieldValue || '');
-
-		// Update the textarea value
-		textarea.value = content;
-
-		// Try to find and update Quill editor
-		const editorContainer = fieldWrapper.querySelector('.editor');
-		if (editorContainer) {
-			// Try different ways to access the Quill instance
-			let quillInstance = null;
-
-			// Method 1: Check if Quill is stored on the editor element
-			if (editorContainer.__quill) {
-				quillInstance = editorContainer.__quill;
-			}
-			// Method 2: Check if Quill is stored as quill property
-			else if (editorContainer.quill) {
-				quillInstance = editorContainer.quill;
-			}
-			// Method 3: Try to find Quill in the global registry (if you have one)
-			else if (window.Quill && window.Quill.find) {
-				quillInstance = window.Quill.find(editorContainer);
-			}
-			// Method 4: Check all Quill instances if available
-			else if (window.Quill && window.Quill.instances) {
-				// Some setups store instances in a registry
-				for (let instance of window.Quill.instances) {
-					if (instance.container === editorContainer) {
-						quillInstance = instance;
-						break;
-					}
-				}
-			}
-
-			if (quillInstance) {
-				// Set the content in Quill
-				quillInstance.root.innerHTML = content;
-				// Store the instance reference for future use
-				editorContainer.__quill = quillInstance;
-			} else {
-				console.warn(`Quill instance not found for ${fieldName}, setting HTML directly`);
-				// Fallback: set HTML directly
-				editorContainer.innerHTML = content;
-			}
-		} else {
-			console.warn(`Editor container not found for ${fieldName}`);
-		}
-
-		// Trigger change event on textarea
-		textarea.dispatchEvent(new Event('change', { bubbles: true }));
-	}
-
-	/**
 	 * Populate location fields
 	 */
 	populateLocationField(fieldWrapper, fieldName, fieldValue) {
@@ -379,36 +603,6 @@
 		});
 	}
 
-	/**
-	 * Populate taxonomy fields
-	 */
-	populateTaxonomyField(fieldWrapper, fieldName, fieldValue) {
-		// Handle different value formats
-		let termIds = [];
-
-		if (Array.isArray(fieldValue)) {
-			termIds = fieldValue.map(v => String(v));
-		} else if (typeof fieldValue === 'string') {
-			try {
-				const parsed = JSON.parse(fieldValue);
-				termIds = Array.isArray(parsed) ? parsed.map(v => String(v)) : [String(parsed)];
-			} catch (e) {
-				termIds = fieldValue.split(',').map(v => v.trim());
-			}
-		} else if (fieldValue) {
-			termIds = [String(fieldValue)];
-		}
-
-		if (termIds.length === 0) {
-			return;
-		}
-
-		// Update hidden input
-		const hiddenInput = fieldWrapper.querySelector(`input[type="hidden"][name="${fieldName}"]`);
-		if (hiddenInput) {
-			hiddenInput.value = termIds.join(',');
-		}
-	}
 
 	/**
 	 * Populate user fields (similar to taxonomy)
@@ -419,181 +613,6 @@
 	}
 
 	/**
-	 * Populate upload fields (images, videos, files)
-	 */
-	populateUploadField(fieldWrapper, fieldName, fieldValue, imagesData = {}) {
-		// Check if this is a timeline gallery
-		const isTimeline = fieldWrapper.dataset.subtype === 'timeline' || fieldName === 'timeline';
-
-		if (isTimeline) {
-			this.populateTimelineGallery(fieldWrapper, fieldName, fieldValue, imagesData);
-			return;
-		}
-
-		if (!fieldValue) {
-			return;
-		}
-
-		// Handle comma-separated IDs or single ID
-		const itemIds = String(fieldValue).split(',').filter(id => parseInt(id.trim()));
-		if (itemIds.length === 0) {
-			return;
-		}
-
-		// Update hidden input
-		const hiddenInput = fieldWrapper.querySelector(`input[type="hidden"][name="${fieldName}"]`);
-		if (hiddenInput) {
-			hiddenInput.value = itemIds.join(',');
-		}
-
-		// Update display grid
-		const grid = fieldWrapper.querySelector('.item-grid');
-		const uploadContainer = fieldWrapper.querySelector('.file-upload-container');
-
-
-		fieldWrapper.querySelector('.progress')?.remove();
-
-		if (grid) {
-			window.removeChildren(grid);
-			itemIds.forEach(itemId => {
-				const template = window.getTemplate('uploadItem');
-
-				if (!template) {
-					console.warn('uploadItem template not found');
-					return;
-				}
-
-				let input = template.querySelector('input[name="select-item"]');
-				let label = template.querySelector('label[for="select-item"]');
-				template.dataset.id = itemId;
-				input.name = input.name + `-${itemId}`;
-				input.id = input.name;
-				label.htmlFor = input.name;
-
-
-				const img = template.querySelector('img');
-
-				template.querySelector('video').remove();
-				const details = template.querySelector('details');
-
-				// Populate with data
-				if (imagesData[itemId]) {
-					const data = imagesData[itemId];
-					if (img) {
-						img.src = data.medium || data.small || data.large || '';
-						img.alt = data['image-alt-text'] || data.alt || '';
-					}
-
-					// Populate metadata fields
-					const titleInput = template.querySelector('[name="image-title"]');
-					const altInput = template.querySelector('[name="image-alt-text"]');
-					const captionInput = template.querySelector('[name="image-caption"]');
-
-					if (titleInput) titleInput.value = data['image-title'] || data.title || '';
-					if (altInput) altInput.value = data['image-alt-text'] || data.alt || '';
-					if (captionInput) captionInput.value = data['image-caption'] || data.caption || '';
-				} else {
-					console.warn('No image data found for ID:', itemId);
-				}
-
-				// Remove hint if present
-				details?.querySelector('.upload-meta > .hint')?.remove();
-
-				grid.append(template);
-			});
-
-			// Hide upload container if items exist
-			if (itemIds.length > 0 && uploadContainer) {
-				uploadContainer.hidden = true;
-			}
-		}
-	}
-
-	populateTimelineGallery(fieldWrapper, fieldName, fieldValue, imagesData) {
-		console.log('populating Timeline Gallery');
-		if (!fieldValue || typeof fieldValue !== 'object') {
-			return;
-		}
-
-		const imageIds = Object.values(fieldValue);
-		if (imageIds.length === 0) {
-			return;
-		}
-
-		// Update display
-		const grid = fieldWrapper.querySelector('.item-grid');
-		const uploadContainer = fieldWrapper.querySelector('.file-upload-container');
-		fieldWrapper.querySelector('.progress')?.remove();
-
-		if (grid) {
-			window.removeChildren(grid);
-			console.log(imageIds);
-			for (let data of Object.entries(fieldValue)) {
-				let imageId = data['post_thumbnail'];
-				const template = window.getTemplate('timelineItem');
-				if (!template) return;
-
-				const img = template.querySelector('img');
-
-				// Remove unnecessary elements
-				template.querySelector('video')?.remove();
-				template.querySelector('.select-item span')?.remove();
-
-				let input = template.querySelector('input[name="select-item"]');
-				let label = template.querySelector('label[for="select-item"]');
-				template.dataset.id = imageId;
-				template.dataset.postId = data.id;
-				input.name = input.name + `-${imageId}`;
-				input.id = input.name;
-				label.htmlFor = input.name;
-
-				const imgData = imagesData[imageId];
-
-				// Set image source
-				if (img && imgData) {
-					img.src = imgData.medium || imgData.small || imgData.large || '';
-					img.title = imgData['image-title'];
-				}
-
-				// Merge data
-				const mergedData = { ...data, ...imgData };
-
-				// Populate fields
-				const fields = template.querySelectorAll('.field');
-				fields.forEach(field => {
-					if (field.classList.contains('group')) {
-						return;
-					}
-
-					const input = field.querySelector('input:not([type="file"]), textarea');
-					if (!input) return;
-
-					const label = field.querySelector('label');
-					const name = input.name.replace('upload_data::', '');
-					const value = mergedData[name];
-
-					// Populate the field
-					this.populateField(field, name, value, imagesData);
-
-					// Update field identifiers
-					const id = data.id;
-					const newName = `[${id}]${name}`;
-					input.name = newName;
-					input.id = newName;
-					if (label) label.htmlFor = newName;
-				});
-
-				grid.append(template);
-			}
-
-			// Hide upload container if items exist
-			if (imageIds.length > 0 && uploadContainer) {
-				uploadContainer.hidden = true;
-			}
-		}
-	}
-
-	/**
 	 * Populate repeater fields
 	 */
 	populateRepeaterField(fieldWrapper, fieldName, fieldValue) {
@@ -680,4 +699,5 @@
 	}
 }
 
+// Make available globally
 window.jvbPopulate = PopulateForm;

--
Gitblit v1.10.0