Freeform Freeform for Craft

Forms & Fields

Conditional Rules ProImproved in 5.0+

Freeform Pro edition includes Conditional Rules logic that can be added to forms. This feature allows you to effortlessly set fields and groups to show or hide based on the contents/selection of other fields, and even skip pages or submit the form based on the contents/selection of fields on a previous page.

To begin adding rules to your form, click on the Rules tab in the form builder and follow the options.

User Guide:

Quick troubleshooting the most commonly reported issues with your form's appearance, behavior, or submission of the form on the front end.

Overview

Field Layout Map New in 5.0+

For added convenience, Freeform includes a field map along with visual cues. This makes configuration faster and less confusing.

  • A dark gray background shows the field or page that is currently being configured (in the right column).
  • A green border means that the field, group or page has conditional rules configured for it.
  • A green corner border at the top left means that the field, group or page is implicated in another field's conditional rules.
    • E.g. If the Company Name field is configured to only show when the Type field is set to Business, the Type field will display a green corner border.

Adding Rules

Configuring rules for fields, groups and pages is straightforward:

  • To set rules for a field, click on the field name in the left column.
  • To set rules for a Group field, click on the group field name in the left column.
  • To set rules for a page, click on the page name in the left column.

WARNING

Please be cautious about the order of your rules, and be careful not to make any complicated rules that contradict each other.

Available Conditions Improved in 5.0+

The following conditions are available for each field/page:

  • is equal to
  • does not equal
  • greater than
  • greater than or equal to
  • less than
  • less than or equal to
  • contains
  • does not contain
  • starts with
  • ends with
  • is empty
  • is not empty

TIP

Additional Notes

  • Wildcards can be set for criteria values with the asterisk character (*), e.g. cat* will match cat, cats, cat litter, etc.
  • Criteria values/options will automatically display as the following:
    • Text input (where you type out the criteria) for basic text/number field types.
    • Select dropdown (where you select a predefined option as criteria) for multi-option field types such as Checkboxes, Radios, Dropdowns, etc.
    • Checkbox (where you check the checkbox) for single Checkbox field types.

Page Skipping

It is possible to skip pages or submit the form based on the contents/selection of fields on a previous page when using multi-page forms.

Simply configure page skipping the same way you configure fields and groups. If you wish to have the form fully submitted based on some criteria, click on the Submit Form button at the bottom left of the Rules page.

WARNING

Rules cannot be delayed in any way. For example, you can't have a page skip rule on Page 1 that lets you through to Page 2 and Page 3, but skips page 4. The skip is always immediate. If you have Previous buttons enabled for your pages and you have rules that skip pages, the user will technically be able to see skipped pages if they click the Previous button to go back pages.

Eligible Field Types

All field types are eligible to be shown/hidden based on the contents of other field(s). However, some fields cannot be set as criteria:

  • Groups (fields inside of Groups can be set as criteria, but not the group itself)
  • File Upload
  • File Upload Drag & Drop
  • Table
  • Signature
  • Stripe Payment
  • HTML
  • Rich Text

Quick Setup Guide

Finished!

Templating

Freeform will automatically add the necessary attributes and JS to the rendered form. Due to the complex nature of this feature and its reliance on automation, it generally assumes you're automating the render (rather than manually hardcoding each field, etc). All of the Solspace demo templates and sample default formatting templates include this already (and work out of the box).

If you're customizing a formatting template or creating a form template manually, the key is to ensure your field div wrapper contains the data-field-container attribute with the field handle as the value.

There are 3 different approaches you can take:

Approach Benefits Drawbacks
myFieldHandle.renderContainerOpeningTag() Recommended Automatically generates the field wrapper div. Field attributes can still be applied to it. Maximum compatibility with attributes specified in the form builder and template overrides, etc. A bit uglier to look at. Example
myFieldHandle.attributes.container Automatically generates the field wrapper attributes specified in the form builder and template overrides, etc. If the form builder or template overrides contain any of the already hard-coded attributes, it will have no way of knowing and ruin one of the definitions. For example, you hard code in class="form-field", if there are any additional classes specified for the field inside the form builder, it will render as an additional class attribute which will cause issues. Example
data-field-container="myFieldHandle" Minimal template code and looks cleaner. Any attributes set in the form builder or template overrides will not show up. Example

renderContainerOpeningTag Recommended




 



 

 



 

{% set company = form.get("company") %}
{% set email = form.get("email") %}

{{ company.renderContainerOpeningTag({ attributes: { class: "form-field" } }) }}
    {{ company.renderLabel() }}
    {{ company.renderInput() }}
    {{ company.renderErrors() }}
{{ company.renderContainerClosingTag }}

{{ email.renderContainerOpeningTag({ attributes: { class: "form-field" } }) }}
    <label>Email Address</label>
    <input name="email" value="{{ email.value }}" />
    {{ email.renderErrors() }}
{{ email.renderContainerClosingTag }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

attributes.container




 





 





{% set company = form.get("company") %}
{% set email = form.get("email") %}

<div class="form-field" {{ company.attributes.container }}>
    {{ company.renderLabel() }}
    {{ company.renderInput() }}
    {{ company.renderErrors() }}
</div>

<div class="form-field" {{ email.attributes.container }}>
    <label>Email Address</label>
    <input name="email" value="{{ email.value }}" />
    {{ email.renderErrors() }}
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

data-field-container




 





 





{% set company = form.get("company") %}
{% set email = form.get("email") %}

<div class="form-field" data-field-container="company">
    {{ company.renderLabel() }}
    {{ company.renderInput() }}
    {{ company.renderErrors() }}
</div>

<div class="form-field" data-field-container="email">
    <label>Email Address</label>
    <input name="email" value="{{ email.value }}" />
    {{ email.renderErrors() }}
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14