import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

import UppyCdnExample from '/src/components/UppyCdnExample';

# Form

The `@uppy/form` plugin integrates with an existing HTML `<form>` element to
extract input data from it, and send along with the Uppy upload. It then appends
the upload result back to the form via a hidden input.

## When should I use this?

When you have an existing HTML `<form>` element and you would like to:

- **Attach the form input values to the files.** This is useful if you want to
  associate meta data from the form (for example, name, location, id) with the
  uploaded file, so you can process it on the backend. `@uppy/form` extracts the
  input values before uploading/processing files and adds them to Uppy meta data
  state (`uppy.state.meta`), as well as and each file’s meta, and appends to the
  upload in an object with `[file input name attribute]` -> `[file input value]`
  key/values.
- **Upload the files and put the response (such as the file URLs) into a hidden
  field** (`<input type="hidden" name="uppyResult">`). Then you can POST and
  handle the form yourself. The appended result is a stringified version of a
  result returned from calling `uppy.upload()` or listening to `complete` event.
- **Automatically start the file upload on submit or submit the form after file
  upload.** This is off by default. See [`submitOnSuccess`](#submitOnSuccess)
  and [`triggerUploadOnSubmit`](#triggerUploadOnSubmit) options respectively for
  details.

:::note

If you are using a UI framework or library like React, Vue or Svelte, you’ll
most likely handle form data there as well, and thus won’t need this plugin.
Instead, pass meta data to Uppy via [`uppy.setMeta()`](/docs/uppy#setmetadata)
and listen to [`uppy.on('complete')`](/docs/uppy#complete) to get the upload
results back.

:::

## Install

<Tabs>
  <TabItem value="npm" label="NPM" default>

```shell
npm install @uppy/form
```

  </TabItem>

  <TabItem value="yarn" label="Yarn">

```shell
yarn add @uppy/form
```

  </TabItem>

  <TabItem value="cdn" label="CDN">
    <UppyCdnExample>
      {`
        import { Uppy, Form } from "{{UPPY_JS_URL}}"
        const uppy = new Uppy()
        uppy.use(Form, {
          // Options
        })
      `}
    </UppyCdnExample>
  </TabItem>
</Tabs>

## Use

```js title="app.js"
import Uppy from '@uppy/core';
import Form from '@uppy/form';
import DragDrop from '@uppy/drag-drop';

import '@uppy/core/dist/style.min.css';
import '@uppy/drag-drop/dist/style.min.css';

new Uppy().use(Form, {
	target: '#my-form',
});
```

```html title="index.html"
<form id="my-form" action="/submit" method="get">
	<label for="name">Enter your name: </label>
	<input type="text" name="name" required />

	<label for="dob">Date of birth: </label>
	<input type="date" name="dob" />

	<input type="submit" value="Save" />
</form>
```

By default the code above will:

1. Extract meta data from the form `#my-form`.
2. Send it with the Uppy upload.
3. Those fields will then be added to Uppy meta data state (`uppy.state.meta`)
   and each file’s meta, and appended as (meta)data to the upload in an object
   with `[file input name attribute]` -> `[file input value]` key/values.
4. When Uppy completes upload/processing, it will add an
   `<input type="hidden" name="uppyResult">` with the stringified upload result
   object back to the form.

:::note

You can disable both of these features, see options below.

:::

:::tip

`@uppy/form` can also start Uppy upload automatically once the form is
submitted, and even submit the form after the upload is complete. This is off by
default. See [`triggerUploadOnSubmit`](#triggerUploadOnSubmit) and
[`submitOnSuccess`](#submitOnSuccess) options below for details.

:::

## API

### Options

#### `id`

A unique identifier for this plugin (`string`, default: `'Form'`).

#### `target`

DOM element or CSS selector for the form element (`string` or `Element`,
default: `null`).

This is required for the plugin to work.

#### `resultName`

The `name` attribute for the `<input type="hidden">` where the result will be
added (`string`, default: `uppyResult`).

#### `getMetaFromForm`

Configures whether to extract metadata from the form (`boolean`, default:
`true`).

When set to `true`, the Form plugin will extract all fields from a `<form>`
element before upload begins. Those fields will then be added to Uppy meta data
state (`uppy.state.meta`) and each file’s meta, and appended as (meta)data to
the upload in an object with `[file input name attribute]` ->
`[file input value]` key/values.

#### `addResultToForm`

Configures whether to add upload/encoding results back to the form in an
`<input name="uppyResult" type="hidden">` element (`boolean`, default: `true`).

#### `triggerUploadOnSubmit`

Configures whether to start the upload when the form is submitted (`boolean`,
default: `false`).

When a user submits the form (via a submit button, the <kbd>Enter</kbd> key or
otherwise), this option will prevent form submission, and instead upload files
via Uppy. Then you could:

- Set `submitOnSuccess: true` if you need the form to _actually_ be submitted
  once all files have been uploaded.
- Listen for `uppy.on('complete')` event to do something else if the file
  uploads are all you need. For example, if the form is used for file metadata
  only.

#### `submitOnSuccess`

Configures whether to submit the form after Uppy finishes uploading/encoding
(`boolean`, default: `false`).
