I wrote a simple file upload with drag-and-drop. It uploads an image to server and show preview on the form.
$ = require 'jquery'
React = require 'react'
ReactDOM = require 'react-dom'
{EventEmitter} = require('events')
Dropzone = require 'react-dropzone'
D = React.DOM
class DataModel extends EventEmitter
constructor: ->
@state = {
text: 'upload a file'
files: []
}
$.get('files/').then((data)=>
@state.files = @state.files.concat(data.result)
@emit('change')
)
getState: ->
return @state
uploadHandler: (file)->
fd = new FormData()
fd.append('file', file)
reader = new FileReader()
$.ajax({
url: 'upload/',
data: fd,
processData: false,
contentType: false,
type: 'POST'
}).done =>
reader.readAsDataURL(file)
reader.onload = (e)=>
@state.files.push({
src: e.target.result
})
@emit('change')
@state.text = 'upload next'
@emit('change')
.fail =>
@state.text = 'uploading failed'
@emit('change')
class FormComponent extends React.Component
constructor: (props)->
super(props)
@state = props.store.getState()
componentDidMount: () ->
@props.store.addListener('change', @_onChange.bind(@))
componentWillUnmount: ->
@props.store.removeListener('change', @_onChange.bind(@))
_onChange: ()->
{store} = @props
@setState(store.getState())
clickHandler: (e)->
e.preventDefault()
{store} = @props
store.uploadHandler(@refs.file.files[0])
onDrop: (files)->
{store} = @props
for f in files
store.uploadHandler(f)
render: ->
{state} = @
return D.form(
{ ref: 'form' }
state.files.map (el, i)->
D.img {src: el.src, key: i, height: 160, width: 100}
D.span {}, state.text
React.createElement(
Dropzone
{ onDrop: @onDrop.bind(@) }
D.div null, 'Drop here'
)
D.input {
type: "submit", value: 'next', onClick: @clickHandler.bind(@)
}
)
ReactDOM.render(
React.createElement(FormComponent, {store: new DataModel()}),
document.getElementById('container')
)
I'm expect some thoughts about DataModel
(or store
). Any other advice works too