# Data binding

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

```javascript
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 $}.
```

<div><figure><img src="https://824814026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRq8uKg8VhNAvWTRL52uz%2Fuploads%2FpOOvVedTDavDtnnsvDmY%2Finline-data-binding-1.png?alt=media&#x26;token=f1fde098-6c97-4e61-9f18-48f33da930d2" alt=""><figcaption><p>Slide 1 with input</p></figcaption></figure> <figure><img src="https://824814026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRq8uKg8VhNAvWTRL52uz%2Fuploads%2FrC1tSdsej0en8XwUZuTc%2Finline-data-binding-2.png?alt=media&#x26;token=d79f8cad-f903-4c59-920c-35ac3cb5ccca" alt=""><figcaption><p>Slide 2 with inline data binding</p></figcaption></figure></div>

{% hint style="info" %}
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.
{% endhint %}

***

## 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 <a href="#function-overview" id="function-overview"></a>

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[]`                               | The CSS class names of the division element. [See the available CSS utility classes](https://docs.forms.md/content/css-utility-classes).                    |
| `attrs`      | `Array<{ name: string, value: string }>` | Other HTML attributes of the division element. Each attribute has a `name` and `value` property.                                                            |

### Example

Please note, the content inside the `<div>` elements uses [Nunjucks](https://mozilla.github.io/nunjucks/), 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.

```javascript
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 %}

:::
```

<figure><img src="https://824814026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRq8uKg8VhNAvWTRL52uz%2Fuploads%2FoXLB9yI63Axwx4ZfZJjr%2Fblock-data-binding.png?alt=media&#x26;token=e3e1fa4c-ea57-4ff5-80d5-4f69a08bdb8f" alt=""><figcaption><p>Block-level data binding</p></figcaption></figure>

***

## Group together inputs and content using `<div>`

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

### Function overview

```typescript
divStart(params?: object)
divEnd()
```

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

### Example

```javascript
// 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
)

:::
```
