Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

form: exclude own metadata, append result instead of overwriting #1686

Merged
merged 5 commits into from
Jul 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions packages/@uppy/form/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = class Form extends Plugin {
resultName: 'uppyResult',
getMetaFromForm: true,
addResultToForm: true,
multipleResults: false,
submitOnSuccess: false,
triggerUploadOnSubmit: false
}
Expand Down Expand Up @@ -86,26 +87,47 @@ module.exports = class Form extends Plugin {

let resultInput = this.form.querySelector(`[name="${this.opts.resultName}"]`)
if (resultInput) {
resultInput.value = JSON.stringify(result)
if (this.opts.multipleResults) {
// Append new result to the previous result array
const updatedResult = JSON.parse(resultInput.value)
updatedResult.push(result)
resultInput.value = JSON.stringify(updatedResult)
} else {
// Replace existing result with the newer result on `complete` event.
// This behavior is not ideal, since you most likely want to always keep
// all results in the input. This is kept for backwards compatability until 2.0.
resultInput.value = JSON.stringify(result)
}
return
}

resultInput = document.createElement('input')
resultInput.name = this.opts.resultName
resultInput.type = 'hidden'
resultInput.value = JSON.stringify(result)

if (this.opts.multipleResults) {
// Wrap result in an array so we can have multiple results
resultInput.value = JSON.stringify([result])
} else {
// Result is an object, kept for backwards compatability until 2.0
resultInput.value = JSON.stringify(result)
}

this.form.appendChild(resultInput)
}

getMetaFromForm () {
const formMeta = getFormData(this.form)
// We want to exclude meta the the Form plugin itself has added
// See https://github.com/transloadit/uppy/issues/1637
delete formMeta[this.opts.resultName]
this.uppy.setMeta(formMeta)
}

install () {
this.form = findDOMElement(this.opts.target)
if (!this.form || !this.form.nodeName === 'FORM') {
console.error('Form plugin requires a <form> target element passed in options to operate, none was found', 'error')
this.uppy.log('Form plugin requires a <form> target element passed in options to operate, none was found', 'error')
return
}

Expand Down
21 changes: 14 additions & 7 deletions website/src/docs/form.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ The `@uppy/form` plugin has the following configurable options:
```js
uppy.use(Form, {
target: null,
resultName: 'uppyResult',
getMetaFromForm: true,
addResultToForm: true,
resultName: 'uppyResult',
triggerUploadOnSubmit: false,
submitOnSuccess: false
multipleResults: false,
submitOnSuccess: false,
triggerUploadOnSubmit: false
})
```

Expand All @@ -59,6 +60,10 @@ A unique identifier for this plugin. It defaults to `'Form'`.

DOM element or CSS selector for the form element. This is required for the plugin to work.

### `resultName: 'uppyResult'`

The `name` attribute for the `<input type="hidden">` where the result will be added.

### `getMetaFromForm: true`

Configures whether or not to extract metadata from the form. 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 global `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.
Expand All @@ -67,16 +72,18 @@ Configures whether or not to extract metadata from the form. When set to true, t

Configures whether or not to add upload/encoding results back to the form in an `<input name="uppyResult" type="hidden">` element.

### `resultName: 'uppyResult'`
### `multipleResults: false`

The `name` attribute for the `<input type="hidden">` where the result will be added.
By default, the Form plugin will _replace_ the `value` of `<input type="hidden">` it adds with the result (if `addResultToForm` is enabled) on each upload / `complete` event. This behavior can be confusing, because if a user uploads a file and then adds another, only the last result will end up in the hidden input and submitted to your server.

Setting `multipleResults: true` turns the value of `<input type="hidden">` into an array and _appends_ each result from `complete` event to it. Since this is likely the desired default behavior in most cases, it will be made default in the next major release of Uppy, the option is kept for backwards compatability.

### `triggerUploadOnSubmit: false`

Configures whether or not to start the upload when the form is submitted. When the user presses a submit button, this will prevent form submission, and instead upload files. You can then:

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

### `submitOnSuccess: false`

Expand Down