|
1 |
| -(ns om-widgets.modal-box |
2 |
| - (:require-macros [cljs.core.async.macros :refer [go]]) |
3 |
| - (:require [om.core :as om :include-macros true] |
4 |
| - [om.dom :as dom :include-macros true] |
5 |
| - [om-widgets.forms :as f :include-macros true] |
6 |
| - [dommy.core :as dommy :refer-macros [sel sel1]] |
7 |
| - [cljs.core.async :refer [put! chan <! alts! timeout]])) |
8 |
| - |
9 |
| - |
10 |
| -(defn handle-keydown |
11 |
| - [owner event] |
12 |
| - (let [ESC 27 |
13 |
| - k (.-keyCode event)] |
14 |
| - (when (#{ESC} k) |
15 |
| - (condp = k |
16 |
| - ESC ((om/get-state owner :close-fn)))))) |
17 |
| - |
18 |
| -(defn create-modal-box |
19 |
| - [target owner] |
20 |
| - (reify |
21 |
| - |
22 |
| - om/IDidMount |
23 |
| - (did-mount [this] |
24 |
| - (-> (sel1 "body") |
25 |
| - (dommy/add-class! "om-widgets-modal-is-open")) |
26 |
| - |
27 |
| - (when (om/get-state owner :close-on-esc) |
28 |
| - (let [handle-keydown-fn (partial handle-keydown owner)] |
29 |
| - (om/set-state! owner :handle-keydown-fn handle-keydown-fn) |
30 |
| - (dommy/listen! (sel1 :body) :keydown handle-keydown-fn)))) |
31 |
| - |
32 |
| - om/IWillUnmount |
33 |
| - (will-unmount [this] |
34 |
| - (-> (sel1 "body") |
35 |
| - (dommy/remove-class! "om-widgets-modal-is-open")) |
36 |
| - |
37 |
| - (when-let [handle-keydown-fn (om/get-state owner :handle-keydown-fn)] |
38 |
| - (dommy/unlisten! (sel1 :body) :keydown handle-keydown-fn))) |
39 |
| - |
40 |
| - om/IRenderState |
41 |
| - (render-state [this {:keys [title body footer close-fn class-name size] :as state}] |
42 |
| - (dom/div #js {:className "modal" |
43 |
| - :role "dialog" |
44 |
| - :tabIndex -1 |
45 |
| - :style #js {:display "block"}} |
46 |
| - (dom/div #js {:className "om-widgets-overlay"}) |
47 |
| - (dom/div #js {:className "om-widgets-modal-box"} |
48 |
| - (dom/div #js {:className (str "om-widgets-modal-dialog " |
49 |
| - class-name |
50 |
| - (when size (str " modal-" (name size))))} |
51 |
| - (dom/div #js {:className "om-widgets-modal-content"} |
52 |
| - (if (string? title) |
53 |
| - (dom/div #js {:className "om-widgets-modal-header"} |
54 |
| - (dom/h4 #js {:className "om-widgets-modal-title"} title)) |
55 |
| - (when-let [title-seq (cond |
56 |
| - (fn? title) [(title close-fn target)] |
57 |
| - (seq? title) title |
58 |
| - (not= nil title) [title] |
59 |
| - :else nil)] |
60 |
| - (apply dom/div #js {:className "om-widgets-modal-header"} title-seq))) |
61 |
| - |
62 |
| - (when-let [body-seq (cond |
63 |
| - (fn? body) [(body close-fn target)] |
64 |
| - (seq? body) body |
65 |
| - (not= nil body) [body] |
66 |
| - :else nil)] |
67 |
| - (apply dom/div #js {:className "om-widgets-modal-body"} body-seq)) |
68 |
| - |
69 |
| - (when-let [footer-seq (cond |
70 |
| - (fn? footer) [(footer close-fn target)] |
71 |
| - (seq? footer) footer |
72 |
| - (not= nil footer) [footer] |
73 |
| - :else nil)] |
74 |
| - (apply dom/div #js {:className "om-widgets-modal-footer"} footer-seq))))))))) |
75 |
| - |
76 |
| - |
77 |
| -(defn modal-box |
78 |
| - "Arguments title, body and footer [string or vector of components]" |
79 |
| - [target {:keys [title body footer close-fn class-name close-on-esc size] |
80 |
| - :or {body "Missing body parameter!"}}] |
81 |
| - (om/build create-modal-box target {:state {:body body |
82 |
| - :close-fn close-fn |
83 |
| - :footer footer |
84 |
| - :title title |
85 |
| - :close-on-esc close-on-esc |
86 |
| - :size size |
87 |
| - :class-name class-name}})) |
88 |
| - |
89 |
| -(defn install-modal-box! |
90 |
| - [target owner] |
91 |
| - (when-let [config (om/get-state owner :mb_config)] |
92 |
| - (modal-box target config))) |
93 |
| - |
94 |
| -(defn alert |
95 |
| - [owner title message] |
96 |
| - (let [c (chan)] |
97 |
| - (go |
98 |
| - (om/set-state! owner |
99 |
| - :mb_config |
100 |
| - {:title title |
101 |
| - :body message |
102 |
| - :footer (f/with-owner owner |
103 |
| - (f/button :btn-mb-alert-ok |
104 |
| - {:location :left |
105 |
| - :style :mb-alert-ok |
106 |
| - :icon :icon-ok |
107 |
| - :text " OK" |
108 |
| - :on-click #(put! c :ok)}))}) |
109 |
| - (when (<! c) |
110 |
| - (om/set-state! owner :mb_config nil))))) |
111 |
| - |
112 |
| - |
113 |
| -(defn ok-cancel |
114 |
| - [owner title message] |
115 |
| - (let [c (chan)] |
116 |
| - (go |
117 |
| - (om/set-state! owner |
118 |
| - :mb_config |
119 |
| - {:title title |
120 |
| - :body message |
121 |
| - :footer (dom/div nil |
122 |
| - (f/with-owner owner |
123 |
| - (f/button :btn-mb-alert-ok |
124 |
| - {:location :left |
125 |
| - :icon :ok |
126 |
| - :text " OK" |
127 |
| - :on-click #(put! c :ok)})) |
128 |
| - (f/with-owner owner |
129 |
| - (f/button :btn-mb-alert-cancel |
130 |
| - {:location :right |
131 |
| - :style :danger |
132 |
| - :icon :remove |
133 |
| - :text " CANCEL" |
134 |
| - :on-click #(put! c :cancel)})))}) |
135 |
| - (when-let [result (<! c)] |
136 |
| - (om/set-state! owner :mb_config nil) |
137 |
| - result)))) |
138 |
| - |
139 |
| -(defn modal-launcher-component |
140 |
| - [_ owner opts] |
141 |
| - (reify |
142 |
| - om/IRenderState |
143 |
| - (render-state [this {:keys [html-fn title-fn body-fn footer-fn visible channel] :as state}] |
144 |
| - (dom/div nil |
145 |
| - (when visible |
146 |
| - (om/build create-modal-box nil {:state {:body body-fn |
147 |
| - :close-fn (fn [res] |
148 |
| - (om/set-state! owner :visible false) |
149 |
| - (put! channel (or res false))) |
150 |
| - :footer footer-fn |
151 |
| - :title title-fn}})) |
152 |
| - (html-fn (fn [] |
153 |
| - (go (let [channel (chan)] |
154 |
| - (om/update-state! owner (fn [st] |
155 |
| - (merge st {:visible true |
156 |
| - :channel channel}))) |
157 |
| - (<! channel))))))))) |
158 |
| -(defn modal-launcher |
159 |
| - [html title body footer] |
160 |
| - (om/build modal-launcher-component nil {:state {:html-fn html |
161 |
| - :title-fn title |
162 |
| - :body-fn body |
163 |
| - :footer-fn footer}})) |
164 |
| - |
165 |
| -(defn do-modal |
166 |
| - [owner title body footer {:keys [class-name]}] |
167 |
| - (let [c (chan)] |
168 |
| - (go |
169 |
| - (let [close-fn (fn [result] |
170 |
| - (put! c (or result false)))] |
171 |
| - (om/set-state! owner |
172 |
| - :mb_config |
173 |
| - {:close-fn close-fn |
174 |
| - :title title |
175 |
| - :body body |
176 |
| - :footer footer |
177 |
| - :class-name class-name})) |
178 |
| - (let [result (<! c)] |
179 |
| - (om/set-state! owner :mb_config nil) |
180 |
| - result)))) |
| 1 | +(ns om-widgets.modal-box |
| 2 | + (:require-macros [cljs.core.async.macros :refer [go]]) |
| 3 | + (:require [om.core :as om :include-macros true] |
| 4 | + [om.dom :as dom :include-macros true] |
| 5 | + [om-widgets.forms :as f :include-macros true] |
| 6 | + [dommy.core :as dommy :refer-macros [sel sel1]] |
| 7 | + [cljs.core.async :refer [put! chan <! alts! timeout]])) |
| 8 | + |
| 9 | + |
| 10 | +(defn handle-keydown |
| 11 | + [owner event] |
| 12 | + (let [ESC 27 |
| 13 | + k (.-keyCode event)] |
| 14 | + (when (#{ESC} k) |
| 15 | + (condp = k |
| 16 | + ESC ((om/get-state owner :close-fn)))))) |
| 17 | + |
| 18 | +(defn create-modal-box |
| 19 | + [target owner] |
| 20 | + (reify |
| 21 | + |
| 22 | + om/IDidMount |
| 23 | + (did-mount [this] |
| 24 | + (when (om/get-state owner :set-modal-is-open) |
| 25 | + (-> (sel1 "body") |
| 26 | + (dommy/add-class! "om-widgets-modal-is-open"))) |
| 27 | + |
| 28 | + (when (om/get-state owner :close-on-esc) |
| 29 | + (let [handle-keydown-fn (partial handle-keydown owner)] |
| 30 | + (om/set-state! owner :handle-keydown-fn handle-keydown-fn) |
| 31 | + (dommy/listen! (sel1 :body) :keydown handle-keydown-fn)))) |
| 32 | + |
| 33 | + om/IWillUnmount |
| 34 | + (will-unmount [this] |
| 35 | + (when (om/get-state owner :set-modal-is-open) |
| 36 | + (-> (sel1 "body") |
| 37 | + (dommy/remove-class! "om-widgets-modal-is-open"))) |
| 38 | + |
| 39 | + (when-let [handle-keydown-fn (om/get-state owner :handle-keydown-fn)] |
| 40 | + (dommy/unlisten! (sel1 :body) :keydown handle-keydown-fn))) |
| 41 | + |
| 42 | + om/IRenderState |
| 43 | + (render-state [this {:keys [title body footer close-fn class-name size] :as state}] |
| 44 | + (dom/div #js {:className "modal" |
| 45 | + :role "dialog" |
| 46 | + :tabIndex -1 |
| 47 | + :style #js {:display "block"}} |
| 48 | + (dom/div #js {:className "om-widgets-overlay"}) |
| 49 | + (dom/div #js {:className "om-widgets-modal-box"} |
| 50 | + (dom/div #js {:className (str "om-widgets-modal-dialog " |
| 51 | + class-name |
| 52 | + (when size (str " modal-" (name size))))} |
| 53 | + (dom/div #js {:className "om-widgets-modal-content"} |
| 54 | + (if (string? title) |
| 55 | + (dom/div #js {:className "om-widgets-modal-header"} |
| 56 | + (dom/h4 #js {:className "om-widgets-modal-title"} title)) |
| 57 | + (when-let [title-seq (cond |
| 58 | + (fn? title) [(title close-fn target)] |
| 59 | + (seq? title) title |
| 60 | + (not= nil title) [title] |
| 61 | + :else nil)] |
| 62 | + (apply dom/div #js {:className "om-widgets-modal-header"} title-seq))) |
| 63 | + |
| 64 | + (when-let [body-seq (cond |
| 65 | + (fn? body) [(body close-fn target)] |
| 66 | + (seq? body) body |
| 67 | + (not= nil body) [body] |
| 68 | + :else nil)] |
| 69 | + (apply dom/div #js {:className "om-widgets-modal-body"} body-seq)) |
| 70 | + |
| 71 | + (when-let [footer-seq (cond |
| 72 | + (fn? footer) [(footer close-fn target)] |
| 73 | + (seq? footer) footer |
| 74 | + (not= nil footer) [footer] |
| 75 | + :else nil)] |
| 76 | + (apply dom/div #js {:className "om-widgets-modal-footer"} footer-seq))))))))) |
| 77 | + |
| 78 | + |
| 79 | +(defn modal-box |
| 80 | + "Arguments title, body and footer [string or vector of components]" |
| 81 | + [target {:keys [title body footer close-fn class-name close-on-esc size set-modal-is-open] |
| 82 | + :or {body "Missing body parameter!" |
| 83 | + set-modal-is-open true}}] |
| 84 | + (om/build create-modal-box target {:state {:body body |
| 85 | + :close-fn close-fn |
| 86 | + :footer footer |
| 87 | + :title title |
| 88 | + :close-on-esc close-on-esc |
| 89 | + :size size |
| 90 | + :set-modal-is-open set-modal-is-open |
| 91 | + :class-name class-name}})) |
| 92 | + |
| 93 | +(defn install-modal-box! |
| 94 | + [target owner] |
| 95 | + (when-let [config (om/get-state owner :mb_config)] |
| 96 | + (modal-box target config))) |
| 97 | + |
| 98 | +(defn alert |
| 99 | + [owner title message] |
| 100 | + (let [c (chan)] |
| 101 | + (go |
| 102 | + (om/set-state! owner |
| 103 | + :mb_config |
| 104 | + {:title title |
| 105 | + :body message |
| 106 | + :footer (f/with-owner owner |
| 107 | + (f/button :btn-mb-alert-ok |
| 108 | + {:location :left |
| 109 | + :style :mb-alert-ok |
| 110 | + :icon :icon-ok |
| 111 | + :text " OK" |
| 112 | + :on-click #(put! c :ok)}))}) |
| 113 | + (when (<! c) |
| 114 | + (om/set-state! owner :mb_config nil))))) |
| 115 | + |
| 116 | + |
| 117 | +(defn ok-cancel |
| 118 | + [owner title message] |
| 119 | + (let [c (chan)] |
| 120 | + (go |
| 121 | + (om/set-state! owner |
| 122 | + :mb_config |
| 123 | + {:title title |
| 124 | + :body message |
| 125 | + :footer (dom/div nil |
| 126 | + (f/with-owner owner |
| 127 | + (f/button :btn-mb-alert-ok |
| 128 | + {:location :left |
| 129 | + :icon :ok |
| 130 | + :text " OK" |
| 131 | + :on-click #(put! c :ok)})) |
| 132 | + (f/with-owner owner |
| 133 | + (f/button :btn-mb-alert-cancel |
| 134 | + {:location :right |
| 135 | + :style :danger |
| 136 | + :icon :remove |
| 137 | + :text " CANCEL" |
| 138 | + :on-click #(put! c :cancel)})))}) |
| 139 | + (when-let [result (<! c)] |
| 140 | + (om/set-state! owner :mb_config nil) |
| 141 | + result)))) |
| 142 | + |
| 143 | +(defn modal-launcher-component |
| 144 | + [_ owner opts] |
| 145 | + (reify |
| 146 | + om/IRenderState |
| 147 | + (render-state [this {:keys [html-fn title-fn body-fn footer-fn visible channel] :as state}] |
| 148 | + (dom/div nil |
| 149 | + (when visible |
| 150 | + (om/build create-modal-box nil {:state {:body body-fn |
| 151 | + :close-fn (fn [res] |
| 152 | + (om/set-state! owner :visible false) |
| 153 | + (put! channel (or res false))) |
| 154 | + :footer footer-fn |
| 155 | + :title title-fn}})) |
| 156 | + (html-fn (fn [] |
| 157 | + (go (let [channel (chan)] |
| 158 | + (om/update-state! owner (fn [st] |
| 159 | + (merge st {:visible true |
| 160 | + :channel channel}))) |
| 161 | + (<! channel))))))))) |
| 162 | +(defn modal-launcher |
| 163 | + [html title body footer] |
| 164 | + (om/build modal-launcher-component nil {:state {:html-fn html |
| 165 | + :title-fn title |
| 166 | + :body-fn body |
| 167 | + :footer-fn footer}})) |
| 168 | + |
| 169 | +(defn do-modal |
| 170 | + [owner title body footer {:keys [class-name]}] |
| 171 | + (let [c (chan)] |
| 172 | + (go |
| 173 | + (let [close-fn (fn [result] |
| 174 | + (put! c (or result false)))] |
| 175 | + (om/set-state! owner |
| 176 | + :mb_config |
| 177 | + {:close-fn close-fn |
| 178 | + :title title |
| 179 | + :body body |
| 180 | + :footer footer |
| 181 | + :class-name class-name})) |
| 182 | + (let [result (<! c)] |
| 183 | + (om/set-state! owner :mb_config nil) |
| 184 | + result)))) |
0 commit comments