How do I show or hide fields based on other answers?
In Formhaus you add show (all conditions must match) or showAny (at least one must match) to a field in the JSON definition. The FormEngine re-evaluates visibility on every change, clears the values of fields that become hidden, and skips hidden fields in validation and submission. The React and Vue renderers apply this without extra code.
Definition
A checkout form: company name for business buyers, an invoice email for business buyers or individuals who ask for an invoice, and an address or pickup point depending on delivery.
json
{
"$schema": "https://formhaus.dev/schema/form-definition.json",
"id": "checkout-details",
"title": "Checkout details",
"submit": { "label": "Continue to payment" },
"fields": [
{
"key": "customerType",
"type": "radio",
"label": "Buying as",
"defaultValue": "personal",
"options": [
{ "value": "personal", "label": "Individual" },
{ "value": "business", "label": "Business" }
]
},
{
"key": "companyName",
"type": "text",
"label": "Company name",
"show": [{ "field": "customerType", "eq": "business" }],
"validation": { "required": true }
},
{
"key": "needInvoice",
"type": "checkbox",
"label": "Send me an invoice",
"show": [{ "field": "customerType", "eq": "personal" }]
},
{
"key": "invoiceEmail",
"type": "email",
"label": "Invoice email",
"showAny": [
{ "field": "customerType", "eq": "business" },
{ "field": "needInvoice", "eq": true }
],
"validation": { "required": true }
},
{
"key": "delivery",
"type": "radio",
"label": "Delivery",
"validation": { "required": true },
"options": [
{ "value": "courier", "label": "Courier" },
{ "value": "pickup", "label": "Pickup point" }
]
},
{
"key": "address",
"type": "textarea",
"label": "Delivery address",
"rows": 3,
"show": [{ "field": "delivery", "eq": "courier" }],
"validation": { "required": true }
},
{
"key": "pickupPoint",
"type": "select",
"label": "Pickup point",
"show": [{ "field": "delivery", "eq": "pickup" }],
"validation": { "required": true },
"options": [
{ "value": "central", "label": "Central station" },
{ "value": "north", "label": "North mall" }
]
}
]
}React
tsx
import { FormRenderer } from '@formhaus/react';
import type { FormDefinition } from '@formhaus/core';
import checkout from './checkout-details.json';
const definition = checkout as FormDefinition;
export function CheckoutDetails({ onDone }: { onDone: (values: Record<string, unknown>) => void }) {
return <FormRenderer definition={definition} onSubmit={onDone} />;
}Vue
vue
<script setup lang="ts">
import { FormRenderer } from '@formhaus/vue';
import type { FormDefinition } from '@formhaus/core';
import checkout from './checkout-details.json';
const definition = checkout as FormDefinition;
const emit = defineEmits<{ done: [values: Record<string, unknown>] }>();
</script>
<template>
<FormRenderer :definition="definition" @submit="(values) => emit('done', values)" />
</template>How it works
companyNamehasshow: [{ "field": "customerType", "eq": "business" }]and appears only for business buyers.invoiceEmailusesshowAny: it appears whencustomerTypeisbusinessor whenneedInvoiceistrue.addressandpickupPointdepend ondelivery. Only one of them is visible at a time, so only one is required.- Switching from Business to Individual hides
companyNameand removes its value from the engine. Switching back shows an empty field. - Cleanup cascades. Switching from Individual to Business hides
needInvoiceand clears it;invoiceEmailstays because its business condition still matches. - Hidden fields are not validated. A required
pickupPointdoes not block submit while Courier is selected. onSubmitreceives only visible values. Operators areeq,neq,in,notInandnotEmpty.- Steps accept the same
showandshowAnykeys. A hidden step is skipped and drops out of the progress count.
Related
- Conditional Fields: operators, AND/OR rules and conditional submit buttons
- Multi-step branching: route between steps with the same conditions
- Definition Reference: the
ShowConditiontype - FormEngine:
setValue,validateandgetSubmitValues