|
|
@@ -0,0 +1,116 @@ |
|
|
(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)]])]]]]))))) |