Created
March 23, 2015 21:44
-
-
Save olivergeorge/233e961bd7f59b918dd6 to your computer and use it in GitHub Desktop.
Rough cut/paste of a modal component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def ESCAPE-KEY-CODE 27) | |
(defn handle-key-down [owner e] | |
"For handling non-printing events" | |
(if (= ESCAPE-KEY-CODE (.-keyCode e)) | |
(if-let [on-dismiss (:on-dismiss (om/get-props owner))] | |
(on-dismiss e)))) | |
(defn Modal [props owner] | |
(reify | |
om/IDidMount | |
(did-mount [_] | |
(let [key-down-callback (fn [e] (handle-key-down owner e))] | |
(.addEventListener js/window "keydown" key-down-callback) | |
(om/set-state! owner :key-down-callback key-down-callback))) | |
om/IWillUnmount | |
(will-unmount [_] | |
(.removeEventListener js/window "keydown" (om/get-state owner :key-down-callback))) | |
om/IRender | |
(render [_] | |
(let [{:keys [modal-header modal-body dialog-class | |
on-save on-cancel on-dismiss ok-copy loading] | |
:or {on-save identity on-cancel identity on-dismiss identity}} props] | |
(html [:div.modal-open | |
[:div.modal.in {:style {:display "block"} :tabIndex -1} | |
[:div.modal-backdrop.in {:style {:position "fixed"} ;GOTCHA: Large modals / scrolling is messy | |
:disabled loading | |
:on-click #(on-dismiss %)}] | |
[:div.modal-dialog {:class dialog-class} | |
[:div.modal-content | |
[:h4.modal-header modal-header | |
[:button.close {:disabled (not loading) :on-click #(on-dismiss %)} | |
[:span {:dangerouslySetInnerHTML {:__html "×"}}]]] | |
[:div.modal-body | |
(om/build ModalErrorMessage nil) | |
modal-body] | |
[:div.modal-footer | |
(if loading [:span [:span.fa.fa-spinner.fa-spin] " "]) | |
[:button.btn.btn-default {:disabled loading | |
:on-click #(on-cancel %)} "Cancel"] | |
[:button.btn.btn-primary {:disabled loading | |
:on-click #(on-save %)} (or ok-copy "OK")]]]]]]))))) | |
(defn hide-modal! [owner] (om/set-state! owner :show false)) | |
(defn show-modal! [owner] (om/set-state! owner :show true)) | |
(defn handle-modal-show [owner] | |
(om/set-state! owner :undo-state (.-state app-state)) | |
(show-modal! owner) | |
nil) | |
(defn handle-modal-cancel [owner] | |
(reset! app-state (om/get-state owner :undo-state)) | |
(hide-modal! owner) | |
nil) | |
(defn handle-modal-dismiss [owner] | |
(reset! app-state (om/get-state owner :undo-state)) | |
(hide-modal! owner) | |
nil) | |
(defn handle-modal-save [owner] | |
(let [save-ch (om/get-state owner :save-ch)] | |
(put! (:pub-chan (om/get-shared owner)) | |
{:topic :save :feedback-ch save-ch}) | |
nil)) | |
(defn UpdateForm [props owner] | |
(reify | |
om/IInitState | |
(init-state [_] {:show false | |
:saving? false | |
:save-ch (chan)}) | |
om/IWillMount | |
(will-mount [_] | |
(let [save-ch (om/get-state owner :save-ch) | |
saving! (fn [] (om/set-state! owner :saving? true)) | |
success! (fn [] (hide-modal! owner)) | |
idle! (fn [] (om/set-state! owner :saving? false))] | |
(go (loop [state :idle] | |
(when-let [[e v] (<! save-ch)] | |
(recur (match [state e] | |
[:idle :saving] (do (saving!) (<! (timeout 1000)) :saving) | |
[:saving :success] (do (success!) (idle!) :idle) | |
[:saving :failure] (do (idle!) :idle) | |
[_ _] state))))))) | |
om/IRenderState | |
(render-state [_ {:keys [show saving?]}] | |
(let [{:keys [modal-header disabled]} props] | |
(html [:div | |
(if show (om/build Modal (assoc props | |
:loading saving? | |
:ok-copy "OK" | |
:modal-header [:span [:span.glyphicon.glyphicon-pencil] " " modal-header] | |
:on-dismiss #(handle-modal-dismiss owner) | |
:on-save #(handle-modal-save owner) | |
:on-cancel #(handle-modal-cancel owner)))) | |
[(if disabled :button.btn-default :button.btn-primary) | |
{:type "button" | |
:disabled disabled | |
:class "UpdateButton btn btn-sm" | |
:style {:position "absolute" :right "1em" :z-index "1"} | |
:on-click #(handle-modal-show owner)} | |
[:span.glyphicon.glyphicon-pencil] " Update"]]))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment