LogoLogo
WebsitePricingGitHubSign up
  • Getting started
    • Installation and usage
    • Form settings
    • Options
    • Frequently asked questions
    • Spam protection
    • React
  • Customization
    • Theming
    • Localization
  • Input types
    • Text input
    • Email input
    • URL input
    • Telephone input
    • Password input
    • Number input
    • Select box
    • Choice input
    • Picture choice
    • Rating input
    • Opinion scale / Net Promoter ScoreĀ®
    • Datetime input
    • Date input
    • Time input
    • File input
  • Content
    • Slide
    • Start slide
    • End slide
    • Markdown
    • Data binding
    • CSS utility classes
  • Integrations
    • Google Sheets integration
Powered by GitBook

Ā© 2025 Forms.md | All rights reserved

On this page
  • Inline data binding
  • Example
  • Block-level data binding
  • Function overview
  • Parameters
  • Example
  • Group together inputs and content using <div>
  • Function overview
  • Example

Was this helpful?

  1. Content

Data binding

Bind form field data to content.

Use data binding to create dynamic content in your forms. These functions help you bind form field data to Markdown elements and create conditional content blocks.

Inline data binding

Bind form field data directly within Markdown elements using the {$ field $} syntax.

Example

import { Composer } from "formsmd";

const composer = new Composer({
  id: "my-form"
});

composer.emailInput("email", {
  question: "What's your email address?",
  required: true
});

composer.slide({});

composer.h1("Welcome, {$ email $}!");
composer.p("Order confirmation will be sent to {$ email $}.");

Generates the following Markdown-like syntax:

#! id = my-form

email* = EmailInput(
  | question = What's your email address?
)

---
# Welcome, {$ email $}!

Order confirmation will be sent to {$ email $}.

Inline data binding will also work in the same slide (where the input is). The example above just shows a common use case where the next slide greets the user with their own information.


Block-level data binding

Create dynamic content blocks that respond to multiple form field values. Use the div() function with the bind parameter to specify which form fields to watch.

Function overview

The following is the overview of the function:

div(content: string, params?: object)

Parameters

Name
Type
Description

bind

Array<string>

The names of the form fields to bind to the division (e.g., ["name", "email"]). Any changes to these fields will trigger updates to the division content.

id

string

The id attribute of the division element.

classNames

string[]

attrs

Array<{ name: string, value: string }>

Other HTML attributes of the division element. Each attribute has a name and value property.

Example

composer.numberInput("price", {
  question: "Price",
  required: true,
  unitEnd: "$",
  subfield: true,
  min: 1
});

composer.numberInput("quantity", {
  question: "Quantity",
  required: true,
  subfield: true,
  min: 1
});

composer.div(`
{% if price and quantity -%}
  Total: \${{ price }} Ɨ {{ quantity }} = \${{ price * quantity }}
{% else -%}
  Total: Set price and quantity
{% endif %}
`, {
  classNames: ["fs-lead", "col-8"],
  bind: ["price", "quantity"]
});

Generates the following Markdown-like syntax:

price* = NumberInput(
  | question = Price
  | subfield
  | min = 1
  | unitend = $
)

quantity* = NumberInput(
  | question = Quantity
  | subfield
  | min = 1
)

::: [.fs-lead .col-8 {$ price quantity $}]

{% if price and quantity -%}
  Total: ${{ price }} Ɨ {{ quantity }} = ${{ price * quantity }}
{% else -%}
  Total: Set price and quantity
{% endif %}

:::

Group together inputs and content using <div>

Use divStart() and divEnd() functions to create content groups with shared data bindings or styling.

Function overview

divStart(params?: object)
divEnd()

The parameters for divStart() are the same as the div() function.

Example

// Start a new <div>
composer.divStart({
  classNames: ["col-6"]
});

composer.p("Contact information:");

composer.textInput("name", {
  question: "Full name",
  required: true
});

composer.emailInput("email", {
  question: "Email address",
  required: true
});

// End the <div>
composer.divEnd();

Generates the following Markdown-like syntax:

::: [.col-6]

Contact information:

name* = TextInput(
  | question = Full name
)

email* = EmailInput(
  | question = Email address
)

:::
PreviousMarkdownNextCSS utility classes

Last updated 4 months ago

Was this helpful?

The CSS class names of the division element. .

Please note, the content inside the <div> elements uses , so its entire list of features such as if-else statements, loops, filters, etc. are fully supported. Of course, Markdown is also supported within the content.

Nunjucks
See the available CSS utility classes
Slide 1 with input
Slide 2 with inline data binding
Block-level data binding