I'm trying to run Jason's code but I cannot run it work.
I received the following error when I run (modal-ui).
#<function modal_ui(){return
om.core.root.call(null,test.modal.wrapper,test.modal.app_state,new
cljs.core.PersistentArrayMap(null, 1, [new
cljs.core.Keyword(null,"target","target",253001721),document.getElementById("app")],
null));
}>
"Error evaluating:" (modal-ui) :as "test.modal.modal_ui.call(null);\n"
#<Error: Invariant Violation: ReactCompositeComponent.render(): A valid
ReactComponent must be returned. You may have returned null, undefined, an
array, or some other invalid object.>
Error: Invariant Violation: ReactCompositeComponent.render(): A valid
ReactComponent must be returned. You may have returned null, undefined, an
array, or some other invalid object.
at invariant (http://localhost:8080/js-lib/react.js:15915:19)
at null.<anonymous> (http://localhost:8080/js-lib/react.js:6034:41)
at null._renderValidatedComponent (
http://localhost:8080/js-lib/react.js:11403:21)
at null.<anonymous> (http://localhost:8080/js-lib/react.js:5582:14)
at null.mountComponent (http://localhost:8080/js-lib/react.js:11403:21)
at ReactMultiChild.Mixin.mountChildren (
http://localhost:8080/js-lib/react.js:10913:42)
at ReactDOMComponent.Mixin._createContentMarkup (
http://localhost:8080/js-lib/react.js:6812:32)
at null.<anonymous> (http://localhost:8080/js-lib/react.js:6734:14)
at null.mountComponent (http://localhost:8080/js-lib/react.js:11403:21)
at null.<anonymous> (http://localhost:8080/js-lib/react.js:5587:44)
What is a problem in my code do you think ?
https://gist.github.com/tokomakoma123/3e33299cc7dd7ecf63ad
Thanks,
Makoto
2014-08-14 21:11 GMT+09:00 Daniel Kersten <[email protected]>:
> I tried the bootstrap-cljs modal yesterday and it works pretty well for
> me. I'd say its definitely worth a look.
>
>
> On 14 August 2014 07:44, Makoto H. <[email protected]> wrote:
>
>> It looks cool ! I will try to run your code.
>>
>> > Don't know if this'll help you, but I had a similar issue and took a
>> stab at translating the bootstrap modal into an om component. It's a bit
>> hacky, but here it is:
>> >
>> >
>> >
>> > (ns om-pages.components.modal
>> >
>> > (:require-macros [cljs.core.async.macros :refer [go]])
>> >
>> > (:require [goog.dom :as gdom]
>> >
>> > [om.core :as om :include-macros true]
>> >
>> > [om.dom :as dom :include-macros true]
>> >
>> > [cljs.core.async :refer [chan timeout put! <!]]))
>> >
>> >
>> >
>> > (def modal-opts-chan (chan))
>> >
>> > (def modal-close-chan (chan))
>> >
>> > (def fade-time 160)
>> >
>> >
>> >
>> > (defn set-modal [modal-opts]
>> >
>> > (put! modal-opts-chan modal-opts))
>> >
>> >
>> >
>> > (defn close-modal []
>> >
>> > (put! modal-close-chan true))
>> >
>> >
>> >
>> > (defn option->button [{:keys [text style action]}]
>> >
>> > (let [className (str "btn btn-" (or style "default"))]
>> >
>> > (dom/button #js {:type "button" :className className :onClick
>> action} text)))
>> >
>> >
>> >
>> > (defn modal [cursor owner]
>> >
>> > (reify
>> >
>> > om/IInitState
>> >
>> > (init-state [_]
>> >
>> > {:modal-opts nil})
>> >
>> >
>> >
>> > om/IWillMount
>> >
>> > (will-mount [_]
>> >
>> > (go (loop []
>> >
>> > (om/set-state! owner :modal {:opts (<! modal-opts-chan) :state
>> :init})
>> >
>> > (<! (timeout 50))
>> >
>> > (om/set-state! owner [:modal :state] :in)
>> >
>> > (<! modal-close-chan)
>> >
>> > (om/set-state! owner [:modal :state] :out)
>> >
>> > (<! (timeout fade-time))
>> >
>> > (om/set-state! owner :modal {:opts nil :state :clear})
>> >
>> > (recur))))
>> >
>> >
>> >
>> > om/IRenderState
>> >
>> > (render-state [_ {{:keys [opts state]} :modal}]
>> >
>> > (when opts
>> >
>> > (let [{:keys [title content options]} opts
>> >
>> > in (= state :in)
>> >
>> > click-on-bg? #(= (.-target %) (.-currentTarget %))]
>> >
>> > (dom/div nil
>> >
>> > (dom/div #js {:className (str "modal fade" (when in " in"))
>> >
>> > :onClick #(when (click-on-bg? %)
>> (close-modal))}
>> >
>> > (dom/div #js {:className "modal-dialog"}
>> >
>> > (dom/div #js {:className "modal-content"}
>> >
>> > (dom/div #js {:className "modal-header"}
>> >
>> > (dom/button #js {:type "button" :className "close"
>> >
>> > :onClick close-modal}
>> >
>> > (dom/i #js {:className "fa fa-times"}))
>> >
>> > (dom/h4 #js {:className "modal-title"} title))
>> >
>> > (dom/div #js {:className "modal-body"} content)
>> >
>> > (apply dom/div #js {:className "modal-footer"}
>> >
>> > (map option->button options)))))
>> >
>> > (dom/div #js {:className (str "modal-backdrop fade" (when
>> in " in"))})))))))
>> >
>> >
>> >
>> > I mount this to one of the last top-level divs in my html file using
>> om/root. Then, other components can show and hide the modal by using the
>> set-modal and close-modal functions. Something like this:
>> >
>> >
>> >
>> > (set-modal
>> >
>> > {:title "Unsaved Changes"
>> >
>> > :content "You have made changes to this page that have not
>> >
>> > yet been saved. How do you wish to proceed?"
>> >
>> > :options [{:text "Discard Changes"
>> >
>> > :style "danger"
>> >
>> > :action #(do (set! (.-hash js/location) view-url)
>> >
>> > (close-modal))}
>> >
>> > {:text "Cancel"
>> >
>> > :action close-modal}]})
>> >
>> >
>> >
>> > The way the component works is to allow the bootstrap css transition
>> settings to do all the fading in and out work. The trick is to set the
>> classes to the proper starting state, then add or remove the "in" class to
>> allow the transition to take effect and allow enough time to pass.
>> >
>> >
>> >
>> > I used core.async channels to help with the timing and also to guard
>> against situations where two or more events might trigger modals. This way,
>> when that happens, the modal will show for the event that fired first, and
>> once that's dealt with, the modal for the next will show, and on and on.
>> >
>> >
>> >
>> > One more note—you need to add something like the following to your
>> css/sass/less to make sure the modal displays. (You could alternatively add
>> it to the css style attribute on the component itself, but I don't like
>> doing that.)
>> >
>> >
>> >
>> > #modal {
>> >
>> > .modal.fade {
>> >
>> > display: block !important;
>> >
>> > }
>> >
>> > }
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > On Wednesday, August 6, 2014 8:53:54 PM UTC-7, Makoto H. wrote:
>> >
>> > > It worked with jayq. My code is as follows:
>> >
>> > >
>> >
>> > >
>> >
>> > >
>> >
>> > > (ns menu.test
>> >
>> > >
>> >
>> > > (:require-macros [cljs.core.async.macros :refer [go]])
>> >
>> > >
>> >
>> > > (:require [om.core :as om :include-macros true]
>> >
>> > >
>> >
>> > > [om.dom :as dom :include-macros true]
>> >
>> > >
>> >
>> > > ....
>> >
>> > >
>> >
>> > > [jayq.core :refer [$]]
>> >
>> > >
>> >
>> > >
>> >
>> > >
>> >
>> > > .....
>> >
>> > >
>> >
>> > > (.modal ($ :#div-modal) "hide")
>> >
>> > >
>> >
>> > > (.modal ($ :#div-modal) "show")
>> >
>> > >
>> >
>> > >
>> >
>> > >
>> >
>> > > I also think writing Thomas's suggestion using modal Om component is
>> better and
>> >
>> > >
>> >
>> > > I will try this. The bootstrap-cljs approach is also interesting.
>> >
>> > >
>> >
>> > >
>> >
>> > >
>> >
>> > > Thanks,
>> >
>> > >
>> >
>> > > Makoto
>> >
>> > >
>> >
>> > >
>> >
>> > >
>> >
>> > > > You call .modal on the div, but AFAIK when using jquery, $(..) does
>> more than just retrieve the DOM node - it adds all the jquery methods too.
>> >
>> > >
>> >
>> > > > You could try calling (.modal (js/$ modal) "show") or you could
>> look into using https://github.com/ibdknox/jayq
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > In any case, mixing jquery (and similar) with React/Om doesn't seem
>> to be a great idea if you can at all help it. My suggestion would be as
>> Thomas says and write a modal Om component instead. Another alternative
>> (probably what I will do soon) is to look into using the modals from
>> https://github.com/luxbock/bootstrap-cljs
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > On 6 August 2014 14:54, Makoto H. <[email protected]> wrote:
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > I have defined bootstrap.js like
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > ":externs ["/bootstrap.js"]" in my project.clj.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > But I'm not sure that is correct or not.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > https://gist.github.com/tokomakoma123/d2111e9ee288e3dddbcf
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > I found an article in the web which provides a solution how to use
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > bootstrap components from react.js.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> http://clozeit.wordpress.com/2014/01/08/bootstrap-modals-and-popover-in-react-js/
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > I will try to rewrite it into om.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > Thanks,
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > Makoto
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > > Looking at the code it seems like you are calling jquery style
>> code without actual jquery.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > > (.modal modal "show")
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > > .modal is a method provided via bootstrap.js/jquery and usually
>> called as
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > > $('#div-modal').modal('show')
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > > I'm not sure on how you'd interface bootstrap with Om but I doubt
>> that there is a "sane" way. You are probably better off writing a modal
>> component in Om.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > --
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > Note that posts from new members are moderated - please be patient
>> with your first post.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > ---
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > You received this message because you are subscribed to the Google
>> Groups "ClojureScript" group.
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > To unsubscribe from this group and stop receiving emails from it,
>> send an email to [email protected].
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > To post to this group, send email to [email protected].
>> >
>> > >
>> >
>> > > >
>> >
>> > >
>> >
>> > > > Visit this group at http://groups.google.com/group/clojurescript.
>>
>> --
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "ClojureScript" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To post to this group, send email to [email protected].
>> Visit this group at http://groups.google.com/group/clojurescript.
>>
>
> --
> Note that posts from new members are moderated - please be patient with
> your first post.
> ---
> You received this message because you are subscribed to the Google Groups
> "ClojureScript" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/clojurescript.
>
--
Note that posts from new members are moderated - please be patient with your
first post.
---
You received this message because you are subscribed to the Google Groups
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.