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.

Reply via email to