Skip to content

Instantly share code, notes, and snippets.

@olivergeorge
Last active August 29, 2015 14:12
Show Gist options
  • Save olivergeorge/ad212adb8a064b77eaad to your computer and use it in GitHub Desktop.
Save olivergeorge/ad212adb8a064b77eaad to your computer and use it in GitHub Desktop.
Bootstrap modal as pure OM
(ns olivergeorge.modal
(:require [om.core :as om :include-macros true]
[sablono.core :as html :refer-macros [html]]))
(def ESCAPE-KEY-CODE (js/Number 27))
(defn handle-key-down [owner e]
(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 [_]
; GOTCHA: can't watch for escape using :on-keypress which is only for input elements
; GOTCHA: can't removeEventListener unless we keep a reference to the one we hooked up
(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
on-save on-cancel on-dismiss]
:or {on-save identity on-cancel identity on-dismiss identity}} props]
(html [:div.modal-open
[:div.modal.in {:style {:display "block"}}
[:div.modal-backdrop.in {:on-click #(on-dismiss %)}]
[:div.modal-dialog {:onKeyDown #(handle-key-down owner %)
:onKeyUp #(handle-key-down owner %)
:onKeyPress #(handle-key-down owner %)}
[:div.modal-content
[:div.modal-header modal-header
[:button.close
[:span {:dangerouslySetInnerHTML {:__html "×"}}]]]
[:div.modal-body modal-body]
[:div.modal-footer
[:button.btn.btn-default {:on-click #(on-cancel %)} "Cancel"]
[:button.btn.btn-primary {:on-click #(on-save %)} "Save"]]]]]])))))
@olivergeorge
Copy link
Author

Example usage:

(defn UpdateForm [props owner]
  (reify

    om/IInitState
    (init-state [_] {:show false})

    om/IRenderState
    (render-state [_ {:keys [show]}]
      (let [{:keys [modal-header modal-body]} props]
        (html [:div
               (if show (om/build Modal {:modal-header modal-header
                                         :modal-body   modal-body
                                         :on-dismiss   #(om/set-state! owner :show false)
                                         :on-save      #(om/set-state! owner :show false)
                                         :on-cancel    #(om/set-state! owner :show false)}))
               [:button
                {:type "button"
                 :class    "btn btn-sm btn-primary"
                 :on-click #(om/set-state! owner :show true)}
                [:span.glyphicon.glyphicon-pencil] " Edit"]])))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment