# Setting up Image Editing with the Pintura Input element

The `<pintura-input>` custom element is a tiny wrapper around the `<input type="file">` element.

For a quick start use the [Pintura Input example project](https://github.com/pqina/pintura-example-pintura-input) as a guideline.

It's the easiest and fastest way to add image editing and uploading functionality to a webpage.

```html
<!DOCTYPE html>

<link rel="stylesheet" href="pintura-input.css" />

<form method="post" action="/upload" enctype="multipart/form-data">
    <pintura-input name="my-image"></pintura-input>
    <button type="submit">Upload</button>
</form>

<script src="pintura-input.js"></script>
```

This will automatically create a `<input type="file" name="my-image">` element with an `accept` attribute that filters for images and a `name` attribute set to `my-field`.

When an image is selected the editor will automatically open in a modal. The file input value is automatically set to the edited file.

Posting files along with the form submit works on browsers that [support the DataTransfer constructor](https://caniuse.com/mdn-api%5Fdatatransfer%5Fdatatransfer), currently this is Firefox, Chrome, Chromium powered browsers, and Safari 14.1.

If we need to support more browsers we can upload images asynchronously using the [store](#store) attribute.

## Configuration

All serializable image editor properties can be assigned to the `pintura-input` field.

```html
<pintura-input image-crop-aspect-ratio="4/3"></pintura-input>
```

This also works:

```html
<pintura-input utils='["crop", "finetune", "filter"]'></pintura-input>
```

If we have multiple fields on the page, we can set a global `PinturaInput` property on the `window` to share configuration options between fields.

```html
<script>
    window.PinturaInput = {
        imageCropMinSize: {
            width: 256,
            height: 256,
        },
        locale: {
            labelButtonExport: 'Save',
        },
    };
</script>

<pintura-input name="my-field"></pintura-input>
```

To supply custom properties to a single field we can set the `id` attribute on our field.

```html
<script>
    // These properties will be applied to all <pintura-input> elements
    window.PinturaInput = {
        imageCropMinSize: {
            width: 256,
            height: 256,
        },
        locale: {
            labelButtonExport: 'Save',
        },
    };

    // These properties will only be assigned to the <pintura-input id="myField"/> element
    window.myField = {
        imageCropAspectRatio: 1,
    };
</script>

<pintura-input id="myField" name="my-field"></pintura-input>
```

To supply custom options to the [imageWriter](../../api/image-editor/properties/#imagewriter), for example to resize the output image, we can set the [imageWriter](../../api/image-editor/properties/#imagewriter) property like this.

```html
<script>
    window.PinturaInput = {
        imageCropMinSize: {
            width: 256,
            height: 256,
        },
        imageWriter: {
            targetSize: {
                width: 128,
                height: 128,
            },
        },
    };
</script>

<pintura-input name="my-field"></pintura-input>
```

If we add a file input element to the `pintura-input` element it'll use that element as the file field. If the `accept` attribute is omitted or doesn't filter images it's automatically added to the field.

```html
<pintura-input>
    <input type="file" name="my-field" />
</pintura-input>
```

Pintura editor events are routed to the `<pintura-input>` element, so you can use `addEventListener` to subscribe to events.

```html
<pintura-input></pintura-input>

<script>
    const input = document.querySelector('pintura-input');
    input.addEventListener('pintura:process', (e) => {
        // The image was processed
    });
</script>
```

## Properties

The `<pintura-input>` field accepts the default editor properties and the following list of additional properties.

| Attribute                           | Default value                      | Description                                                                                   |
| ----------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------- |
| name                                | undefined                          | Used as name attribute on the internal file input element.                                    |
| accept                              | 'image/\*'                         | Used as accept attribute on the internal file input element.                                  |
| capture                             | undefined                          | Used as capture attribute on the internal file input element.                                 |
| src                                 | undefined                          | Used to set the initial image source.                                                         |
| [store](#store)                     | undefined                          | Optional URL location of the upload handler for async file uploads.                           |
| [post-field-name](#post-field-name) | undefined                          | Custom fields to add to the store upload action. FieldName is the name used in the form post. |
| input-store-success                 | '{filename} uploaded successfully' | The label to use for the success message.                                                     |
| input-button-reset                  | '&times;'                          | The label to use on the input reset button. Defaults to the × symbol.                         |

### store

Set to a target URL and the editor will upload files to that URL when the editing has completed.

If the `store` property is omitted the output file will be stored in the file field value. At the time of this writing [this doesn't work on Safari versions below 14.1](https://caniuse.com/mdn-api%5Fdatatransfer%5Fdatatransfer).

### post-field-name

If `store` is not set but post fields have been defined the `store` value is set to an empty string.

The example below will add a field called `"action"` with value `"upload"` to the `FormData`.

```html
<pintura-input post-custom-data="abcd"></pintura-input>
```

Is equal to a field posted like this:

```html
<input type="hidden" name="custom-data" value="abcd" />
```

or a field added like this:

```js
const fd = FormData();
fd.append('custom-data', 'abcd');
```

The attribute name without the `post-` part is used as the field name.

```js
'post-custom-data' -> 'custom-data'
'post-customData' -> 'customData'
'post-custom_data' -> 'custom_data'
```

## Templating

To improve the visual looks and default interaction of the `<pintura-input>` element we can supply an HTML template.

The template can contain three optional views which we can mark with the `data-empty`, `data-load`, and `data-process` attributes. There can be one of each.

We can use any HTML elements and [styles](#styles) that we like, we only need to add data attributes to tell the `<pintura-input>` component how to interact with the template.

```html
<pintura-input>
    <template>
        <!-- show this if no file loaded -->
        <div data-empty data-drop>
            <p>
                Drag &amp; Drop your image here or
                <button type="button" data-browse>Browse</button>
            </p>
        </div>
        <!-- show this if an image is already loaded. Use `src` attribute 
        on pintura-input for original image source -->
        <div data-load>
            <img src="image-thumb.jpeg" width="300" alt="" />
            <button type="button" data-remove>remove</button>
            <button type="button" data-edit>edit</button>
        </div>
        <!-- show this if an image has been processed -->
        <output data-process>
            <img src="{url}" width="300" alt="" />
            <p role="status">{filename} uploaded successfully</p>
            <button type="button" data-remove>remove</button>
            <button type="button" data-edit>edit</button>
        </output>
    </template>
</pintura-input>
```

The elements in the templates can be decorated with a list of attributes, these attribute can be used to quickly assign behavior to your elements.

| Attribute   | Description                                                     |
| ----------- | --------------------------------------------------------------- |
| data-drop   | Element will be able to catch dropped files.                    |
| data-browse | When element clicked it will open the browse file dialog.       |
| data-remove | When element clicked it will trigger removal of current image.  |
| data-reset  | When element clicked it will reset the input to the load state. |
| data-edit   | When element clicked it will open the editor.                   |

The following placeholders in the `data-process` template are automatically replaced when the template is rendered.

| Placeholder, Description |                                                                    |
| ------------------------ | ------------------------------------------------------------------ |
| {filename}               | Will be replaced with the filename of the output image.            |
| {url}                    | Will be replace with the object URL of the output image.           |
| {response}               | Will be replaced with the response of the server if store was set. |

### Styles

By default there are no styles applied to the templates. Either style the templates using your favorite CSS framework or use the styles below as a starting point.

```css
/* The empty state grey box */
pintura-input.base [data-empty] {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #eee;
}

/* To make each state equal size */
pintura-input.base [data-empty],
pintura-input.base img {
    width: 400px;
    height: 300px;
    object-fit: cover;
}
```

## Template Demo

By adding a couple additional elements and styles we can create a very nice looking image upload and edit control. This control below is included in the product package.

Drag & Drop your image here or Browse 

![](/pintura/demo/image.jpeg) Remove Edit 

![]({url}) 

"{filename}" uploaded successfully

Remove Edit 

## Next steps

With the editor set up, we can continue to configure the editor to our liking by adjusting the available options exposed by [the editor API](../../api/image-editor/)