Skip to content

Instantly share code, notes, and snippets.

Created April 29, 2015 07:47
Show Gist options
  • Save anonymous/fcc096d83d7e0833ed2a to your computer and use it in GitHub Desktop.
Save anonymous/fcc096d83d7e0833ed2a to your computer and use it in GitHub Desktop.
(defn upload! [owner]
(let [form (om/get-node owner "upload-form")
io (goog.net.IframeIo.)]
(goog.events.listen
io goog.net.EventType.COMPLETE #(js/console.log "COMPLETE"))
(goog.events.listen
io goog.net.EventType.SUCCESS (fn [_]
(put!
(om/get-state owner :reset-file-drop)
true)
(->> io
.getResponseJson
js->clj
(map-keys keyword)
(swap! app-state update-in
[:attachments] conj))))
(goog.events.listen
io goog.net.EventType.ERROR #(js/console.log "ERROR"))
(goog.events.listen
io goog.net.EventType.TIMEOUT #(js/console.log "TIMEOUT"))
(.sendFromForm io form)))
(defn FileDrop [{:keys [on-change reset-ch] :as props} owner]
(reify
om/IDisplayName (display-name [_] "FileDrop")
om/IDidMount
(did-mount [_]
(goog.events.listen
(goog.events.FileDropHandler. js/document)
goog.events.FileDropHandler.EventType.DROP
#(set!
(.-files (om/get-state owner :holder))
(.. % getBrowserEvent -dataTransfer -files)))
(go-loop []
(when (<! reset-ch)
(let [holder (goog.dom.createDom "input" #js {:type "file"})]
(goog.events.listen
holder goog.events.EventType.CHANGE
#(om/set-state! owner :file
(-> % .-target .-files (.item 0) .-name)))
(om/set-state! owner {:holder holder :file nil}))
(recur)))
(put! reset-ch true))
om/IDidUpdate
(did-update [_ _ prev-state]
(set! (.-files (om/get-node owner "input"))
(.-files (om/get-state owner :holder)))
(let [file (om/get-state owner :file)]
(when (and on-change (not= file (:file prev-state)))
(on-change file))))
om/IRenderState
(render-state [_ {:keys [file holder]}]
(html [:div
[:div {:on-click #(.click holder)}
[:h3.text-center.dropzone
(or file (:placeholder props)
"Drop file here or click to upload")]]
[:input.hidden
{:ref "input" :type "file" :name (:name props)}]]))))
(defn UploadData [_ owner]
(reify
om/IDisplayName (display-name [_] "UploadData")
om/IInitState
(init-state [_]
{:reset-file-drop (chan)})
om/IRenderState
(render-state [_ {:keys [file filename reset-file-drop]}]
(let [attachments (observe-path owner [:attachments])
upload-form (observe-path owner [:upload_form])
uff (:fields upload-form)]
(html [:div.UploadData
[:form#upload-form
{:ref "upload-form"
:method "POST"
:action (:url upload-form)
:enc-type "multipart/form-data"}
[:input {:type "hidden"
:name "csrfmiddlewaretoken"
:value (get-in uff [:csrfmiddlewaretoken :initial])
#_(.get (goog.net.Cookies. js/document) "csrftoken")}]
[:input {:type "hidden"
:name "document"
:value (get-in uff [:document :initial])}]
[:div.form-group
[:label "Filename"]
[:input.form-control
{:type "text"
:name "name"
:value filename
:on-change #(om/set-state! owner :filename
(.. % -target -value))}]]
(om/build FileDrop
{:name "file"
:reset-ch reset-file-drop
:on-change (fn [name]
(om/set-state-nr! owner :file name)
(when (or (= filename file)
(blank? filename))
(om/set-state!
owner :filename name)))})]
[:button.btn.btn-primary
{:on-click #(upload! owner)
:disabled (when-not (not-any? blank? [file filename]) "disabled")}
"Upload"]
[:h3 "Uploaded files"]
[:div
[:table.table.table-hover
[:thead
[:tr [:th "Id"] [:th "Name"] [:th "Created"]]]
[:tbody
(for [a attachments]
[:tr
[:td (:id a)]
[:td [:a {:href (:file a)} (:name a)]]
[:td (-> a :created js/Date. .toDateString)]])]]]])))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment