> For the complete documentation index, see [llms.txt](https://manual.bubble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual.bubble.io/help-guides/design/elements/ios-and-android-app/input-forms.md).

# Input forms (mobile)

Input forms let users enter information in your native mobile app, from text and dates to selections and checkboxes. Learn how each input works and what kind of data it returns.

**Input forms** are how you collect information from your users. They range from simple text fields and toggles to more complex controls like date pickers, dropdowns, and selectable lists.

Bubble includes a range of built-in input types for common needs, letting you build everything from a quick signup form to a detailed multi-step questionnaire. Each input type is designed to feel native to the platform, matching the interactions users expect.

## Input

Input elements accept a single line of plain text, and you can choose its content format from a wide range of options. The *Field type returned* in the list below specifies what kind of database field format the input returns.

<details>

<summary>How Bubble stores text formatting</summary>

Bubble uses a markup language called BBCode to store text formatting such as bold, italics, and bullet points. The BBCode is generated and applied automatically as you add formatting to your text.

BBCode is simpler and safer to use than HTML because it has more limited capabilities and only allows a select number of tags. This stops your users from uploading malicious code, such as CSS or JavaScript, that might break the app.

**External page:** [Guide to BBCode](https://www.bbcode.org/how-to-use-bbcode-a-complete-guide.php)\
**External page:** [BBCode tags reference](https://www.bbcode.org/reference.php)

### I want to use HTML instead

Sometimes it's useful to be able to store formatted text as HTML, such as when you want to pass formatted text to an email sending service that only supports this format.

None of the built-in Bubble text editors supports HTML formatting, but there are multiple [plugins](https://bubble.io/plugins) that let you store text with formatting as HTML instead of BBCode. Searching the Bubble Marketplace for *Rich Text Editor* is likely to give you some results that support this.

Regular text elements don't support HTML either: if you want to display text formatted with HTML, you can use the built-in HTML element.

</details>

{% hint style="info" %}
Because of the predictive text functionality on **Android devices**, some content formats involving masks have a slightly different UX. This applies to US phone, Percentage, Currency, Date, Euro date, and Text (numbers only).

On Android devices, the input lets users type anything and validates the content against the mask only after the user stops typing.

This doesn't affect the final data generated by the input.
{% endhint %}

### Text

The input accepts any text value.

**Field type returned:** text

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FInTKZvMONIQxfPSKSVpW%2Ftext%402x.png?alt=media&amp;token=421be641-2d5b-4675-8710-f37d7126f98f" alt="Input element with no formatting, showing the placeholder Jane Doe."><figcaption><p>An input with the <em>Text</em> content format.</p></figcaption></figure>

### Email

The input only accepts text values that are formatted like an email address.

**Field type returned:** text

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fm6aD5yFlD4Tw6mfcqcbq%2Femail%402x.png?alt=media&amp;token=a033ed96-2c29-4c59-a333-e7fb0911c675" alt="Input element with email formatting, showing the placeholder email@email.com."><figcaption><p>An input with the <em>Email</em> content format.</p></figcaption></figure>

### Password

The input accepts any kind of text value, but the characters typed are replaced by asterisks.

**Field type returned:** text

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F3aRIcciAsCuViegIu7Mi%2Fpassword%402x.png?alt=media&amp;token=26edd9a2-888d-4c08-ba93-fcf560578656" alt="Input element with password formatting, showing only asterisks."><figcaption><p>An input with the <em>Password</em> content format hides the characters as the user types.</p></figcaption></figure>

### Integer

The input only accepts whole numbers. Use this when you need to collect numerical values that can later be used for calculations (as opposed to numbers saved as text). You can specify a dynamic minimum and maximum value when this option is selected.

**Field type returned:** number

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fe6jK5JD1ni2VzvNUApcl%2Fnumber%402x.png?alt=media&amp;token=1214cbe9-2562-461f-ad53-ab361c18cbc1" alt="Input element with number (integer) formatting, showing the value 256."><figcaption><p>An input with the <em>Integer</em> content format.</p></figcaption></figure>

### Decimal

The input accepts any whole number or decimal number. You can specify a minimum and maximum value, as well as the number of decimals to include. You can also set the input to automatically include thousands separators as the user types. This option is only visual and doesn't affect the final value.

**Field type returned:** number

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F4NeDo1RfcLxUFFCePerI%2Fdecimal%402x.png?alt=media&amp;token=8e5338a9-2ca0-4f0e-8d67-a869657202b1" alt="Input element with decimal formatting, showing the value 29.99."><figcaption><p>An input with the <em>Decimal</em> content format.</p></figcaption></figure>

### Address

A geographic address. With this option, the input automatically validates the address with Google Maps. Note that the input doesn't search for valid addresses as the user types, so the user has to provide an already valid address (for example, by copying and pasting it from Google Maps). If you want the user to be able to see Google Maps search results as they type, you may want to look into using the Search box element instead.

**Field type returned:** address

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FGVivkTJGssfNGhQvNdmM%2Faddress%402x.png?alt=media&amp;token=7c40eb55-aef2-49b7-befb-249163d87341" alt="Input element with address formatting, showing the address of the Eiffel Tower in Paris."><figcaption><p>An input with the <em>Address</em> content format.</p></figcaption></figure>

### US phone

This input accepts correctly formatted US phone numbers. The value is saved as text.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FAgqbtzv0TVN3bV0iOYQN%2Fus-phone%402x.png?alt=media&amp;token=227727f9-a957-48a5-8fb7-0598b022db89" alt="Input element with US phone number formatting, showing (123) 123-1231."><figcaption><p>An input with the <em>US phone</em> content format.</p></figcaption></figure>

**Field type returned:** text

### Percentage

This input formats the user's input as a percentage and accepts input such as 20%. Bubble automatically saves it as the numerical equivalent of the percentage. For example, 20% is saved as the number 0.2, and 150% is saved as 1.5.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FvfMAM9iJsLqOwF51OjI1%2Fpercentage%402x.png?alt=media&amp;token=35a01748-e0d2-441d-95cb-6f577548dd75" alt="Input element with percentage formatting, showing 25%."><figcaption><p>An input with the <em>Percentage</em> content format.</p></figcaption></figure>

**Field type returned:** number

### Currency

The input accepts any whole number or decimal number and automatically formats the input in the chosen currency, such as *$20*. You can specify a minimum and maximum value, as well as the number of decimals to include. You can also set the input to automatically include thousands separators as the user types. The currency and thousands separators options are only visual and don't affect the final value.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FyztzWebFtLYcJztKMC3q%2Fcurrency%402x.png?alt=media&amp;token=05c2ba6c-b6c7-4eb7-9640-c5619da9ec36" alt="Input element with currency formatting, showing $29.99."><figcaption><p>An input with the <em>Currency</em> content format.</p></figcaption></figure>

**Field type returned:** number

### Date

The input accepts any date, but doesn't include time. It automatically formats the input's value as mm/dd/yyyy while the user types, guiding the user to provide the date in the right way. You can specify a time zone for the input, and Bubble automatically calculates any offset from the user's current time zone. If no time zone is provided, the user's current time zone is used. Dates are saved at 12 AM (00:00) on the given date.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FJAGmtVIWYWJ0e6pB8Aly%2Fus-date%402x.png?alt=media&amp;token=95a6439b-1be4-4594-97a5-9da57d79e6d0" alt="Input element with date formatting, showing 01/31/1970."><figcaption><p>An input with the <em>Date</em> content format, using the mm/dd/yyyy order.</p></figcaption></figure>

**Field type returned:** date

### Euro date

The input accepts any date, but doesn't include time. It automatically formats the input's value as dd/mm/yyyy while the user types, guiding the user to provide the date in the right way. You can specify a time zone for the input, and Bubble automatically calculates any offset from the user's current time zone. If no time zone is provided, the user's current time zone is used. Dates are saved at 12 AM (00:00) on the given date. The difference between this content format and the *Date* format is purely visual.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F0BmnRHhScazb0dMZYlRI%2Feuro-date%402x.png?alt=media&amp;token=72150c54-01c9-497c-8722-e98f7f877616" alt="Input element with European date formatting, showing 31/01/1970."><figcaption><p>An input with the <em>Euro date</em> content format, using the dd/mm/yyyy order.</p></figcaption></figure>

**Field type returned:** date

### Text (numbers only)

This input only accepts whole numbers, and the result is saved as text. This is useful when you want to save numerical values that need to remain exactly as the user typed them (without losing leading zeros, for example) and won't be used for any type of calculation, such as international phone numbers, zip codes, and order numbers.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fe6jK5JD1ni2VzvNUApcl%2Fnumber%402x.png?alt=media&amp;token=1214cbe9-2562-461f-ad53-ab361c18cbc1" alt="Input element with numbers as text formatting, showing the value 256."><figcaption><p>An input with the <em>Text (numbers only)</em> content format looks like a number input, but saves the value as text.</p></figcaption></figure>

**Field type returned:** text

<details>

<summary>Storing numbers as text versus storing them as numbers</summary>

### What is the difference between the two?

The Bubble database offers two different field types that can both be used to save numerical values: text and number.

There are a few scenarios where it makes sense to save a number as a text string:

#### When you need to include leading zeros

In an integer (or number), a leading zero represents no value and is disregarded when saved to the database. After all, 045 and 45 are the same thing from a mathematical point of view, and the zero only adds confusion and increases the total size of the database.

Sometimes leading zeros are necessary. For example, a phone number or zip code might start with a zero, and it must be stored as text to preserve the complete value.

#### When you need to pass the data as text

Sometimes when you communicate with an external system through an API, that system may expect a numerical value to be passed as text. In that case, it can be useful to store it as text in the database to avoid having to convert it later.

### When to use what

**Text** should be used when you're working with numerical values that will remain static and won't be included in any kind of calculation. For example:

* Phone numbers
* Zip codes
* Postal codes
* Product and part numbers

**Numbers** should be used when you're working with values that may need to be calculated or aggregated, such as:

* Year of birth
* Age
* Counts and totals (such as the number of items in a cart and the cart's total value)
* Financial numbers
* Enumerated values, such as the values used to represent the days of the week (for example, Sunday = 0, Monday = 1, and so on)

</details>

## Multiline input

As the name suggests, the **Multiline input** element accepts multiple lines of text. Like the regular input, this element supports plain text only and doesn't provide any custom formatting.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FUDrMISeQa5egr2vOohbB%2Fmultiline-input%402x.png?alt=media&amp;token=055a0a9d-b10c-4635-b880-d6a7dec1c5a7" alt="Multiline input element containing two paragraphs of placeholder text."><figcaption><p>A multiline input grows to show several lines and paragraphs of text.</p></figcaption></figure>

Use the Multiline input element when you need the user to be able to supply multiple lines of text but you don't want them to be able to add formatting such as bold, italics, and headers.

**Field type returned:** text

## Date/TimePicker

The **Date/TimePicker** is a native mobile element created specifically for the native mobile app editor, offering an alternative to the date/time picker used in the web app editor.

It automatically adapts to the device's system, displaying the iOS picker on Apple devices and the Android picker on Android devices. This happens by default, with no additional configuration needed.

{% hint style="warning" %}
The Date/TimePicker uses the device's native component, so it **won't render in web preview**. Use simulated device or a dev build to test any flows that involve the Date/TimePicker.

**Article:** [Previewing a mobile app](/help-guides/previewing-your-app/previewing-a-mobile-app.md)
{% endhint %}

### Appearance

The Date/TimePicker's properties control two key parts:

* The [element](#element-properties) placed in the view
* The [native date/time picker](#native-date-time-picker-properties), which appears when the user taps the element

### Element properties

* **Picker style:** Choose between:
  * Label/Icon: Show both a label and a customizable icon.
  * Label: Show just a label.
* **Icon placement:** Choose to display the icon to the left (leading) or right (trailing) of the label.
* **Icon size:** Set the size of the icon in pixels.
* **Icon color:** Set the color of the icon.

### Native date/time picker properties

* **Input type:**
  * Date: Displays the date picker only. The value is stored in the database as the selected date plus the current time.
  * Time: Displays the time picker only. The value is stored in the database as the current date plus the selected time.\
    \
    To combine the date from one picker with the time from another picker, you can use the `change time to` operator.
* **Accent color:**
  * Color picker: Sets the color of a few properties in the calendar picker.
* **Minimum/Maximum date:** Sets the minimum and maximum date and time that can be picked in the date/time picker.

## Selectable lists

A *selectable list* functions as an input element that lets users *select one or multiple options* from a list. It's particularly useful for building filters, segmented controls, and selection forms without requiring additional custom states or workflows.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F6NGE0htqRi0s8HkTnqli%2Fselectable-list-mobile-element.png?alt=media&amp;token=99ff5668-a6b2-453a-aa37-041b4f349d96" alt="Selectable list element showing a list of blog posts."><figcaption><p>Selectable lists allow users to select one or multiple options from a list.</p></figcaption></figure>

It can function in *single-select* or *multi-select* mode, with additional customization options for selection limits and workflow integration. Below are the key behaviors of the selectable list.

### Single-select and multi-select behavior

Selectable lists can be set to single-select or multi-select mode, depending on how you want users to interact with them.

#### Single-select behavior

In single-select mode, only one option can be active at a time. Selecting a new item automatically replaces the previous selection, similar to how radio buttons work.

Users can also clear the current selection by tapping the selected item again, returning the list to an unselected state. This makes it easy for users to change their mind or start over without needing a separate reset action.

#### Multi-select behavior

In multi-select mode, users can choose more than one option from the list.

By default, there's no cap on how many items can be selected. If you want to limit the selection, you can set a maximum number of choices. Once the user reaches that limit, the remaining options are automatically disabled, and the user has to deselect an item before selecting a new one.

### Validation and required lists

Selectable lists can be marked as required, similar to how you'd mark an [input field](#input) as required. This helps make sure the user makes a valid selection before their data is saved.

The way validation appears follows the same pattern as required inputs:

* **Conditional styling for missing selections activates when the values are being saved.** For example, if the user tries to submit a form without making a selection, the list can visibly indicate that a selection is missing, such as by highlighting a border or showing an error message.
* **The required styling clears automatically once the selection meets the requirement.** In single-select mode, this happens as soon as an item is selected. In multi-select mode with a range restriction, the styling clears once the required number of items has been selected.

### Performance considerations

* The selectable list *loads all items immediately*, meaning it doesn't use lazy loading or virtualization like the [*vertical list*](/help-guides/design/elements/ios-and-android-app/the-view.md#vertical-list).
* Large data sets may impact performance, so it's a good idea to limit the number of options when possible.
* This element is *not a replacement for vertical lists* and shouldn't be used for extensive lists of items.

### Formatting selected items

The selectable list element has `is selected` and `isn't selected` data sources that you can use in conditionals to apply formatting to selected items.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FPX5m7Vom6hYhT0Dv1gYd%2Fselected-selectablelist-item-conditional.png?alt=media&amp;token=32179fc6-c9ca-4939-960b-9db366a5813f" alt="Conditional formatting on a selected list item in a selectable list element on mobile."><figcaption><p>This conditional adds a solid 1px border to an item when <code>This SelectableListItem is selected</code>.</p></figcaption></figure>

The conditional must be set on the *SelectableListItem* pseudo child element, not on the selectable list element itself.

### Workflows and actions

Workflows can be triggered when a user interacts with a list item. When adding a workflow from the list item property editor, the "When element is clicked" workflow event is automatically pre-filled.

The following actions are available for selectable lists:

* **Set selectable list value:** Set a selected value for the selectable list (single item or list, depending on the [selection type](#single-select-behavior)).
* **Select all:** Selects all the available entries in the list.
* **Unselect all:** Deselects all selected entries.
* **Display list:** Set a list of entries for the selectable list, formatted as a list.
* **Clear list:** Removes all entries from the list.
* **Scroll to entry:** Scrolls the list to a specific entry.

### Properties

The following properties are available on selectable lists:

* 's list of items (if multi)
* 's selected item (if single)
* 's list of selected items (if multi)
* 's list of unselected items (if multi)
* 's minimum number of selections (if range is selected)
* 's maximum number of selections (if range is selected)
* 's number of allowed selections (if exact is selected)
* Width
* Height
* isn't valid
* is disabled

#### Conditional properties

The following conditional properties are available on selectable lists:

* **Minimum number of selections** (`number`): The minimum number of selectable entries, as specified in the minimum number of selections property
* **Maximum number of selections** (`number`): The maximum number of selectable entries, as specified in the maximum number of selections property
* **Number of selections** (`number`): The current number of selected entries

## Checkbox

The **Checkbox** element provides an intuitive way to manage selection states without needing complex workflows or custom states.

Here are two common use cases for the Checkbox element:

### Filtering to-dos

The Checkbox element can be used to filter lists, such as a list of to-do items. Instead of manually creating icons, workflows, and custom states to manage selections, you can add the Checkbox element directly to each list item. The checkbox works similarly to a button, allowing for customization of icons, labels, sizes, and colors.

It also includes built-in conditionals for the checked and unchecked states, making it simple to toggle between states by tapping. The current value of the checkbox is easily readable, so you can trigger actions based on whether it's selected or not.

### Managing task status

Another common use case for the Checkbox element is to visually indicate task completion. For instance, when a task is marked as done, the checkbox appears checked, and when a task isn't done, it appears unchecked. You can modify the default state of the checkbox through conditionals. For example, if a task is marked as complete in the database, the checkbox automatically reflects that state by appearing checked.

### Key features

* **Customizable appearance:** Adjust icons, labels, colors, and sizes.
* **Default checked/unchecked states:** Built-in toggling functionality.
* **Conditional behavior:** Reflect the current state based on conditions (for example, task completion).
