index.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import BasePlugin from '@uppy/core/lib/BasePlugin.js'
  2. import findDOMElement from '@uppy/utils/lib/findDOMElement'
  3. import toArray from '@uppy/utils/lib/toArray'
  4. import getFormData from 'get-form-data'
  5. import packageJson from '../package.json'
  6. /**
  7. * Form
  8. */
  9. export default class Form extends BasePlugin {
  10. static VERSION = packageJson.version
  11. constructor (uppy, opts) {
  12. super(uppy, opts)
  13. this.type = 'acquirer'
  14. this.id = this.opts.id || 'Form'
  15. this.title = 'Form'
  16. // set default options
  17. const defaultOptions = {
  18. target: null,
  19. resultName: 'uppyResult',
  20. getMetaFromForm: true,
  21. addResultToForm: true,
  22. submitOnSuccess: false,
  23. triggerUploadOnSubmit: false,
  24. }
  25. // merge default options with the ones set by user
  26. this.opts = { ...defaultOptions, ...opts }
  27. this.handleFormSubmit = this.handleFormSubmit.bind(this)
  28. this.handleUploadStart = this.handleUploadStart.bind(this)
  29. this.handleSuccess = this.handleSuccess.bind(this)
  30. this.addResultToForm = this.addResultToForm.bind(this)
  31. this.getMetaFromForm = this.getMetaFromForm.bind(this)
  32. }
  33. handleUploadStart () {
  34. if (this.opts.getMetaFromForm) {
  35. this.getMetaFromForm()
  36. }
  37. }
  38. handleSuccess (result) {
  39. if (this.opts.addResultToForm) {
  40. this.addResultToForm(result)
  41. }
  42. if (this.opts.submitOnSuccess) {
  43. this.form.submit()
  44. }
  45. }
  46. handleFormSubmit (ev) {
  47. if (this.opts.triggerUploadOnSubmit) {
  48. ev.preventDefault()
  49. const elements = toArray(ev.target.elements)
  50. const disabledByUppy = []
  51. elements.forEach((el) => {
  52. const isButton = el.tagName === 'BUTTON' || (el.tagName === 'INPUT' && el.type === 'submit')
  53. if (isButton && !el.disabled) {
  54. el.disabled = true // eslint-disable-line no-param-reassign
  55. disabledByUppy.push(el)
  56. }
  57. })
  58. this.uppy.upload().then(() => {
  59. disabledByUppy.forEach((button) => {
  60. button.disabled = false // eslint-disable-line no-param-reassign
  61. })
  62. }, (err) => {
  63. disabledByUppy.forEach((button) => {
  64. button.disabled = false // eslint-disable-line no-param-reassign
  65. })
  66. return Promise.reject(err)
  67. }).catch((err) => {
  68. this.uppy.log(err.stack || err.message || err)
  69. })
  70. }
  71. }
  72. addResultToForm (result) {
  73. this.uppy.log('[Form] Adding result to the original form:')
  74. this.uppy.log(result)
  75. let resultInput = this.form.querySelector(`[name="${this.opts.resultName}"]`)
  76. if (resultInput) {
  77. // Append new result to the previous result array.
  78. // If the previous result is empty, or not an array,
  79. // set it to an empty array.
  80. let updatedResult
  81. try {
  82. updatedResult = JSON.parse(resultInput.value)
  83. } catch (err) {
  84. // Nothing, since we check for array below anyway
  85. }
  86. if (!Array.isArray(updatedResult)) {
  87. updatedResult = []
  88. }
  89. updatedResult.push(result)
  90. resultInput.value = JSON.stringify(updatedResult)
  91. return
  92. }
  93. resultInput = document.createElement('input')
  94. resultInput.name = this.opts.resultName
  95. resultInput.type = 'hidden'
  96. resultInput.value = JSON.stringify([result])
  97. this.form.appendChild(resultInput)
  98. }
  99. getMetaFromForm () {
  100. const formMeta = getFormData(this.form)
  101. // We want to exclude meta the the Form plugin itself has added
  102. // See https://github.com/transloadit/uppy/issues/1637
  103. delete formMeta[this.opts.resultName]
  104. this.uppy.setMeta(formMeta)
  105. }
  106. install () {
  107. this.form = findDOMElement(this.opts.target)
  108. if (!this.form || this.form.nodeName !== 'FORM') {
  109. this.uppy.log('Form plugin requires a <form> target element passed in options to operate, none was found', 'error')
  110. return
  111. }
  112. this.form.addEventListener('submit', this.handleFormSubmit)
  113. this.uppy.on('upload', this.handleUploadStart)
  114. this.uppy.on('complete', this.handleSuccess)
  115. }
  116. uninstall () {
  117. this.form.removeEventListener('submit', this.handleFormSubmit)
  118. this.uppy.off('upload', this.handleUploadStart)
  119. this.uppy.off('complete', this.handleSuccess)
  120. }
  121. }