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.

roboli
  • 1,418
  • 20
  • 24

2 Answers2

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).

Anna Pawlicka
  • 757
  • 7
  • 22
  • 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)... – roboli Jul 14 '14 at 11:48
  • 1
    Everything is kebab case in Om world :-) – Anna Pawlicka Jul 14 '14 at 13:07
  • @AnnaPawlicka Not quite "everything" is kebab-case: :className and :onClick (though I use om-tools, which lets me write :class and :on-click :-P) –  Aug 16 '14 at 18:32
  • She's using sablono, which normalizes names as well: https://github.com/r0man/sablono#html-attributes – Jorge Israel Peña Aug 17 '14 at 07:26
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.

Sam Ritchie
  • 10,988
  • 4
  • 42
  • 53