diff --git a/components/ComponentPreview.vue b/components/ComponentPreview.vue
index bff41e7..60a8293 100644
--- a/components/ComponentPreview.vue
+++ b/components/ComponentPreview.vue
@@ -184,7 +184,8 @@
+ :value="group[field.name]"
+ @input="updateGroupField(component.props.name, groupIndex, field.name, $event)" />
@@ -278,11 +279,12 @@
:checked="isItemSelected(component.props.name, index)"
@change="toggleItemSelection(component.props.name, index)"
class="mr-2 h-4 w-4 rounded border-gray-300" />
-
+ @input="updateListItem(component.props.name, index, $event.target.value)" />
@@ -324,7 +326,7 @@
@@ -646,8 +648,10 @@ onMounted(() => {
const defaultItems = props.component.props.defaultItems;
if ((!currentFormData || currentFormData.length === 0) && defaultItems && defaultItems.length > 0) {
- const updatedData = { ...formStore.previewFormData, [listName]: [...defaultItems] };
- formStore.updatePreviewFormData(updatedData);
+ nextTick(() => {
+ const updatedData = { ...formStore.previewFormData, [listName]: [...defaultItems] };
+ formStore.updatePreviewFormData(updatedData);
+ });
}
}
}
@@ -677,8 +681,10 @@ onMounted(() => {
initialGroups.push(newGroup);
}
- const updatedData = { ...formStore.previewFormData, [groupName]: initialGroups };
- formStore.updatePreviewFormData(updatedData);
+ nextTick(() => {
+ const updatedData = { ...formStore.previewFormData, [groupName]: initialGroups };
+ formStore.updatePreviewFormData(updatedData);
+ });
}
}
}
@@ -690,11 +696,19 @@ watch(() => props.component.props.defaultItems, (newDefaultItems, oldDefaultItem
const listName = props.component.props.name;
if (!listName) return;
+ // Check if defaultItems actually changed to prevent unnecessary updates
+ const newItemsStr = JSON.stringify(newDefaultItems);
+ const oldItemsStr = JSON.stringify(oldDefaultItems);
+
+ if (newItemsStr === oldItemsStr) return;
+
// Always update when defaultItems change, regardless of current form data
const items = newDefaultItems || [];
- const updatedData = { ...formStore.previewFormData, [listName]: [...items] };
- formStore.updatePreviewFormData(updatedData);
+ nextTick(() => {
+ const updatedData = { ...formStore.previewFormData, [listName]: [...items] };
+ formStore.updatePreviewFormData(updatedData);
+ });
}
}, { deep: true, immediate: true });
@@ -702,7 +716,7 @@ watch(() => props.component.props.defaultItems, (newDefaultItems, oldDefaultItem
watch(() => props.component.props.minItems, (newMinItems, oldMinItems) => {
if (props.component.type === 'repeating-group') {
const groupName = props.component.props.name;
- if (!groupName) return;
+ if (!groupName || newMinItems === oldMinItems) return;
const currentGroups = safeGetField(groupName, formStore.previewFormData);
const minItems = newMinItems || 1;
@@ -725,12 +739,51 @@ watch(() => props.component.props.minItems, (newMinItems, oldMinItems) => {
updatedGroups.push(newGroup);
}
- const updatedData = { ...formStore.previewFormData, [groupName]: updatedGroups };
- formStore.updatePreviewFormData(updatedData);
+ nextTick(() => {
+ const updatedData = { ...formStore.previewFormData, [groupName]: updatedGroups };
+ formStore.updatePreviewFormData(updatedData);
+ });
}
}
}, { deep: true, immediate: true });
+// Controlled update methods to prevent circular reactivity
+const updateGroupField = (groupName, groupIndex, fieldName, newValue) => {
+ if (!props.isPreview) return;
+
+ const currentGroups = [...(safeGetField(groupName, formStore.previewFormData) || [])];
+ if (!currentGroups[groupIndex]) return;
+
+ // Only update if value actually changed
+ if (currentGroups[groupIndex][fieldName] === newValue) return;
+
+ currentGroups[groupIndex][fieldName] = newValue;
+
+ nextTick(() => {
+ const updatedData = { ...formStore.previewFormData, [groupName]: currentGroups };
+ formStore.updatePreviewFormData(updatedData);
+ emit('form-data-updated', updatedData);
+ });
+};
+
+const updateListItem = (listName, index, newValue) => {
+ if (!props.isPreview) return;
+
+ const currentItems = [...(safeGetField(listName, formStore.previewFormData) || [])];
+ if (currentItems[index] === newValue) return; // No change
+
+ // Validate and handle duplicates
+ if (!checkDuplicates(listName, newValue, index)) return;
+ if (!validateItem(listName, index, newValue)) return;
+
+ currentItems[index] = newValue;
+
+ nextTick(() => {
+ const updatedData = { ...formStore.previewFormData, [listName]: currentItems };
+ formStore.updatePreviewFormData(updatedData);
+ });
+};
+
// Repeating group and dynamic list functionality
const addGroupItem = () => {
if (!props.isPreview) return;
@@ -1181,13 +1234,48 @@ const updateListItems = (listName, newItems) => {
formStore.updatePreviewFormData(updatedData);
};
+// Get table data safely and initialize if needed
+const getTableData = (tableName) => {
+ if (!tableName) return [];
+
+ // Directly check the form store without using safeGetField to avoid warnings
+ const formData = formStore.previewFormData || {};
+
+ // If field exists and is an array, return it
+ if (formData.hasOwnProperty(tableName) && Array.isArray(formData[tableName])) {
+ return formData[tableName];
+ }
+
+ // If data doesn't exist, initialize it immediately (no nextTick needed for initial render)
+ const initialData = [];
+ const updatedFormData = { ...formData, [tableName]: initialData };
+ formStore.updatePreviewFormData(updatedFormData);
+
+ return initialData;
+};
+
// Update table data for repeating-table component
const updateTableData = (newData) => {
const tableName = props.component.props.name;
if (!tableName) return;
- const updatedFormData = { ...formStore.previewFormData, [tableName]: newData };
- formStore.updatePreviewFormData(updatedFormData);
+ // Ensure newData is always an array
+ const safeNewData = Array.isArray(newData) ? newData : [];
+
+ // Check if data actually changed to prevent unnecessary updates
+ const currentData = safeGetField(tableName, formStore.previewFormData) || [];
+ const currentDataStr = JSON.stringify(currentData);
+ const newDataStr = JSON.stringify(safeNewData);
+
+ if (currentDataStr === newDataStr) return;
+
+ nextTick(() => {
+ const updatedFormData = { ...formStore.previewFormData, [tableName]: safeNewData };
+ formStore.updatePreviewFormData(updatedFormData);
+
+ // Emit the change for workflow page to sync with its local formData
+ emit('form-data-updated', updatedFormData);
+ });
};
// Form Section Component
diff --git a/components/RepeatingTable.vue b/components/RepeatingTable.vue
index bd34e27..397f2dd 100644
--- a/components/RepeatingTable.vue
+++ b/components/RepeatingTable.vue
@@ -70,9 +70,9 @@