Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/formsmd/formsmd/llms.txt

Use this file to discover all available pages before exploring further.

Conditional logic enables you to show or hide form fields and slides based on user input. This creates personalized, adaptive forms that only ask relevant questions.

Overview

Forms.md supports two types of conditional logic:
  1. Display conditions - Show/hide individual form fields based on values
  2. Jump conditions - Show/hide entire slides based on values
Both use JavaScript expressions evaluated against form data.
// Display condition: Show field if another field has specific value
composer.textInput("otherRole", {
  question: "Please specify",
  displayCondition: {
    dependencies: ["role"],
    condition: "role == 'Other'"
  }
});

// Jump condition: Show slide if user is adult
composer.slide({
  jumpCondition: "age >= 18"
});

Display conditions

Display conditions control the visibility of individual form fields. Fields are hidden by default when the condition is false.

Basic display condition

src/composer.js
composer.choiceInput("hasCompany", {
  question: "Do you have a company?",
  choices: ["Yes", "No"],
  required: true
});

composer.textInput("companyName", {
  question: "Company name?",
  required: true,
  displayCondition: {
    dependencies: ["hasCompany"],
    condition: "hasCompany == 'Yes'"
  }
});

Display condition structure

The displayCondition parameter accepts an object with two properties:
dependencies
Array<string>
required
Array of form field names that the condition depends on. These fields must be filled before the condition is evaluated.
condition
string
required
JavaScript expression that evaluates to a boolean. Use field names as variables.

Multiple dependencies

Conditions can depend on multiple fields:
composer.numberInput("age", {
  question: "How old are you?",
  required: true
});

composer.choiceInput("hasLicense", {
  question: "Do you have a driver's license?",
  choices: ["Yes", "No"],
  required: true
});

composer.dateInput("licenseExpiry", {
  question: "License expiry date?",
  required: true,
  displayCondition: {
    dependencies: ["age", "hasLicense"],
    condition: "age >= 18 && hasLicense == 'Yes'"
  }
});
All dependencies must have values before the condition is evaluated. Until then, the field remains hidden.

Jump conditions

Jump conditions control the visibility of entire slides. Slides with false jump conditions are automatically skipped during navigation.

Basic jump condition

src/composer.js
composer.choiceInput("userType", {
  question: "Are you a student or professional?",
  choices: ["Student", "Professional"],
  required: true
});

// This slide only shows for students
composer.slide({ 
  jumpCondition: "userType == 'Student'",
  pageProgress: "50%"
});
composer.textInput("university", {
  question: "Which university do you attend?",
  required: true
});

// This slide only shows for professionals
composer.slide({ 
  jumpCondition: "userType == 'Professional'",
  pageProgress: "50%"
});
composer.textInput("company", {
  question: "Which company do you work for?",
  required: true
});

Jump condition syntax

Jump conditions are specified in the slide parameters:
src/composer.js
composer.slide({
  jumpCondition: "expression",  // JavaScript expression
  pageProgress: "50%"
});
The first slide cannot have a jump condition. Jump conditions are only evaluated on subsequent slides.

Condition expressions

Conditions use JavaScript expressions with form field values as variables.

Comparison operators

// Equality
composer.slide({ jumpCondition: "status == 'active'" });
composer.slide({ jumpCondition: "status != 'inactive'" });

// Numeric comparisons
composer.slide({ jumpCondition: "age >= 18" });
composer.slide({ jumpCondition: "score > 50" });
composer.slide({ jumpCondition: "rating <= 3" });

// Logical operators
composer.slide({ 
  jumpCondition: "age >= 18 && hasLicense == 'Yes'" 
});
composer.slide({ 
  jumpCondition: "plan == 'Pro' || plan == 'Enterprise'" 
});

String operations

// String contains
composer.textInput("followup", {
  question: "Tell us more",
  displayCondition: {
    dependencies: ["feedback"],
    condition: "feedback.includes('bug')"
  }
});

// String length
composer.textInput("details", {
  question: "Please provide more details",
  displayCondition: {
    dependencies: ["summary"],
    condition: "summary.length > 0"
  }
});

Array operations (for multiple choice)

composer.choiceInput("interests", {
  question: "Select your interests",
  choices: ["Technology", "Sports", "Music", "Art"],
  multiple: true
});

composer.textInput("favoriteTeam", {
  question: "What's your favorite sports team?",
  displayCondition: {
    dependencies: ["interests"],
    condition: "interests.includes('Sports')"
  }
});
Multiple choice fields (with multiple: true) store values as arrays, so use array methods like includes() in conditions.

