Ver código fonte

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

* exclude meta the the Form plugin itself has added

* append new result to the previous one, instead of overwriting it

* add `replaceResultInFormWithNew` — replace result input value by default, with option to append

* talk about `replaceResultInFormWithNew`

* replaceResultInFormWithNew --> multipleResults
Artur Paikin 5 anos atrás
pai
commit
ae49cefd93
2 arquivos alterados com 39 adições e 10 exclusões
  1. 25 3
      packages/@uppy/form/src/index.js
  2. 14 7
      website/src/docs/form.md

+ 25 - 3
packages/@uppy/form/src/index.js

@@ -23,6 +23,7 @@ module.exports = class Form extends Plugin {
       resultName: 'uppyResult',
       getMetaFromForm: true,
       addResultToForm: true,
+      multipleResults: false,
       submitOnSuccess: false,
       triggerUploadOnSubmit: false
     }
@@ -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
     }
 

+ 14 - 7
website/src/docs/form.md

@@ -44,11 +44,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
 })
 ```
 
@@ -60,6 +61,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.
@@ -68,16 +73,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`