> For the complete documentation index, see [llms.txt](https://docs.forms.md/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forms.md/input-types/picture-choice.md).

# Picture choice

<figure><img src="/files/ZDlxCEij8apFy4hAfUqM" alt=""><figcaption><p>Picture choice</p></figcaption></figure>

Use the `pictureChoice()` function to create picture choice inputs in your forms. It allows users to select one or more options from a list of choices with associated images.

***

## Basic usage

```javascript
import { Composer } from "formsmd";

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

composer.pictureChoice("style", {
  question: "Choose your preferred style",
  choices: [
    { label: "Modern", value: "modern", image: "/styles/modern.jpg" },
    { label: "Classical", value: "classical", image: "/styles/classical.jpg" },
    { label: "Minimalist", value: "minimalist", image: "/styles/minimalist.jpg" }
  ]
});
```

Generates the following Markdown-like syntax:

```
#! id = my-form

style = PictureChoice(
  | question = Choose your preferred style
  | choices = "modern" Modern && /styles/modern.jpg, "classical" Classical && /styles/classical.jpg, "minimalist" Minimalist && /styles/minimalist.jpg
)
```

### Required

Add the `required` parameter to make the field mandatory:

```javascript
composer.pictureChoice("style", {
  question: "Choose your preferred style",
  choices: [
    { label: "Modern", value: "modern", image: "/styles/modern.jpg" },
    { label: "Classical", value: "classical", image: "/styles/classical.jpg" },
    { label: "Minimalist", value: "minimalist", image: "/styles/minimalist.jpg" }
  ],
  required: true
});
```

Generates the following Markdown-like syntax:

```
style* = PictureChoice(
  | question = Choose your preferred style
  | choices = "modern" Modern && /styles/modern.jpg, "classical" Classical && /styles/classical.jpg, "minimalist" Minimalist && /styles/minimalist.jpg
  | required
)
```

***

## Function overview

The following is the overview of the function:

```typescript
pictureChoice(name: string, params: object)
```

### Arguments

| Name     | Type     | Description                                                                                                                                                         |
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`   | `string` | A unique name for your form field that you'll use to identify the user's response.<mark style="color:red;">\*</mark>                                                |
| `params` | `object` | An object containing all the configuration parameters for your picture choice field (see the [parameters section](#parameters) below for the full list of options). |

{% hint style="danger" %} <mark style="color:red;">\*</mark>Avoid values for the `name` argument which may be the names of HTML attributes, such as `"name"`, `"role"`, `"id"`, etc. This is because by default, the form's template string is first sanitized using [DOMPurify](https://github.com/cure53/DOMPurify), and these values may be removed to prevent DOM clobbering.
{% endhint %}

***

## Parameters

### Shared parameters

These parameters are common to all form fields:

| Name                  | Type                                            | Description                                                                                                                                                                                                                                                                             |
| --------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `question` (required) | `string`                                        | The main question or label of the form field.                                                                                                                                                                                                                                           |
| `required`            | `true` (`boolean`)                              | When set, the field becomes required.                                                                                                                                                                                                                                                   |
| `description`         | `string`                                        | Any extra information that the user may need to fill out the form. Appears right below the question.                                                                                                                                                                                    |
| `fieldSize`           | `"sm"`                                          | When set to `"sm"`, the font sizes of the question, description, and answer are made smaller.                                                                                                                                                                                           |
| `labelStyle`          | `"classic"`                                     | When set to `"classic"`, the question and description of the form field are made smaller.                                                                                                                                                                                               |
| `subfield`            | `true` (`boolean`)                              | When set, the question and description of the form field are made smaller. Functionally the same as setting `labelStyle` to `"classic"`.                                                                                                                                                |
| `disabled`            | `true` (`boolean`)                              | When set, the input is disabled.                                                                                                                                                                                                                                                        |
| `autofocus`           | `true` (`boolean`)                              | When set, the input will be automatically focused when the parent slide becomes active, or immediately after page load.                                                                                                                                                                 |
| `id`                  | `string`                                        | The `id` attribute of the form field container.                                                                                                                                                                                                                                         |
| `classNames`          | `string[]`                                      | The CSS class names of the form field. [See the available CSS utility classes](/content/css-utility-classes.md).                                                                                                                                                                        |
| `attrs`               | `Array<{ name: string, value: string }>`        | Other HTML attributes of the form field. Each attribute has a `name` and `value` property.                                                                                                                                                                                              |
| `displayCondition`    | `{ dependencies: string[], condition: string }` | Controls when the field is shown. The `dependencies` lists the fields to watch, and `condition` is the expression that must be true to show the field. The `condition` must be a valid [Nunjucks](https://mozilla.github.io/nunjucks/) expression. [See example](#conditional-display). |

### Picture choice specific parameters

| Name                 | Type                                                      | Description                                                                                                                                                                                        |
| -------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `choices` (required) | `Array<{ label: string, value?: string, image: string }>` | Array of choices that must include a `label` for display text, an optional `value` that's stored in the form data (if not provided, `label` is used as the value), and an `image` URL for display. |
| `multiple`           | `true` (`boolean`)                                        | Allow multiple selections.                                                                                                                                                                         |
| `supersize`          | `true` (`boolean`)                                        | Make the pictures larger.                                                                                                                                                                          |
| `hideLabels`         | `true` (`boolean`)                                        | Hide the text labels.                                                                                                                                                                              |
| `hideFormText`       | `true` (`boolean`)                                        | For multiple selections, when set, the form text **"Choose as many as you like"** is hidden.                                                                                                       |
| `checked`            | `string[]`                                                | Array of pre-checked choice values.                                                                                                                                                                |

***

## Examples

### Picture choice with value-label pairs and image URLs

Value-label pairs allow different values to be stored than what's shown to users. The `label` appears for users to select, while the `value` is stored in the form data. Each choice must also include an `image` URL. Please note, for `checked` to work with value-label pairs, it must contain the `value`, not the `label`.

```javascript
composer.pictureChoice("theme", {
  question: "Select your preferred theme",
  choices: [
    { 
      label: "Light and Airy",
      value: "light",
      image: "https://example.com/themes/light.jpg"
    },
    { 
      label: "Dark and Moody",
      value: "dark",
      image: "https://example.com/themes/dark.jpg"
    },
    { 
      label: "Bold and Colorful",
      value: "colorful",
      image: "https://example.com/themes/colorful.jpg"
    }
  ],
  checked: ["light"],
  multiple: true,
  required: true
});
```

Generates the following Markdown-like syntax:

```
theme* = PictureChoice(
  | question = Select your preferred theme
  | choices = "light" Light and Airy && https://example.com/themes/light.jpg, "dark" Dark and Moody && https://example.com/themes/dark.jpg, "colorful" Bold and Colorful && https://example.com/themes/colorful.jpg
  | checked = light
  | multiple
  | required
)
```

### Supersized picture choice with hidden labels

Create a picture choice with larger images and hidden text labels:

```javascript
composer.pictureChoice("avatar", {
  question: "Choose your avatar",
  choices: [
    { label: "Warrior", image: "/avatars/warrior.jpg" },
    { label: "Mage", image: "/avatars/mage.jpg" },
    { label: "Archer", image: "/avatars/archer.jpg" }
  ],
  supersize: true,
  hideLabels: true
});
```

Generates the following Markdown-like syntax:

```
avatar = PictureChoice(
  | question = Choose your avatar
  | choices = Warrior && /avatars/warrior.jpg, Mage && /avatars/mage.jpg, Archer && /avatars/archer.jpg
  | supersize
  | hidelabels
)
```

### Styled picture choice with custom attributes

Add CSS classes and other HTML attributes using the `classNames` and `attrs` parameters:

```javascript
composer.pictureChoice("layout", {
  question: "Pick your preferred layout",
  choices: [
    { label: "Grid", image: "/layouts/grid.jpg" },
    { label: "List", image: "/layouts/list.jpg" },
    { label: "Masonry", image: "/layouts/masonry.jpg" }
  ],
  classNames: ["col-6", "xs:col-6"],
  attrs: [
    { name: "style", value: "margin-top: 1rem;" }
  ]
});
```

Generates the following Markdown-like syntax:

```
[.col-6 .xs:col-6 style="margin-top: 1rem;"]
layout = PictureChoice(
  | question = Pick your preferred layout
  | choices = Grid && /layouts/grid.jpg, List && /layouts/list.jpg, Masonry && /layouts/masonry.jpg
)
```

Please [see the available CSS utility classes](/content/css-utility-classes.md).

### Conditional display

Conditionally show or hide a picture choice using the `displayCondition` parameter. It works as follows:

* `dependencies` lists the fields to watch.
* `condition` is the expression that must be true to show the field. This must be a valid [Nunjucks](https://mozilla.github.io/nunjucks/) expression.

For instance, in the example below, the room style choices will only show up if the user indicates they are interested in interior design.

```javascript
composer.choiceInput("interest", {
  question: "What is your interest?",
  choices: ["Interior Design", "Photography", "Cooking"],
  required: true
});

composer.pictureChoice("roomStyle", {
  question: "Which room style appeals to you most?",
  choices: [
    { label: "Contemporary", image: "/rooms/contemporary.jpg" },
    { label: "Traditional", image: "/rooms/traditional.jpg" },
    { label: "Industrial", image: "/rooms/industrial.jpg" }
  ],
  displayCondition: {
    dependencies: ["interest"],
    condition: "interest == 'Interior Design'"
  }
});
```

Generates the following Markdown-like syntax:

```
interest* = ChoiceInput(
  | question = What is your interest?
  | choices = Interior Design, Photography, Cooking
)

::: [{$ interest $}]
{% if interest == "Interior Design" %}
roomStyle = PictureChoice(
  | question = Which room style appeals to you most?
  | choices = Contemporary && /rooms/contemporary.jpg, Traditional && /rooms/traditional.jpg, Industrial && /rooms/industrial.jpg
)
{% endif %}
:::
```
