Conditional rendering
Learn how to render almost any part of your forms conditionally.
Element Conditions
We can pass an array
to :conditions
prop of any element:
<template>
<Vueform>
<CheckboxElement name="newsletter" text="Subscribe for newsletter" />
<TextElement
name="Email"
placeholder="Email address"
:conditions="[
['newsletter', '==', true]
]"
>
</Vueform>
</template>
If any of the conditions are failing the element will be invisible, its data will be excluded from requestData
and the element's available
property will become false
.
When a condition is provided as an array
, the first value must be the path
of an other element. The second is an operator that should define the type of comparison. The third is the expected value of the other field.
Available operators:
==
- expect equality!=
- expect inequality>
- expect the other element's value(s) to be higher>=
- expect the other element's value(s) to be higher or equal<
- expect the other element's value(s) to be lower<=
- expect the other element's value(s) to be lower or equalbetween
- expect the other element's value(s) to be between two numbers ([x, y]
)^
- expect the other element's value to start with$
- expect the other element's value to end with*
- expect the other element's value to containin
- expect to be among an array of valuesnot_in
- expect not to be among an array of valuestoday
- expect to be todaybefore
- expect to be before a date (value can be aYYYY-MM-DD
date string ortoday
)after
- expect to be after a date (value can be aYYYY-MM-DD
date string ortoday
)
If we are checking for equality we can leave the operator and pass the expected value as the second param:
<TextElement :conditions="[['newsletter', true]]" ...>
The expected value can also be defined as an array
in which case any of its values will fulfill the condition:
<template>
<SelectElement name="delivery" :items="{
ups: 'UPS',
fedex: 'FedEx',
shop: 'In person'
}" ... />
<TextElement name="phone" :conditions="[
['delivery', ['ups', 'fedex']]
]" ... />
</template>
AND Conditions
When multiple conditions are applied they must all be fulfilled:
<template>
<SelectElement name="delivery" :items="{
ups: 'UPS',
fedex: 'FedEx',
shop: 'In person'
}" ... />
<CheckboxElement name="ask_call" text="Ask for a call" ... />
<!-- `delivery` AND `ask_call` need to satisfy the condition -->
<TextElement name="phone" :conditions="[
['delivery', ['ups', 'fedex']],
['ask_call', true],
]" ... />
</template>
OR Conditions
To use or
type conditions or condition groups we need to wrap our conditions in an extra array:
<template>
<SelectElement name="delivery" :items="{
ups: 'UPS',
fedex: 'FedEx',
shop: 'In person'
}" ... />
<CheckboxElement name="ask_call" text="Ask for a call" ... />
<!-- `delivery` OR `ask_call` need to satisfy the condition -->
<TextElement name="phone" :conditions="[
[
['delivery', ['ups', 'fedex']],
['ask_call', true],
]
]" ... />
</template>
In this case either choosing UPS
or FedEx
will satisfy the condition OR checking Ask for a call
.
We might combine or conditions with and:
<template>
<SelectElement name="delivery" :items="{
ups: 'UPS',
fedex: 'FedEx',
shop: 'In person'
}" ... />
<SelectElement name="payment_method" :items="{
credit_card: 'Credit Card',
wire: 'Wire Transfer',
}" ... />
<CheckboxElement name="ask_call" text="Ask for a call" :conditions="[
[
['delivery', ['ups', 'fedex']],
['payment_method', 'wire'],
]
]" ... />
<!-- `delivery` OR `payment_method` AND `ask_call` need to satisfy the condition -->
<TextElement name="phone" :conditions="[
[
['delivery', ['ups', 'fedex']],
['payment_method', 'wire'],
],
['ask_call', true],
]" ... />
</template>
Either selecting UPS
or FedEx
as delivery option or Wire Transfer
as payment method and checking Ask for a call
will fulfill our condition. Note that in our example Ask for a call
also receives a condition.
We can combine multiple or
condition groups as well:
<!-- `delivery` OR `payment_method` AND `ask_call` OR `some_other_condition` need to satisfy the condition -->
<TextElement name="phone" :conditions="[
[
['delivery', ['ups', 'fedex']],
['payment_method', 'wire'],
],
[
['ask_call', true],
['some_other_condition', 'expected value'],
]
]" ... />
We can also use another AND
group in an OR
group:
<!-- `delivery` OR `a` is greater than `10` AND lower than `20` -->
<TextElement name="phone" :conditions="[
[
['delivery', ['ups', 'fedex']],
[
['a', '>', 10], ['a', '<', 20]
],
],
]" ... />
Functional Conditions
A condition can also be a function
that receives form$
as a first param and el$
as the second if the condition is assigned to an element.
Here's an example of custom functional condition:
<template>
<SelectElement name="delivery" :items="{
ups: 'UPS',
fedex: 'FedEx',
shop: 'In person'
}" ... />
<CheckboxElement name="ask_call" text="Ask for a call" ... />
<TextElement name="phone" :conditions="[
function(form$) {
return ['ups', 'fedex'].indexOf(form$.el$('delivery')?.value) !== -1 ||
form$.el$('ask_call')?.value
}
]" ... />
</template>
Note: some elements might not be returned the time conditions are checked. Therefore it's recommended to use the optional chaning operator (?.) to avoid errors.
Conditions in Nested Elements
We can also apply conditions that point to nested elements by using their path with .
syntax:
<template>
<Vueform>
<GroupElement name="registration">
<CheckboxElement name="newsletter" text="Subscribe for newsletter" />
</GroupElement>
<TextElement
name="Email"
placeholder="Email address"
:conditions="[
['registration.newsletter', true]
]"
>
</Vueform>
</template>
The same dot .
syntax can be used for <ObjectElement>
.
List Conditions
We can reference elements in lists within the same instance using *
:
<template>
<Vueform>
<ListElement name="users">
<template #default="{ index }">
<ObjectElement :name="index">
<TextElement name="name" placeholder="Name" />
<CheckboxElement name="is_admin" text="Has admin rights" />
<CheckboxElement name="can_delete" text="Can delete posts" :conditions="[
['users.*.is_admin', true]
]" />
</ObjectElement>
</template>
</ListElement>
</Vueform>
</template>
Conditions on Form Steps
We can add conditions to FormStep
components:
<template>
<Vueform>
<template #empty>
<FormSteps>
<FormStep label="First" :elements="['first']" />
<FormStep label="Second" :elements="['second']" :conditions="[
['checkbox', true]
]" />
<FormStep label="Third" :elements="['third']" />
</FormSteps>
<TextElement name="first" placeholder="First input">
<TextElement name="second" placeholder="Second input">
<TextElement name="third" placeholder="Third input">
<CheckboxElement name="checkbox" text="Check me" />
<FormStepsControls />
</template>
</Vueform>
</template>
Any element contained in a step with conditions will only be part of requestData
if the step's conditions are fullfilled.
Conditions on Form Tabs
We can also add conditions to FormTab
components:
<template>
<Vueform>
<template #empty>
<FormTabs>
<FormTab label="First" :elements="['first']" />
<FormTab label="Second" :elements="['second']" :conditions="[
['checkbox', true]
]" />
<FormTab label="Third" :elements="['third']" />
</FormTabs>
<TextElement name="first" placeholder="First input">
<TextElement name="second" placeholder="Second input">
<TextElement name="third" placeholder="Third input">
<CheckboxElement name="checkbox" text="Check me" />
</template>
</Vueform>
</template>
Any element contained in a tab with conditions will only be part of requestData
if the tab's conditions are fullfilled.