I'm using Om/Sente/Sablono and working with dynamic menus. Here's my navigation component (like your dropdown):
(defn navigation
"Primary navigation."
[app-state self]
(reify
om/IRenderState
(render-state [this state]
(html [:div {:id "main-nav"}
[:div {:id "env"}
(when (:environment app-state)
(get-in app-state [:environment :name]))]
[:div {:id "nav-items"}
(into [:ul] (map (nav-item app-state)
(nav-menu app-state)))]
[:div {:style {:clear "both"}}]]))))
nav-item builds the actual HTML along with selecting the currently active
element:
(defn nav-item
[app-state]
(fn [{:keys [item label key]}]
[:li {:class (nav-selected app-state item) :id (str "menu-" key)
:on-click (fn [e] (om/update! app-state :nav/state item))}
label]))
And nav-menu extracts the sequence of items from the app-state, each as a map
of value (item) / name (label) and React key - in my case so I can ensure all
the elements in the sequence of :li's are unique.
I do a similar thing in another component to build a drop-down list:
(defn upstream-app
... lots of stuff omitted ...
[:div
[:div "Select a tier to work on:"]
(into [:select {:on-change #(om/update! app-state
[:upstream :tier :name]
(keyword (..
% -target -value)))
:value (get-in app-state [:upstream
:tier :name])}]
(cons [:option {:value nil} "-- select --"]
(map tier-option (get-in app-state
[:environment :tiers]))))])))))
Hope that helps?
Sean
On Sep 4, 2014, at 7:50 PM, Tom George <[email protected]> wrote:
> I'm doing my first real work in clojurescript/om. I have a little web
> service that queries a database and returns a JSON message of all known
> schema owners. I want to use this data source to populate a dropdown.
>
> The demo page for om-bootstrap is really nice, but in the examples for
> populating a dropdown, the menu-items are known beforehand, so they just nest
> a lot of (menu-item) calls. I won't know the size of my dropdown until I hit
> the database, and I don't want to spell out each individual menu item.... Is
> there a better way to do this? I was thinking maybe creating a map of
> number-string pairs, where the keys are menu item keys, and the values are
> the schema owners. However, I can't think of how I would get around
> specifying each individual menu item. I tried mapping the menu-item function
> to no avail.
>
> The relevant clojurescript looks like this right now:
>
> (ns junk-browser.core
> (:require-macros [cljs.core.async.macros :refer [go]])
> (:require [cljs.core.async :refer [>! <! chan close!]]
> [om.core :as om :include-macros true]
> [om.dom :as dom :include-macros true]
> [om-bootstrap.button :as b]
> [cljs-http.client :as http]))
>
>
> (defn schema-dropdown [app owner]
> (reify
> om/IInitState
> (init-state [_]
> {:owners []})
> om/IWillMount
> (will-mount [_]
> (go
> (let [owners (into [] (<! (schema-owners)))] ; (schema-owners) is a
> cljs-http GET
> (om/update-state! owner #(assoc % :owners owners)))))
> om/IRenderState
> (render-state [ _ state]
> (dom/div nil
> (b/dropdown {:title "Schema Owners"}
> (b/menu-item {:key 1} (nth (:owners state) 0
> :not-found
> ...
> (b/menu-item {:key n} (nth (:owners state) n-1
> :not-found)))))))
>
>
>
> Any ideas on how I can tackle this in a better way?
signature.asc
Description: Message signed with OpenPGP using GPGMail
