Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.