From 2127b1bdd73ecd2423e443992da4b442f5a3c1a3 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Wed, 04 Feb 2026 21:19:25 +0000
Subject: [PATCH] =Major overhaul of MetaManager.php -> Meta.php and RestRouteManager.php -> Rest.php. Seems to work for JakeVan
---
assets/js/concise/FormController.js | 90 +++++++++++++++++++++++++++++++++++---------
1 files changed, 71 insertions(+), 19 deletions(-)
diff --git a/assets/js/concise/FormController.js b/assets/js/concise/FormController.js
index 9a3f632..07185b6 100644
--- a/assets/js/concise/FormController.js
+++ b/assets/js/concise/FormController.js
@@ -73,7 +73,7 @@
},
tagList: {
tagList: '.field.tag-list', //querySelectorAll
- input: '.tag-input-row',
+ input: '.row',
add: '.add-tag',
remove: '.remove-tag',
label: '.tag-label',
@@ -325,6 +325,7 @@
if (e.target.closest('[data-ignore]') || this.isRestoring) return;
let field = this.getField(e.target);
+
//Dependencies
if (this.dependencies.has(field.dataset.field)) {
let dependency = this.dependencies.get(field.dataset.field);
@@ -333,6 +334,11 @@
});
}
+ if (Object.hasOwn(field.dataset, 'repeater-id') || Object.hasOwn(field.dataset,'tag-list-id')) {
+ this.updateCollectionField(field);
+ return;
+ }
+
let form = this.getForm(e.target);
this.updateItem(field.dataset.field, this.getFieldValue(e.target), form);
}
@@ -377,12 +383,12 @@
if (this.subscribers.size > 0) {
e.preventDefault();
- console.log('Cancelling scheduled backup and manually backing up');
- this.cancelBackup();
- await this.backup();
- const storedData = await this.store.get(form.id);
if (form.options.cache) {
+ this.cancelBackup();
+ await this.backup();
+ const storedData = await this.store.get(form.id);
+
this.notify('form-submit', {
config: form,
data: storedData.changes
@@ -605,8 +611,11 @@
this.removeQuantityListeners(item.element);
break;
}
+
+ if (check.has(item.id)) {
+ check.delete(item.id);
+ }
});
- check.delete(item.id);
}
}
@@ -787,6 +796,7 @@
}
}
checkForRepeaters(form) {
+
if (!form.querySelector(this.selectors.repeater.repeater)) return;
form.querySelectorAll(this.selectors.repeater.repeater).forEach(repeater => {
@@ -799,7 +809,7 @@
sortable: false,
};
- if (!config.ui.addButton) return;
+ if (!config.ui.add) return;
let template = repeater.querySelector('template');
this.templates.define(
@@ -811,8 +821,10 @@
setup({el, refs, manyRefs, data}) {
let index = config.ui.items?.children?.length??0;
el.dataset.index = index;
+
+
manyRefs.inputs?.forEach(input => {
- window.prefixInput(input, `${el.dataset.fieldName}:${index}:`)
+ window.prefixInput(input, `${data.repeater.dataset.fieldName}:${index}:`, el);
});
}
},
@@ -841,13 +853,18 @@
}
handleRepeaterClick(e) {
if (e.target.matches(this.selectors.repeater.add)) {
+ console.log('Add Repeater Row');
this.addRepeaterRow(e.target.closest('[data-repeater-id]'));
} else if (e.target.matches(this.selectors.repeater.remove)) {
- this.removeRepeaterRow(e.target);
+ console.log('Remove Repeater Row');
+ this.removeRepeaterRow(e.target.closest('[data-index]'));
}
}
addRepeaterRow(repeater) {
- repeater.append(this.templates.create(repeater.dataset.repeaterId));
+ let data = {};
+ data.repeater = repeater;
+ repeater.append(this.templates.create(repeater.dataset.repeaterId, data));
+ this.initializeFields(repeater, this.getField(repeater).config??{});
this.a11y.announce('Row added');
}
removeRepeaterRow(row) {
@@ -883,7 +900,8 @@
let index = config.ui.items?.children?.length??0;
el.dataset.index = index;
manyRefs.inputs?.forEach(input => {
- window.prefixInput(input, `${el.dataset.fieldName}:${index}:`)
+ let wrapper = window.closest('.tag-item');
+ window.prefixInput(input, `${el.dataset.fieldName}:${index}:`, wrapper)
});
if (refs.label) {
@@ -977,6 +995,8 @@
config.ui.items.append(newItem);
config.ui.inputs[0]?.focus();
+ this.updateCollectionField(tagList);
+
this.a11y.announce('Item added');
}
removeTagListItem(tag) {
@@ -1179,19 +1199,51 @@
* @param {HTMLElement} container
*/
reindexList(container) {
+ const fieldName = container.dataset.field || container.dataset.repeaterId || container.dataset.tagListId;
+
Array.from(container.children).forEach((item, index) => {
item.dataset.index = `${index}`;
- Array.from(item.children).forEach(child => {
- if (child.type === 'hidden') {
- window.prefixInput(
- child,
- `${container.dataset.field}:${index}:${child.dataset.field}`
- );
- }
+
+ // Find ALL inputs within this item, not just direct children
+ const inputs = item.querySelectorAll('input, select, textarea');
+
+ inputs.forEach(input => {
+ // Skip inputs that shouldn't be re-indexed (like file inputs)
+ if (input.type === 'file') return;
+
+ // Get the field name from the input's data-field or name
+ const inputField = input.dataset.field || input.name.split(':').pop();
+
+ // Re-prefix with the new index, passing item as wrapper
+ window.prefixInput(
+ input,
+ `${fieldName}:${index}:`,
+ item // Pass the item as wrapper for label lookup
+ );
});
});
- //schedule save
+
+ this.updateCollectionField(container);
+ }
+
+ /**
+ * Update the entire repeater/tagList field data
+ * Call this whenever rows are added, removed, or reordered
+ */
+ updateCollectionField(element) {
+ const field = element.closest('[data-field]');
+ if (!field) return;
+
+ const fieldType = field.dataset.fieldType;
+ if (!['repeater', 'tag-list'].includes(fieldType)) return;
+
+ const form = this.getForm(element);
+ if (!form) return;
+
+ // Get all current data for the collection
+ const value = this.getFieldValue(field.querySelector('input, select, textarea'));
+ this.updateItem(field.dataset.field, value, form);
}
/**********************************************************************
VALIDATION
--
Gitblit v1.10.0