-
-
Save leontalbot/1d57bb05c063a989757c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns ^:figwheel-always form.core | |
(:require | |
[goog.dom :as gdom] | |
[om.next :as om :refer-macros [defui]] | |
[om.dom :as dom] | |
[cljs.pprint :as pp])) | |
(enable-console-print!) | |
(def app-state | |
(atom | |
{:poll/questions | |
[{:id :interest | |
:type "radio" | |
:label "Rate your interest in buying this house" | |
:a [{:value "1" :label "1"} | |
{:value "2" :label "2"} | |
{:value "3" :label "3"} | |
{:value "4" :label "4"} | |
{:value "5" :label "5"}]} | |
{:id :reason | |
:type "checkbox" | |
:label "Why aren't you interested?" | |
:a [{:value "already" :label "I just bought a house recently"} | |
{:value "alternative" :label "I'm am looking for something else"}]} | |
{:id :shipping-date | |
:type "checkbox" | |
:label "When would you be interested in moving in?" | |
:a [{:value "2016-july" :label "July 2016"} | |
{:value "2016-fall" :label "Fall 2016"}]}] | |
:user/selections {}})) | |
;; ----------------------------------------------------------------------------- | |
;; Helpers | |
(defn k->s | |
"keyword to string" | |
[k] | |
(->> k str rest (apply str))) | |
;; ----------------------------------------------------------------------------- | |
;; Parsing | |
(defmulti read om/dispatch) | |
(defmethod read :default | |
[{:keys [state] :as env} key params] | |
(let [st @state] | |
(if-let [[_ value] (find st key)] | |
{:value value} | |
{:value :not-found}))) | |
(defmethod read :poll/questions | |
;; I want to update the view so I can see more questions when a radio button | |
;; in question :interest is toggled. | |
[{:keys [state]} key {:keys [type id label a]}] | |
(let [st @state] | |
{:value (let [ids (condp some [(-> st :user/selections :interest)] | |
#{"1" "2"} [:interest :reason] | |
#{"3" "4" "5"} [:interest :shipping-date] | |
[:interest])] | |
(filterv #(some (fn [id] (= id (:id %))) ids) (:poll/questions st)))})) | |
(defmulti mutate om/dispatch) | |
(defmethod mutate 'selections/update-radio | |
;; This should update the users selections when radio button is toggled | |
[{:keys [state]} key {:keys [name value]}] | |
{:value [:poll/questions] | |
:action | |
(fn [] | |
(swap! state assoc-in [:user/selections name] value) | |
(pp/pprint @state))}) | |
;; ----------------------------------------------------------------------------- | |
;; Components | |
(defui Question | |
static om/Ident | |
(ident [this {:keys [id]}] | |
[:questions/by-id id]) | |
static om/IQuery | |
(query [this] | |
'[:id :type :label :a]) | |
Object | |
(render [this] | |
(println "Render Question " (-> this om/props :id)) | |
(let [{:keys [type id label a] :as props} (om/props this)] | |
(dom/div nil | |
(dom/h3 nil label) | |
(apply dom/div nil | |
(map | |
(fn [{:keys [label value]}] | |
(let [name (k->s id)] | |
(dom/label nil | |
(dom/input | |
#js {:type type | |
:name name | |
:value value | |
:onChange | |
(fn [e] | |
(om/transact! | |
this | |
`[(selections/update-radio | |
{:name ~id :value ~value} | |
:poll/questions)]))}) | |
label))) | |
a)))))) | |
(def question (om/factory Question {:keyfn :id})) | |
(defui Form | |
static om/IQuery | |
(query [this] | |
(let [subquery (om/get-query Question)] | |
`[{:poll/questions ~subquery} :user/selections])) | |
Object | |
(render [this] | |
(println "Render Form") | |
(let [{:keys [poll/questions user/selections] :as props} (om/props this)] | |
(dom/form #js {:action "/new-houses"} | |
(apply dom/div nil | |
(map question questions)) | |
(dom/input #js {:type "submit" :value "Send"}) | |
(dom/p nil (str "state: user/selections: " (om/props this))))))) | |
;; ----------------------------------------------------------------------------- | |
;; Reconciler | |
(def parser (om/parser {:read read :mutate mutate})) | |
(def reconciler | |
(om/reconciler | |
{:state app-state | |
:parser parser})) | |
(om/add-root! reconciler | |
Form (gdom/getElement "app")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Needed to move the
:poll/questions
out of the()
in thetransact!
call.[(selections/update-radio {:name ~id :value ~value}) :poll/questions]
is what we want to pass in.