feat: Clear form element values when hidden

This commit is contained in:
2025-12-27 08:29:49 +01:00
parent 63c373c7f6
commit 6fe20d3746
5 changed files with 84 additions and 8 deletions

View File

@@ -99,10 +99,13 @@ const { stepper, activeStepperItemIndex, stepperItems, currentFormElementSection
computed(() => props.formElementSections) computed(() => props.formElementSections)
) )
const { evaluateVisibility } = useFormElementVisibility() const { evaluateFormElementVisibility } = useFormElementVisibility()
const { clearHiddenFormElementValues } = useFormElementValueClearing()
const { processSpawnTriggers } = useSectionSpawning() const { processSpawnTriggers } = useSectionSpawning()
const { cloneElement } = useClonableElements() const { cloneElement } = useClonableElements()
const previousVisibilityMap = ref<Map<string, boolean>>(new Map())
const allFormElements = computed(() => { const allFormElements = computed(() => {
return props.formElementSections.flatMap( return props.formElementSections.flatMap(
(section) => section.formElementSubSections?.flatMap((subsection) => subsection.formElements) ?? [] (section) => section.formElementSubSections?.flatMap((subsection) => subsection.formElements) ?? []
@@ -110,7 +113,7 @@ const allFormElements = computed(() => {
}) })
const visibilityMap = computed(() => { const visibilityMap = computed(() => {
return evaluateVisibility(allFormElements.value) return evaluateFormElementVisibility(allFormElements.value)
}) })
const visibleSubsections = computed(() => { const visibleSubsections = computed(() => {
@@ -137,6 +140,7 @@ onMounted(() => {
if (props.initialSectionIndex !== undefined) { if (props.initialSectionIndex !== undefined) {
activeStepperItemIndex.value = props.initialSectionIndex activeStepperItemIndex.value = props.initialSectionIndex
} }
previousVisibilityMap.value = visibilityMap.value
}) })
async function handleAddInputForm(position: number, subsectionKey: string) { async function handleAddInputForm(position: number, subsectionKey: string) {
@@ -191,9 +195,22 @@ function handleCloneElement(element: FormElementDto, position: number, subsectio
function handleFormElementUpdate(updatedFormElements: FormElementDto[], subsectionKey: string) { function handleFormElementUpdate(updatedFormElements: FormElementDto[], subsectionKey: string) {
let updatedSections = updateSubsectionElements(props.formElementSections, subsectionKey, updatedFormElements) let updatedSections = updateSubsectionElements(props.formElementSections, subsectionKey, updatedFormElements)
updatedSections = processSpawnTriggers(updatedSections, updatedFormElements) updatedSections = processSpawnTriggers(updatedSections, updatedFormElements)
updatedSections = clearNewlyHiddenFormElements(updatedSections)
emit('update:formElementSections', updatedSections) emit('update:formElementSections', updatedSections)
} }
function clearNewlyHiddenFormElements(sections: FormElementSectionDto[]): FormElementSectionDto[] {
const allElements = sections.flatMap(
(section) => section.formElementSubSections?.flatMap((subsection) => subsection.formElements) ?? []
)
const newVisibilityMap = evaluateFormElementVisibility(allElements)
const clearedSections = clearHiddenFormElementValues(sections, previousVisibilityMap.value, newVisibilityMap)
previousVisibilityMap.value = newVisibilityMap
return clearedSections
}
function getSubsectionKey( function getSubsectionKey(
section: FormElementSectionDto | undefined, section: FormElementSectionDto | undefined,
sectionIndex: number, sectionIndex: number,

View File

@@ -0,0 +1,59 @@
import type { FormElementDto, FormElementSectionDto } from '~~/.api-client'
export function useFormElementValueClearing() {
function clearHiddenFormElementValues(
sections: FormElementSectionDto[],
previousVisibilityMap: Map<string, boolean>,
currentVisibilityMap: Map<string, boolean>
): FormElementSectionDto[] {
const elementsToClean = findNewlyHiddenFormElements(previousVisibilityMap, currentVisibilityMap)
if (elementsToClean.size === 0) {
return sections
}
return sections.map((section) => ({
...section,
formElementSubSections: section.formElementSubSections.map((subsection) => ({
...subsection,
formElements: subsection.formElements.map((element) => {
const key = element.id || element.reference
if (key && elementsToClean.has(key)) {
return clearFormElementValue(element)
}
return element
})
}))
}))
}
function findNewlyHiddenFormElements(
previousMap: Map<string, boolean>,
currentMap: Map<string, boolean>
): Set<string> {
const newlyHidden = new Set<string>()
currentMap.forEach((isVisible, key) => {
const wasVisible = previousMap.get(key) !== false
if (wasVisible && !isVisible) {
newlyHidden.add(key)
}
})
return newlyHidden
}
function clearFormElementValue(element: FormElementDto): FormElementDto {
if (['RADIOBUTTON', 'SELECT', 'CHECKBOX'].includes(element.type)) {
return {
...element,
options: element.options.map((opt) => ({ ...opt, value: 'false' }))
}
}
return {
...element,
options: element.options.map((opt, i) => (i === 0 ? { ...opt, value: '' } : opt))
}
}
return {
clearHiddenFormElementValues
}
}

View File

@@ -2,7 +2,7 @@ import type { FormElementDto, VisibilityConditionOperator } from '~~/.api-client
import { VisibilityConditionOperator as VCOperator, VisibilityConditionType as VCType } from '~~/.api-client' import { VisibilityConditionOperator as VCOperator, VisibilityConditionType as VCType } from '~~/.api-client'
export function useFormElementVisibility() { export function useFormElementVisibility() {
function evaluateVisibility(allFormElements: FormElementDto[]): Map<string, boolean> { function evaluateFormElementVisibility(allFormElements: FormElementDto[]): Map<string, boolean> {
const formElementsByRef = buildFormElementsMap(allFormElements) const formElementsByRef = buildFormElementsMap(allFormElements)
const visibilityMap = new Map<string, boolean>() const visibilityMap = new Map<string, boolean>()
@@ -81,6 +81,6 @@ export function useFormElementVisibility() {
} }
return { return {
evaluateVisibility evaluateFormElementVisibility
} }
} }

View File

@@ -82,7 +82,7 @@ if (applicationFormId) {
const { updateApplicationForm: updateForm, submitApplicationForm } = useApplicationForm() const { updateApplicationForm: updateForm, submitApplicationForm } = useApplicationForm()
const { validateFormElements, getHighestComplianceStatus } = useApplicationFormValidator() const { validateFormElements, getHighestComplianceStatus } = useApplicationFormValidator()
const { evaluateVisibility } = useFormElementVisibility() const { evaluateFormElementVisibility } = useFormElementVisibility()
const { canWriteApplicationForms } = usePermissions() const { canWriteApplicationForms } = usePermissions()
const userStore = useUserStore() const userStore = useUserStore()
const { user } = storeToRefs(userStore) const { user } = storeToRefs(userStore)
@@ -109,7 +109,7 @@ const allFormElements = computed(() => {
}) })
const visibilityMap = computed(() => { const visibilityMap = computed(() => {
return evaluateVisibility(allFormElements.value) return evaluateFormElementVisibility(allFormElements.value)
}) })
watch( watch(

View File

@@ -54,7 +54,7 @@ import { useUserStore } from '~~/stores/useUserStore'
const { getAllApplicationFormTemplates } = useApplicationFormTemplate() const { getAllApplicationFormTemplates } = useApplicationFormTemplate()
const { createApplicationForm, submitApplicationForm } = useApplicationForm() const { createApplicationForm, submitApplicationForm } = useApplicationForm()
const { validateFormElements, getHighestComplianceStatus } = useApplicationFormValidator() const { validateFormElements, getHighestComplianceStatus } = useApplicationFormValidator()
const { evaluateVisibility } = useFormElementVisibility() const { evaluateFormElementVisibility } = useFormElementVisibility()
const { canWriteApplicationForms } = usePermissions() const { canWriteApplicationForms } = usePermissions()
const userStore = useUserStore() const userStore = useUserStore()
const { selectedOrganization } = storeToRefs(userStore) const { selectedOrganization } = storeToRefs(userStore)
@@ -91,7 +91,7 @@ const allFormElements = computed(() => {
}) })
const visibilityMap = computed(() => { const visibilityMap = computed(() => {
return evaluateVisibility(allFormElements.value) return evaluateFormElementVisibility(allFormElements.value)
}) })
watch( watch(