Complex conditions

Build sophisticated logic with nested expressions:
composer.numberInput("age", {
  question: "Age?",
  required: true
});

composer.numberInput("income", {
  question: "Annual income?",
  required: true
});

composer.choiceInput("employmentStatus", {
  question: "Employment status?",
  choices: ["Employed", "Self-employed", "Unemployed"],
  required: true
});

// Complex eligibility check
composer.slide({
  jumpCondition: "(age >= 25 && age <= 65) && (income >= 30000 || employmentStatus == 'Self-employed')",
  pageProgress: "75%"
});

composer.textInput("referenceNumber", {
  question: "Enter your reference number",
  required: true
});

Data access in conditions

Conditions can access both form data (user input) and template data (from data blocks).

Form data

Form field values are directly accessible by field name:
composer.textInput("email", { question: "Email?" });

// Access form data
composer.textInput("confirmEmail", {
  question: "Confirm email",
  displayCondition: {
    dependencies: ["email"],
    condition: "email.length > 0"
  }
});

Template data

Data from data blocks is also accessible:
composer.dataBlock({
  minAge: 18,
  maxParticipants: 100
});

composer.numberInput("age", {
  question: "Age?",
  required: true
});

composer.slide({
  jumpCondition: "age >= minAge"  // Uses data from data block
});
Behind the scenes, conditions use Nunjucks templating. The condition is wrapped in {% if condition %} blocks, and dependencies are specified with {$ dependency1 dependency2 $} syntax.

Conditional rendering

When a field’s display condition changes from false to true, Forms.md automatically:
  1. Re-renders the field
  2. Binds event listeners
  3. Restores saved values (if saveState is enabled)
  4. Updates validation state
The rendering happens in the reRenderBindElems method:
src/main.js
formsmd.reRenderBindElems("fieldName");

Complete examples

import { Composer, Formsmd } from "formsmd";

const composer = new Composer({
  id: "feedback",
  postUrl: "/api/feedback"
});

// Initial rating
composer.ratingInput("satisfaction", {
  question: "How satisfied are you?",
  outOf: 5,
  icon: "star",
  required: true
});

// Ask for details if rating is low
composer.textInput("issueDetails", {
  question: "What went wrong?",
  multiline: true,
  required: true,
  displayCondition: {
    dependencies: ["satisfaction"],
    condition: "satisfaction <= 2"
  }
});

// Ask for contact if they want follow-up
composer.choiceInput("wantFollowup", {
  question: "Can we follow up with you?",
  choices: ["Yes", "No"],
  displayCondition: {
    dependencies: ["satisfaction"],
    condition: "satisfaction <= 3"
  }
});

composer.emailInput("email", {
  question: "Your email?",
  required: true,
  displayCondition: {
    dependencies: ["wantFollowup"],
    condition: "wantFollowup == 'Yes'"
  }
});

const formsmd = new Formsmd(
  composer.template,
  document.getElementById("container")
);
formsmd.init();

Implementation details

Under the hood, display conditions generate wrapping <div> elements with Nunjucks conditions:
src/composer.js
::: [{$ dependency1 dependency2 $}]
{% if condition %}
  <!-- Form field here -->
{% endif %}
:::
Jump conditions are stored as data attributes on slides:
src/slides-parse.js
<div class="fmd-slide" data-fmd-jump="condition">
  <!-- Slide content -->
</div>
The getNextSlide() and getPrevSlide() methods in Formsmd evaluate these conditions during navigation to determine which slides to show.

Best practices

1

Keep conditions simple

Use clear, readable conditions. Complex logic can be hard to debug.
2

Specify all dependencies

Always list all fields used in a condition in the dependencies array.
3

Test edge cases

Test conditions with empty values, arrays, and unexpected input.
4

Use jump conditions for major branches

If multiple fields depend on the same condition, consider using a jump condition instead.
5

Consider required fields

Make conditionally shown fields non-required if the condition might not be met.

Troubleshooting

Check that all dependencies are listed and have values. Use browser console to verify condition evaluation.
Verify the jump condition expression syntax. Remember that double quotes in conditions should be single quotes.
For fields with multiple: true, use array methods like includes() instead of equality checks.

Next steps

Slides

Learn more about slide navigation and jump conditions

Composer

Explore all available form fields

Formsmd

Understand form rendering and state management