Overview
Field conditions are set on individual field settings in blueprints. For example, you could create a meta_description
field that is only shown and submitted when the content
field is longer than 140 characters.
You may specify various rules for showing a field under either the if
/ show_when
keys, or hiding a field under the unless
/ hide_when
keys.
Data Flow
Only visible fields are submitted with your form data. This allows you to control data flow, and conditionally apply validation to visible fields when needed.
If you require conditionally hidden fields to be saved with your data, you may use the always_save
config option (read more about field data flow).
If you want to cosmetically hide a larger set of fields to get them out of the user's way, you can use the Revealer fieldtype to hide them until the user needs them without disrupting data flow on form submission.
Boolean
A simple example might be to show a field when a toggle is set to 'on':
- handle: has_author field: type: toggle- handle: author field: type: text if: has_author: true
Empty
If you need to show a field based on whether another field is empty or not, you can use empty
or not empty
:
- handle: favorite_food field: type: text- handle: second_favorite_food field: type: text if: favorite_food: not empty
Equality
Maybe you might wish to show various fields based on the value of a select field:
- handle: post_type field: type: select options: - text - video- handle: content field: type: text if: post_type: text- handle: youtube_id field: type: text if: post_type: video
Contains
If you are dealing with an array of options, you can conditionally show fields when an array contains specific value(s) using contains
or contains_any
:
- handle: favorite_foods field: type: checkboxes options: - pizza - lasagna - oatmeal- handle: favorite_topping field: type: text if: favorite_foods: 'contains pizza'- handle: favorite_italian_singer field: type: text if: favorite_foods: 'contains_any pizza, lasagna'
If you are dealing with a string value, contains
and contains_any
will perform sub-string checks instead:
- handle: favorite_food field: type: text- handle: favorite_topping field: type: text if: favorite_food: 'contains pizza'- handle: favorite_italian_singer field: type: text if: favorite_food: 'contains_any pizza, lasagna'
Advanced Comparisons
For more advanced comparisons, several operators and right-hand-side literals/options are available to you. For example, we could show an email
field if age is greater than or equal to 16
:
- handle: age field: type: text- handle: email field: type: text if: age: '>= 16'
Available operators include:
Operator | Description |
---|---|
is equals == |
Loose equality comparison (inferred if no operator is used). |
not isnt != |
Loose inequality comparison. |
=== |
Strict equality comparison. |
!== |
Strict inequality comparison. |
> |
Greater than comparison. |
>= |
Greater than or equal to comparison. |
< |
Less than comparison. |
<= |
Less than or equal to comparison. |
contains includes |
Check if array contains a value, or if a string contains a sub-string value. |
contains_any includes_any |
Check if array contains any of a comma-separated list of values, or if a string contains any of a comma-separated list of sub-strings values. |
Available right-hand-side literals/options include:
Literal / Option | Description |
---|---|
empty |
Will intelligently check if value is empty (ie. null , '' , [] , or {} ). |
null |
Will be evaluated as a literal null . |
true |
Will be evaluated as a literal true . |
false |
Will be evaluated as a literal false . |
Multiple Conditions
If you define multiple field conditions, all conditions need to pass for the field to be shown (or hidden if you use the unless
/ hide_when
parent key). For example, the following will show the field when this_field
is bacon
AND that_field
is cheeseburger
:
if: this_field: bacon that_field: cheeseburger
If you want to show a field when any of the conditions pass, you can append _any
onto the parent key. For example, the following will show the field when this_field
is bacon
OR that_field
is cheeseburger
:
if_any: this_field: bacon that_field: cheeseburger
Nested Fields
You may use dot notation to access nested values when necessary. For example, maybe you would like to show a field when an array
fieldtype's country
value is Canada
:
if: address.country: Canada
Field Context
By default, conditions are performed against values in the current level of fields
in your blueprint. If you need access to values outside of this context (eg. if you are in a replicator, trying to compare against fields outside of the replicator), you can access parent field values by prepending your field with $parent
:
if: $parent.favorite_foods: includes bacon
You can also access values at the top-level of your blueprint with $root
:
if: $root.favorite_foods: includes bacon
Custom Logic
If you need something more complex than the YAML syntax provides, you may write your own logic. In a JS script or addon, you can define custom functions using the $conditions
JS API:
if: quote: custom isCanadian
Statamic.$conditions.add('isCanadian', ({ target }) => { return new RegExp('eh|bud|hoser').test(target);});
Parameters
You may also pass parameters to your custom functions:
if: hero_video_url: 'custom isFiletype:mp4' hero_image_url: 'custom isFiletype:jpg,png'
Statamic.$conditions.add('isFiletype', ({ target, params }) => { return new RegExp(params.join('|') + '$').test(target);});
Without Target
If you need to perform a condition against multiple hardcoded values, you can bypass setting a target field in the yaml by referencing your function name at the top of your if
condition:
if: reallyLovesFood
Statamic.$conditions.add('reallyLovesFood', ({ values }) => { return (values.meals.length + values.desserts.length) > 10;});
Field Context
Furthermore, if you need access to values outside of the current field context, we also provide a root
values parameter, as well as access to the VueX store via store
and storeName
:
Statamic.$conditions.add('...', ({ root, store, storeName }) => { //});
Validation
If you wish to conditionally apply validation to conditionally shown fields, we recommend using the sometimes
Laravel validation rule.
- handle: online_event field: type: toggle- handle: venue field: type: text if: online_event: false validate: - sometimes - required
The above example will only sometimes apply the required
rule to the venue
field; Only when it exists in the submitted form data (see notes on data flow above).
For more advanced conditional validation, take a look at Laravel's required_if
, required_with
, etc. validation rules.
Templating
You can take advantage of Conditional Fields on your front-end Forms to automatically generate dynamic forms and logic. Learn more about it.