updated form
This commit is contained in:
parent
fb81306a68
commit
82646cf6a9
@ -33,7 +33,6 @@ const handleError = () => {
|
|||||||
<div class="min-h-screen bg-gray-50 flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
<div class="min-h-screen bg-gray-50 flex flex-col items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
|
||||||
<div class="max-w-md w-full space-y-8">
|
<div class="max-w-md w-full space-y-8">
|
||||||
<div>
|
<div>
|
||||||
<img src="@/assets/img/logo/logo-word.svg" alt="Corrad Logo" class="h-12 mx-auto" />
|
|
||||||
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
||||||
{{ error.statusCode === 404 ? 'Page not found' : 'An error occurred' }}
|
{{ error.statusCode === 404 ? 'Page not found' : 'An error occurred' }}
|
||||||
</h2>
|
</h2>
|
||||||
|
@ -35,7 +35,14 @@
|
|||||||
<div class="bg-white rounded-lg shadow p-6">
|
<div class="bg-white rounded-lg shadow p-6">
|
||||||
<div v-for="(form, index) in forms" :key="`content-${index}`" v-show="activeTabIndex === index">
|
<div v-for="(form, index) in forms" :key="`content-${index}`" v-show="activeTabIndex === index">
|
||||||
<h2 class="text-xl font-semibold mb-4">{{ form.formName || `Form ${index + 1}` }}</h2>
|
<h2 class="text-xl font-semibold mb-4">{{ form.formName || `Form ${index + 1}` }}</h2>
|
||||||
<p class="text-gray-600 mb-4">{{ form.description || 'Please complete this form step' }}</p>
|
<p class="text-gray-600 mb-1">{{ form.description || 'Please complete this form step' }}</p>
|
||||||
|
|
||||||
|
<!-- Conditional Logic Engine -->
|
||||||
|
<ConditionalLogicEngine
|
||||||
|
:form-components="form.formComponents"
|
||||||
|
:form-data="formData[index]"
|
||||||
|
@script-generated="handleScriptGenerated"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Form content -->
|
<!-- Form content -->
|
||||||
<FormKit
|
<FormKit
|
||||||
@ -187,9 +194,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, computed } from 'vue'
|
import { onMounted, ref, computed, watch, nextTick } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import RsButton from '~/components/RsButton.vue'
|
import RsButton from '~/components/RsButton.vue'
|
||||||
|
import ConditionalLogicEngine from '~/components/ConditionalLogicEngine.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const error = ref(null)
|
const error = ref(null)
|
||||||
@ -238,6 +246,178 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utility functions for conditional logic
|
||||||
|
const getField = (fieldName) => {
|
||||||
|
const currentFormData = formData.value[activeTabIndex.value] || {}
|
||||||
|
return currentFormData[fieldName]
|
||||||
|
}
|
||||||
|
|
||||||
|
const showField = (fieldName) => {
|
||||||
|
const field = document.querySelector(`[name="${fieldName}"]`)
|
||||||
|
if (field) {
|
||||||
|
const outerDiv = field.closest('.formkit-outer')
|
||||||
|
if (outerDiv) {
|
||||||
|
outerDiv.style.display = ''
|
||||||
|
outerDiv.classList.remove('hidden')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideField = (fieldName) => {
|
||||||
|
const field = document.querySelector(`[name="${fieldName}"]`)
|
||||||
|
if (field) {
|
||||||
|
const outerDiv = field.closest('.formkit-outer')
|
||||||
|
if (outerDiv) {
|
||||||
|
outerDiv.style.display = 'none'
|
||||||
|
outerDiv.classList.add('hidden')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const enableField = (fieldName) => {
|
||||||
|
const field = document.querySelector(`[name="${fieldName}"]`)
|
||||||
|
if (field) {
|
||||||
|
field.removeAttribute('disabled')
|
||||||
|
const outerDiv = field.closest('.formkit-outer')
|
||||||
|
if (outerDiv) {
|
||||||
|
outerDiv.classList.remove('opacity-50', 'pointer-events-none')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const disableField = (fieldName) => {
|
||||||
|
const field = document.querySelector(`[name="${fieldName}"]`)
|
||||||
|
if (field) {
|
||||||
|
field.setAttribute('disabled', 'disabled')
|
||||||
|
const outerDiv = field.closest('.formkit-outer')
|
||||||
|
if (outerDiv) {
|
||||||
|
outerDiv.classList.add('opacity-50', 'pointer-events-none')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onFieldChange = (fieldName, callback) => {
|
||||||
|
const field = document.querySelector(`[name="${fieldName}"]`)
|
||||||
|
if (field) {
|
||||||
|
// Remove existing listeners first to prevent duplicates
|
||||||
|
field.removeEventListener('change', callback)
|
||||||
|
field.removeEventListener('input', callback)
|
||||||
|
// Add new listeners
|
||||||
|
field.addEventListener('change', callback)
|
||||||
|
field.addEventListener('input', callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to evaluate and apply conditional logic for all fields
|
||||||
|
const evaluateAllFieldConditions = () => {
|
||||||
|
const currentForm = forms.value[activeTabIndex.value]
|
||||||
|
if (!currentForm?.formComponents) return
|
||||||
|
|
||||||
|
currentForm.formComponents.forEach(component => {
|
||||||
|
if (component.props?.conditionalLogic?.enabled) {
|
||||||
|
const { conditions, action, operator = 'and' } = component.props.conditionalLogic
|
||||||
|
const fieldName = component.props.name
|
||||||
|
|
||||||
|
// Evaluate all conditions
|
||||||
|
const results = conditions.map(condition => {
|
||||||
|
const fieldValue = getField(condition.field)
|
||||||
|
|
||||||
|
switch (condition.operator) {
|
||||||
|
case 'equals':
|
||||||
|
return fieldValue === condition.value
|
||||||
|
case 'not_equals':
|
||||||
|
return fieldValue !== condition.value
|
||||||
|
case 'contains':
|
||||||
|
return String(fieldValue || '').includes(condition.value)
|
||||||
|
case 'not_contains':
|
||||||
|
return !String(fieldValue || '').includes(condition.value)
|
||||||
|
case 'is_empty':
|
||||||
|
return !fieldValue || fieldValue === ''
|
||||||
|
case 'is_not_empty':
|
||||||
|
return fieldValue && fieldValue !== ''
|
||||||
|
case 'greater_than':
|
||||||
|
return Number(fieldValue) > Number(condition.value)
|
||||||
|
case 'less_than':
|
||||||
|
return Number(fieldValue) < Number(condition.value)
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Check if conditions are met based on operator
|
||||||
|
const conditionsMet = operator === 'and'
|
||||||
|
? results.every(result => result)
|
||||||
|
: results.some(result => result)
|
||||||
|
|
||||||
|
// Apply visibility/state based on conditions
|
||||||
|
if (conditionsMet) {
|
||||||
|
if (action === 'show') showField(fieldName)
|
||||||
|
else if (action === 'hide') hideField(fieldName)
|
||||||
|
else if (action === 'enable') enableField(fieldName)
|
||||||
|
else if (action === 'disable') disableField(fieldName)
|
||||||
|
} else {
|
||||||
|
if (action === 'show') hideField(fieldName)
|
||||||
|
else if (action === 'hide') showField(fieldName)
|
||||||
|
else if (action === 'enable') disableField(fieldName)
|
||||||
|
else if (action === 'disable') enableField(fieldName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch for form data changes to re-evaluate conditional logic
|
||||||
|
watch(() => formData.value[activeTabIndex.value], () => {
|
||||||
|
nextTick(() => {
|
||||||
|
evaluateAllFieldConditions()
|
||||||
|
})
|
||||||
|
}, { deep: true })
|
||||||
|
|
||||||
|
// Watch for active tab changes to re-evaluate conditional logic
|
||||||
|
watch(activeTabIndex, () => {
|
||||||
|
nextTick(() => {
|
||||||
|
evaluateAllFieldConditions()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Watch for forms data to initialize conditional logic
|
||||||
|
watch(forms, (newForms) => {
|
||||||
|
if (newForms.length > 0) {
|
||||||
|
nextTick(() => {
|
||||||
|
evaluateAllFieldConditions()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// Handle script generated from ConditionalLogicEngine
|
||||||
|
const handleScriptGenerated = (script) => {
|
||||||
|
if (!script) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create a function with access to our utility functions
|
||||||
|
const evalScript = new Function(
|
||||||
|
'getField',
|
||||||
|
'showField',
|
||||||
|
'hideField',
|
||||||
|
'enableField',
|
||||||
|
'disableField',
|
||||||
|
'onFieldChange',
|
||||||
|
script
|
||||||
|
)
|
||||||
|
|
||||||
|
// Execute the script with our utility functions
|
||||||
|
evalScript(
|
||||||
|
getField,
|
||||||
|
showField,
|
||||||
|
hideField,
|
||||||
|
enableField,
|
||||||
|
disableField,
|
||||||
|
onFieldChange
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error executing conditional logic script:', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle form submission
|
// Handle form submission
|
||||||
const handleSubmit = async (formIndex) => {
|
const handleSubmit = async (formIndex) => {
|
||||||
try {
|
try {
|
||||||
@ -283,8 +463,21 @@
|
|||||||
forms.value = response.forms
|
forms.value = response.forms
|
||||||
console.log(response.forms)
|
console.log(response.forms)
|
||||||
|
|
||||||
// Initialize formData array with empty objects for each form
|
// Initialize formData array with default values for each form
|
||||||
formData.value = forms.value.map(() => ({}))
|
formData.value = forms.value.map(form => {
|
||||||
|
const defaultData = {};
|
||||||
|
|
||||||
|
// Set default values for form fields
|
||||||
|
form.formComponents?.forEach(component => {
|
||||||
|
// For select fields with options, set first option as default
|
||||||
|
if (component.type === 'select' && component.props.options?.length > 0) {
|
||||||
|
defaultData[component.props.name] = component.props.options[0].value;
|
||||||
|
}
|
||||||
|
// Add more default value logic for other field types if needed
|
||||||
|
});
|
||||||
|
|
||||||
|
return defaultData;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -311,11 +504,11 @@
|
|||||||
.grid-preview-container {
|
.grid-preview-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(12, 1fr);
|
grid-template-columns: repeat(12, 1fr);
|
||||||
gap: 1rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-preview-container > div {
|
.grid-preview-container > div {
|
||||||
grid-column: span 12;
|
grid-column: span 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply width classes */
|
/* Apply width classes */
|
||||||
|
@ -168,6 +168,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
timeline: caseInstance.timeline
|
timeline: caseInstance.timeline
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(`response.forms: ${JSON.stringify(response.forms)}`);
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
...response
|
...response
|
||||||
|
Loading…
x
Reference in New Issue
Block a user