Edit this page

API Switching form state

A field with the [up-switch] attribute can control the state of other element when the field changes.

Common effects are showing, hiding or disabling another element. You can also implement custom switching effects.

Showing or hiding other elements

The controlling form field gets an [up-switch] attribute with a selector for the elements to show or hide:

<select name="level" up-switch=".level-dependent">
  <option value="beginner">beginner</option>
  <option value="intermediate">intermediate</option>
  <option value="expert">expert</option>
</select>

The target elements can use [up-show-for] and [up-hide-for] attributes to indicate for which values they should be shown or hidden:

<div class="level-dependent" up-show-for="beginner"> <!-- mark: up-show-for -->
  shown for beginner level, hidden for other levels
</div>

<div class="level-dependent" up-hide-for="beginner"> <!-- mark: up-hide-for -->
  hidden for beginner level, shown for other levels
</div>

By default the entire form will be searched for matches. This can be configured.

To toggle an element for multiple values, separate with a comma:

<div class="level-dependent" up-show-for="intermediate, expert"> <!-- mark: up-show-for -->
  only shown for intermediate and expert levels
</div>

Disabling or enabling fields

The controlling field gets an [up-switch] attribute with a selector for the fields to disable for enable:

<select name="role" up-switch=".role-dependent">
  <option value="trainee">Trainee</option>
  <option value="manager">Manager</option>
</select>

The target elements can use [up-enable-for] and [up-disable-for] attributes to indicate for which values they should be shown or hidden:

<!-- The department field is only shown for managers -->
<input class="role-dependent" name="department" up-enable-for="manager"> <!-- mark: up-enable-for -->

<!-- The mentor field is only shown for trainees -->
<input class="role-dependent" name="mentor" up-disable-for="manager"> <!-- mark: up-disable-for -->

Custom switching effects

[up-switch] allows you to implement your own switching effects. For example, we want a custom [highlight-for] attribute. It draws a bright outline around the department field when the manager role is selected:

<select name="role" up-switch=".role-dependent">
  <option value="trainee">Trainee</option>
  <option value="manager">Manager</option>
</select>

<input class="role-dependent" name="department" highlight-for="manager"> <!-- mark: highlight-for -->

When the role select changes, an up:form:switch event is emitted on all elements matching .role-dependent. We can use this event to implement our custom [highlight-for] effect:

up.on('up:form:switch', '[highlight-for]', (event) => {
  let highlightedValue = event.target.getAttribute('highlight-for')
  let isHighlighted = (event.field.value === highlightedValue)
  event.target.style.highlight = isHighlighted ? '2px solid orange' : ''
})

Tip

To implement asynchronous effects that are rendered on the server, see Reactive server forms.

Switching for multiple values

To switch for multiple values, separate them with a comma:

<div class="level-dependent" up-show-for="intermediate, expert"> <!-- mark: intermediate, expert -->
  only shown for intermediate and expert levels
</div>

If your values might contain spaces, you may also serialize them as a relaxed JSON array:

<div class='level-dependent' up-show-for='["John Doe", "Jane Doe"]'> <!-- mark: ["John Doe", "Jane Doe"] -->
  You selected John or Jane Doe
</div>

Switching on blank or present values

Instead of switching on specific string values, you can use :blank to match an empty input value:

<input type="text" name="user" up-switch=".target"> <!-- mark: :blank -->

<div class="target" up-show-for=":blank">
  please enter a username
</div>

Inversely, :present will match any non-empty input value:

<div class="target" up-hide-for=":present"> <!-- mark: :present -->
  please enter a username
</div>

Usage with checkboxes

For checkboxes you may match against the pseudo-values :checked or :unchecked:

<input type="checkbox" name="flag" up-switch=".flag-dependent">

<div class="flag-dependent" up-show-for=":checked">
  only shown when checkbox is checked
</div>

<div class="flag-dependent" up-show-for=":unchecked">
  only shown when checkbox is unchecked
</div>

You may also match against the [value] attribute of the checkbox element:

<input type="checkbox" name="flag" value="active" up-switch=".flag-dependent">

<div class="flag-dependent" up-show-for="active">
  only shown when checkbox is checked
</div>

Array fields

When you have multiple checkboxes for a single array field, set [up-switch] on an element containing all checkboxes:

<div up-switch=".department-dependent">
  <input type="checkbox" name="department[]" value="development"> Development
  <input type="checkbox" name="department[]" value="sales"> Sales
  <input type="checkbox" name="department[]" value="accounting"> Accounting
</div>

<div class="department-dependent" up-show-for="sales, accounting">
  shown when either sales or accounting is checked
</div>

Usage with radio buttons

Use [up-switch] on a container for a radio button group:

<div up-switch=".level-dependent"> <!-- mark: div -->
  <input type="radio" name="level" value="beginner">
  <input type="radio" name="level" value="intermediate">
  <input type="radio" name="level" value="expert">
</div> <!-- mark: div -->

<div class="level-dependent" up-show-for="beginner">
  shown for beginner level, hidden for other levels
</div>

<div class="level-dependent" up-hide-for="beginner">
  hidden for beginner level, shown for other levels
</div>

Changing the switched region

By default the entire form will be searched for matches. You can narrow or expand the search scope by setting an [up-switch-region] attribute on the controlling field.

To match all elements within the current layer, set the region to :layer:

<form method="post" action="/order">
  <select name="payment" up-switch="#info" up-switch-region=":layer"> <!-- mark: up-switch-region -->
    <option value="paypal">PayPal</option>
    <option value="manual">Manual wire transfer</option>
  </select>
</form>

<div id="info" up-show-for="paypal">
  You will be redirected to PayPal to complete your order.
</div>

<div id="info" up-show-for="manual">
  We will ship your package once we receive your transfer.
</div>

Reacting to different events

By default switch effects are applied for every input event. For example, text fields will switch other elements as the user is typing:

<input type="text" name="user" up-switch=".user-dependent">

<div class="user-dependent" up-show-for="alice">
  only shown for user alice
</div>

You can watch for other events by setting an [up-watch-event] attribute. For example, listening to change will wait until the text field is blurred before applying any switching effects:

<input type="text" name="user" up-switch=".user-dependent" up-watch-event="change"> <!-- mark: up-watch-event -->

When watching a fast-firing event like input, you can debounce the switching effect with an [up-watch-delay] attribute:

<input type="text" name="user" up-switch=".user-dependent" up-watch-event="input" up-watch-delay="150"> <!-- mark: up-watch-delay -->