I'm attempting to use macros to generate a series of similar Om components (e.g. a modal element which contains common boilerplate and a dynamic "body").
I've got the solution below mostly working. The one exception is accessing the appropriate owner
in the form's on-submit
event handler.
;; macros.clj
(defmacro build-modal
([disp-name body]
`(fn [_# owner#]
(reify
om.core/IRender
(~'render [_#]
(dom/div {:class "login-view-modal"}
(dom/div {:class "login-view-modal-backsplash"})
(dom/div {:class "login-view-modal-content"}
~@body))))) nil))
;; ui.cljs
(defn login-view-modal []
(bs-macros/build-modal
"login-modal"
'(dom/form {:on-submit (fn [event]
(.preventDefault event)
(let [username (get-value owner "username")
password (get-value owner "password")
data {:email_address username
:password password}]
(handle-login-view-modal-form-submit data)))}
;; elided for brevity
(dom/div
(dom/button "LOG IN")))))
(defcomponent home-page-view [app owner]
(init-state [_] {:text ""})
(render-state [this state]
;; elided for brevity
(dom/div (login-view-modal))))
The modal is rendered as expected, however when submitting the form I'm presented with the error: Uncaught TypeError: Cannot read property 'getDOMNode' of undefined
, which seems to be because owner
is not in scope. (Note, this element and its event handler functions as expected when constructed in full - i.e. without using a macro.)
How do I make the appropriate owner
available to the body of the macro?