Steve
Steve

Reputation: 11

Reagent/ClojureScript - multiple component aspect updates

I have a select component which shows a label and the associated options. There is a separate 'language' select which should choose the language of the display. On change it updates both @language which choses the label language and @search-language-options which provides the options to the select. The label updates as expected, but the options list does not - it remains as originally initialised.

;; search-languages -> vector
;; return the languages referenced in the data for options use

(defn search-languages []
  (let [options (list (tr {:dict ld} [@language :en] [:choice-any]))]
  (if (= @language :or) (concat options (vec (set (map (partial get-field "lang") parsed-json))))
    (concat options (vec (set (map (partial get-field "langTranslated") parsed-json)))))))

(def search-language-options (r/atom (search-languages)))

;; filter component -> component
;; create a select
(defn select-filter-component [label value options]
  [:div {:class "form-group"}
  [:label {:class "control-label" :for label} label]
  [:select {:id label :class "form-control" :value @value :on-change #(reset! value (-> % .-target .-value))}
    (for [opt options]
      ^{:key opt} [:option {:value opt} opt])]])

;; lang-select -> component
;; choose display language 
(defn lang-select []
[:div {:class "form-control" }
  [:select {:id :en :value @language :on-change (fn [e]
    (reset! language (.. e -target -value))
    (reset! search-language-options (search-languages)))
    }
  ^{:key :en} [:option {:value :en} "English"]
  ^{:key :fr} [:option {:value :fr} "Français"]
  ^{:key :es} [:option {:value :es} "Español"]
  ^{:key :or} [:option {:value :or} "Original language"]
  ]])

;; filter form
;; filter the results
(defn filter-form []

[:form {:class "form-inline"}
[search-filter-component (tr {:dict ld} [@language :en] [:search] ) search-text]

[select-filter-component (tr {:dict ld} [@language :en] [:language] ) search-language @search-language-options]
[select-filter-component (tr {:dict ld} [@language :en] [:gender] ) gender ["Any" "M" "F"]]
[select-filter-component (tr {:dict ld} [@language :en] [:continent/title] ) continent ["Any" "Europe"]]
[select-filter-component (tr {:dict ld} [@language :en] [:country] ) placeTranslated ["Any" "Austria" "Switzerland" "Germany"]]
[select-filter-component (tr {:dict ld} [@language :en] [:literaryForm] ) literaryForm ["Any" "Drama" "Poetry" "Prose: fiction" "Prose: non-fiction" ]]
[select-filter-component (tr {:dict ld} [@language :en] [:genre] ) genre ["Any" "Short story" "Novella" "Graphic Novel"]]
[reset-button]]

)

Upvotes: 1

Views: 310

Answers (1)

Justin L.
Justin L.

Reputation: 387

Do you mean that the [:option...] elements in select-filter-component don't change? If that's what you mean, it is hard to tell from the code posted why they don't change because those options are rendered based on the props passed into select-filter-component, and you haven't shown how you are calling select-filter-component. Specifically this code is completely dependent on the options prop passed in:

(for [opt options]
   ^{:key opt} [:option {:value opt} opt])

(Side note: though it doesn't matter here, note that for is lazy, so if you ever reference an atom in a for note that you'll have to wrap it in a doall or the atom won't be referenced during rendering and your component won't update when the atom updates.)

If you mean that selecting different options with the mouse doesn't work, then that is because you have commented out the on-change handler.

Upvotes: 0

Related Questions