# Controlling the flow with conditions and logic

Conditional logic allows you to create dynamic, personalized flows without duplicating efforts across multiple form versions. You can use logic to control when certain elements appear based on responder inputs.

Logic can be applied to:

* [Questions](https://docs.formsort.com/adding-questions-and-content/question-reference), [Steps](https://docs.formsort.com/creating-flows/building-a-new-flow/steps), or [Groups](https://docs.formsort.com/creating-flows/building-a-new-flow/organizing-using-groups) &#x20;
* [Redirects](https://docs.formsort.com/redirects-and-endings#redirects)
* [Calculated variables](https://docs.formsort.com/response-data-collection-and-management/variable-schema/calculated-answers)&#x20;
* [API variables](https://docs.formsort.com/response-data-collection-and-management/variable-schema/api-answers)

***

### Content order and conditional logic

Responders experience the flow according to the step order defined in the Content Editor—from Step 0 onward. Conditional logic doesn’t override this order, but it can hide or reveal elements based on logic that evaluates to **true** or **false**.

* If the logic evaluates to **true**, the element is shown.
* If it evaluates to **false**, the element is hidden.

{% hint style="warning" %}
**Important:** Logic does not *skip* responders to other steps. For example, applying logic to Step 30 will not cause the user to jump there from Step 1—they must progress sequentially unless explicitly redirected.
{% endhint %}

**Example flow:**

<figure><img src="https://1036686854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJPnL__mOdr_mLZ8nwf%2Fuploads%2FdHk35ut0Pa2ZCQRfSLec%2Fimage.png?alt=media&#x26;token=96ff8287-c32f-4f7d-bbee-683dad1c5584" alt=""><figcaption></figcaption></figure>

Step 1: *Do you have a cat or a dog?*

* If the responder selects **Cat**: logic on Step 2 evaluates to true → Step 2 is shown, Step 3 is hidden.
* If the responder selects **Dog**: logic on Step 2 evaluates to false → Step 2 is hidden, Step 3 is shown.

This simple pattern allows you to branch the experience without creating a separate flow.

### Simple logic editor

The **Simple Logic Editor** enables basic conditional rendering using one or more logical arguments.

Each condition consists of:

* A **variable** (e.g., answer, external variable)
* A **logical operator** (see the [operator reference](#logical-operator-reference) below)
* A **target value** to compare against

<figure><img src="https://1036686854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJPnL__mOdr_mLZ8nwf%2Fuploads%2FZqnATv4cybXgouNxmz19%2Fimage.png?alt=media&#x26;token=6d2fb704-39cb-4e9e-9024-e7b81279e31c" alt=""><figcaption><p>Using the simple logic editor to conditionally render the first step</p></figcaption></figure>

{% hint style="warning" %}
Logic can only reference variables that are already defined earlier in the flow.\
You cannot apply logic to Step 1 based on a value defined in Step 3.
{% endhint %}

You can:

* Add multiple conditions using **+ Add condition**
* Group conditions using **+ Add group** for more complex logic

<figure><img src="https://1036686854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJPnL__mOdr_mLZ8nwf%2Fuploads%2FjP5vCjVMtzkWU4Q3bqrT%2Fimage.png?alt=media&#x26;token=a29f852e-7523-4ed4-9da2-48f174830068" alt=""><figcaption><p>Creating a two-argument AND statement in the logic editor</p></figcaption></figure>

If you find yourself needing more flexibility, consider using [calculated variables](https://docs.formsort.com/response-data-collection-and-management/variable-schema/calculated-answers) or the advanced logic editor.

### Advanced logic

Advanced logic allows you to create boolean expressions across multiple answers using a freeform logic editor.

For even more control, use a **calculated variable** that returns a `true` or `false` value using TypeScript. This boolean value can then be referenced by simple logic elsewhere in the flow.

![](https://1036686854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJPnL__mOdr_mLZ8nwf%2Fuploads%2FP7ShEHVjIEj0EGObIc95%2Fsimple%20logic2.png?alt=media\&token=a2723a06-5621-43fa-b46f-9e0418758385)

***

### Optional?

By default, Formsort flows require all questions to be answered before moving forward. Toggling on **Optional?** allows responders to skip a question.

***

### Logical operator reference&#x20;

Logical operators evaluate expressions to determine whether a question, step, or group should be enabled.

<figure><img src="https://1036686854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJPnL__mOdr_mLZ8nwf%2Fuploads%2FTkXJY0ANbsLd4OyYB89Q%2Fimage.png?alt=media&#x26;token=61077c6c-0586-4f5e-8cf9-285ff602a53d" alt=""><figcaption></figcaption></figure>

| Operator                              | Description                                                                   |
| ------------------------------------- | ----------------------------------------------------------------------------- |
| **Equals**                            | The value exactly matches the expected value.                                 |
| **Does not equal**                    | The value does not match. Also true if the value is undefined.                |
| **Greater than**                      | The value is greater than the expected value. *(Numbers only)*                |
| **Less than**                         | The value is less than the expected value. *(Numbers only)*                   |
| **Matches regular expression**        | The value matches the regex pattern.                                          |
| **Does not match regular expression** | The value does not match the regex pattern.                                   |
| **Is defined on load**                | The value was set via URL param, POST body, or similar on form load.          |
| **Is defined**                        | Any value (including `false`) is present. Useful for gating logic.            |
| **Is not defined**                    | The value has not been set.                                                   |
| **Had a loading error**               | The value couldn’t be loaded or computed due to an error (e.g., API failure). |
