Using bootstrap dropdown with Om
Asked Answered
G

2

8

This is what I have:

(defn view [cursor owner]
  (reify
    om/IDidMount
    (did-mount [_]
      (-> (js/$ ".dropdown-toggle")
          (.dropdown)))

    om/IRender
    (render [_]
      (dom/div #js {:className "dropdown"}
               (dom/button #js {:className "btn btn-default dropdown-toggle"
                                :type "button"
                                :id "dropdownMenu1"} "Dropdown" (dom/span #js {:className "caret"}))
               (dom/ul #js {:className "dropdown-menu"
                            :role "menu"
                            :ariaLabelledby "dropdownMenu1"}
                       (dom/li #js {:role "presentation"}
                               (dom/a #js {:role "menuitem"
                                           :tabIndex "-1"
                                           :href "#"} "Action"))
                       (dom/li #js {:role "presentation"}
                               (dom/a #js {:role "menuitem"
                                           :tabIndex "-1"
                                           :href "#"} "Another action")))))))

The problem is that once the dropdown is opened, it does not hide anymore as it should be when one clicks on it or somewhere else. Also keystrokes don't work. I believe a missing something important here, what could it be? I'm using bootstrap 3.1.1 and jquery 1.11.0.

Thanks.

Gezira answered 12/7, 2014 at 1:47 Comment(0)
U
8

Here's what I do to create a dropdown component:

(defn dropdown [cursor owner {:keys [id text values]}]
 (om/component
   (html
     [:div.dropdown
       [:button {:type "button"
                 :class "btn dropdown-toggle"
                 :data-toggle "dropdown"
                 :id id}
                text
                [:span {:class "caret"}]]
       [:ul {:class "dropdown-menu" :role "menu" :aria-labelledby id}
         [:li {:role "presentation"}
           (for [v values] 
             [:a {:role "menuitem" :tabIndex "-1" :href "#"} v])]]])))

It hides when it should. I use jQuery 1.11.1, Bootstrap 3.2.0 and sablono for clarity but that doesn't affect anything. I don't think you should be using IDidMount for jQuery as all interaction is handled via bootstrap's dropdown JavaScript plugin (which is included in Bootstrap library).

Universal answered 13/7, 2014 at 12:5 Comment(4)
Thanks Anna! You're right, I don't need IDidMount. But also I was doing it wrong the whole time. Following ReactJs's convention I was trying with :dataToggle instead of :data-toggle. Thats why I was relying on javascript instead of data attributes (hence IDidMount)...Gezira
Everything is kebab case in Om world :-)Universal
@AnnaPawlicka Not quite "everything" is kebab-case: :className and :onClick (though I use om-tools, which lets me write :class and :on-click :-P)Doggy
She's using sablono, which normalizes names as well: github.com/r0man/sablono#html-attributesReseau
P
4

Another option is to use the Om-Bootstrap library that I wrote; there's a dropdown component that handles all of this state internally for you.

The dropdown becomes:

(:require [om-bootstrap.button :as b])

(b/toolbar
 {}
 (for [title ["Default" "Primary" "Success" "Info" "Warning" "Danger" "Link"]
       :let [style (.toLowerCase title)]]
   (b/dropdown {:bs-style style, :title title}
               (b/menu-item {:key 1} "Action")
               (b/menu-item {:key 2} "Another action")
               (b/menu-item {:key 3} "Something else here")
               (b/menu-item {:divider? true})
               (b/menu-item {:key 4} "Separated link"))))

The documentation site at http://om-bootstrap.herokuapp.com has examples and code snippets of how to use all of these components.

Pastern answered 10/12, 2014 at 16:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.