Conditional Fields

Show and hide fields in your publish forms based on conditions and triggers. For example, you may only want to show a caption field if an asset field has an image selected, or a whole block of fields if a toggle switch is enabled.

Overview

Field conditions are set on individual field settings in blueprints. For example, you could create a meta_description field that is only shown when the content field is longer than 140 characters.

Statamic conditional field rule builder
The conditional field rule builder

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.

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
null Will be evaluated as a literal null.
true Will be evaluated as a literal true.
false Will be evaluated as a literal false.
empty Will intelligently check if value is empty.

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 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 root VueX store values by prepending your field 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 }) => {
    //
});
Betterify this page on Github!