3

I have just started using Reagent and am very new to Clojure.

I have created a mobile menu function and want the mobile hamburger menu to be clickable in order to show the actual menu. When clicked on again, the menu must hide. I have no idea how to do

(defn mobile-menu [primary-menu secondary-menu logo-el]
 [:div#ca-horizontal-mobile
  [:div#logo logo-el]
  [:div#menu-button
   [:a
    [:i.icon.bars]]]

  [:header#menu.mobile
   [:div
    [:div.center.menu
     (let [menu (concat primary-menu secondary-menu)]
       (for [i menu]
         [:div.item {:key (:key i)}
          [:a.item {:id   (:key i)
                    :href (:target i)} (:name i)]]))
     [:div.item
      [:a
       {:style    {:cursor :pointer}
        :id       :logout
        :on-click #(re-frame/dispatch [:logout])} (str "Logout")]]]]]])])

The anchor needs to expand and hide the menu.

   [:a
    [:i.icon.bars]]]

All I need is an example of how to make a JavaScript call on a JavaScript event and a little bit of help understanding it.

I found this snippet online https://www.reddit.com/r/Clojure/comments/4ofct5/calling_methods_on_an_element_in_a_reagent/ but am unsure how it hooks up to anything. How does the .play element know what to do on-click?

(defn video-elem [src-url uid]
  [:div
    [:video {:src src-url :id uid}]
        [:button {:on-click #(.play (.getElementById js/document uid))} "Play!"]
        [:button {:on-click #(.pause (.getElementById js/document uid))} "Pause!"]])
2
  • 1
    Looks like you answered your main question. The bit about the .play element works because 'video' is an instance of developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play so that code is just invoking that built-in method on the dom element. Commented Jul 17, 2018 at 14:57
  • That makes more sense now, thanks :) Commented Jul 17, 2018 at 17:31

1 Answer 1

3

With the help of a colleague we added the following. I am not sure if I have explained this correctly though.

(re-frame/reg-event-db
  :toggle-mobile-menu
  (fn [db _]
    (assoc db :mobile-menu-visible (not (:mobile-menu-visible db)))))
    
(re-frame/reg-sub :show-mobile-menu #(:mobile-menu-visible %))))

(defn mobile-menu [primary-menu secondary-menu logo-el]
  [:div#ca-horizontal-mobile
   [:div#logo logo-el]
   [:div#menu-button
    {:on-click #(re-frame/dispatch [:toggle-mobile-menu])}
    [:i.icon.bars]]
    
   (let [show-menu (re-frame/subscribe [:show-mobile-menu])]
     (if @show-menu
       [:header#menu.mobile
        [:div
         [:div.center.menu
          (let [menu (concat primary-menu secondary-menu)]
            (for [i menu]
              [:div.item {:key (:key i)}
               [:a.item {:id   (:key i)
                         :href (:target i)} (:name i)]]))
          [:div.item
           [:a
            {:style    {:cursor :pointer}
             :id       :logout
             :on-click #(re-frame/dispatch [:logout])} (str "Logout")]]]]]))])]])
  • The menu button click event dispatches a :toggle-mobile-menu re-frame/reg-event-db which toggles the visibility of the menu

  • The show_menu binding subscribes to the re-frame/reg-sub :show-menu-mobilewhich gets the:mobile-menu-visible` value from the db

  • The @show-menu value from the db is destructured to a truthy value indicating if the menu should be hidden or displayed.

Sign up to request clarification or add additional context in comments.

1 Comment

I like this solution. it's pretty idiomatic re-frame code. good job

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.