uppy/src/plugins/FileInput.js
Artur Paikin 6f80ea709c Extract metadata from form, closes #153
This PR adds support for extracting metadata from `<form>` elements.
This was asked #153 and came up elsewhere too, I believe. You can use
it like this:

```html
<form class="MyForm" action="/">
  <input type="file" />
  <input type="hidden" name="bla" value="12333">
  <input type="text" name="yo" value="1">
  <button type="submit">Upload</button>
</form>
```

```js
uppy.use(DragDrop, {
    target: '.MyForm',
    locale: {
      strings: {chooseFile: 'Выберите файл'}
    },
    setMetaFromTargetForm: true
  })
```

Then UI acquire type plugins, like Dashboard, FileInput and DragDrop,
before mounting themselves or doing anything else, extract FormData
from the `target` `<form>` element (it must be a form currently), and
merge the object with the global `state.meta`. This is done via
`setMeta` method on core. Then, when a file is added, `state.meta` is
merged to that file’s meta right away. The ability to add more fields
via UI plugin MetaData is also still there, though probably needs an
update.

In addition a new `meta` option is added in core:

```js
const uppy = Uppy({
  debug: true,
  autoProceed: true,
  meta: {
    username: 'Artur'
  }
})
```

This way some data can be set right away, it becomes the initial
`state.meta` object.
2017-06-28 20:21:23 -04:00

93 lines
2.5 KiB
JavaScript

const Plugin = require('./Plugin')
const Utils = require('../core/Utils')
const Translator = require('../core/Translator')
const html = require('yo-yo')
module.exports = class FileInput extends Plugin {
constructor (core, opts) {
super(core, opts)
this.id = 'FileInput'
this.title = 'File Input'
this.type = 'acquirer'
const defaultLocale = {
strings: {
selectToUpload: 'Select to upload'
}
}
// Default options
const defaultOptions = {
target: '.UppyForm',
replaceTargetContent: true,
multipleFiles: true,
pretty: true,
locale: defaultLocale,
inputName: 'files[]',
getMetaDataFromForm: false
}
// Merge default options with the ones set by user
this.opts = Object.assign({}, defaultOptions, opts)
this.locale = Object.assign({}, defaultLocale, this.opts.locale)
this.locale.strings = Object.assign({}, defaultLocale.strings, this.opts.locale.strings)
// i18n
this.translator = new Translator({locale: this.locale})
this.i18n = this.translator.translate.bind(this.translator)
this.render = this.render.bind(this)
}
handleInputChange (ev) {
this.core.log('All right, something selected through input...')
const files = Utils.toArray(ev.target.files)
files.forEach((file) => {
this.core.emitter.emit('core:file-add', {
source: this.id,
name: file.name,
type: file.type,
data: file
})
})
}
render (state) {
const hiddenInputStyle = 'width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1;'
const input = html`<input class="uppy-FileInput-input"
style="${this.opts.pretty ? hiddenInputStyle : ''}"
type="file"
name=${this.opts.inputName}
onchange=${this.handleInputChange.bind(this)}
multiple="${this.opts.multipleFiles ? 'true' : 'false'}"
value="">`
return html`<form class="Uppy uppy-FileInput-form">
${input}
${this.opts.pretty
? html`<button class="uppy-FileInput-btn" type="button" onclick=${() => input.click()}>
${this.i18n('selectToUpload')}
</button>`
: null
}
</form>`
}
install () {
if (this.opts.setMetaFromTargetForm) {
this.setMetaFromTargetForm()
}
const target = this.opts.target
const plugin = this
this.target = this.mount(target, plugin)
}
uninstall () {
this.unmount()
}
}