Last active
May 13, 2016 21:26
-
-
Save mattyulrich/8524ce8f20606e644770205021875639 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 cljs-problem.app | |
(:require | |
[goog.dom :as gdom] | |
[om.next :as om :refer-macros [defui]] | |
[om.dom :as dom] | |
[ajax.core :refer [POST]])) | |
(enable-console-print!) | |
;(def target-app-state {:current-user {:user-id 123 :user-name "John"} | |
; :selected-class {:class-id 1 :class-name "Learning Om" | |
; :teacher {:user-id 456 :user-name "Fred"} | |
; :students [{:user-id 789 :user-name "Jill"} | |
; {:user-id 963 :user-name "Mary"}]} | |
; :classes | |
; [{:class-id 1 :class-name "Learning Om" | |
; :teacher {:user-id 456 :user-name "Fred"} | |
; :students [{:user-id 789 :user-name "Jill"} | |
; {:user-id 963 :user-name "Mary"}]} | |
; {:class-id 2 :class-name "Not Being Confused" | |
; :teacher {:user-id 246 :user-name "Jane"} | |
; :students [{:user-id 867 :user-name "Carl"} | |
; {:user-id 309 :user-name "Gretchen"}]}] | |
; }) | |
(def initial-app-state {}) | |
(defonce initial-state (atom initial-app-state)) | |
(defmulti read om/dispatch) | |
(defmulti mutate om/dispatch) | |
(def parser (om/parser {:read read :mutate mutate})) | |
(def reconciler (om/reconciler {:state initial-state | |
:parser parser})) | |
(defn ajax-result-for-user-classes | |
[] | |
(let [user-classes [{:class-id 1 :class-name "Learning Om" | |
:teacher {:user-id 456 :user-name "Fred"} | |
:students [{:user-id 789 :user-name "Jill"} | |
{:user-id 963 :user-name "Mary"}]} | |
{:class-id 2 :class-name "Not Being Confused" | |
:teacher {:user-id 246 :user-name "Jane"} | |
:students [{:user-id 867 :user-name "Carl"} | |
{:user-id 309 :user-name "Gretchen"}]}]] | |
(om/transact! reconciler `[(classes/set-classes {:classes-for-user ~user-classes}) :classes]))) | |
(defn ajax-result-for-user | |
[e] | |
(let [current-user {:user-id 123 :user-name "John"}] | |
(om/transact! reconciler `[(users/set-current-user {:new-current-user ~current-user}) :current-user]) | |
(ajax-result-for-user-classes))) | |
(defui Login-Button | |
Object | |
(render [this] | |
(dom/button #js {:className "btn btn-primary" :onClick ajax-result-for-user} "Login"))) | |
(def login (om/factory Login-Button)) | |
(defui Hello-Current-User | |
Object | |
(render [this] | |
(let [{:keys [user-name]} (om/props this)] | |
(dom/span #js {:className "lead"} (str "Hello " user-name "!"))))) | |
(def hello (om/factory Hello-Current-User)) | |
(defui Header | |
Object | |
(render [this] | |
(let [current-user (om/props this)] | |
(dom/header #js {:className "navbar navbar-default navbar-fixed-top"} | |
(dom/div #js {:className "container-fluid"} | |
(dom/div #js {:className "nav navbar-header navbar-left"} | |
(dom/h2 nil "CLJS Test")) | |
(dom/div #js {:className "nav navbar-header navbar-right"} | |
(dom/div nil | |
(if (= :not-found current-user) | |
(login) | |
(hello current-user))))))))) | |
(def header-component (om/factory Header)) | |
(defui User | |
static om/Ident | |
(ident [this {:keys [user-id]}] | |
[:user/by-id user-id]) | |
static om/IQuery | |
(query [this] | |
[:user-id :user-name]) | |
Object | |
(render [this] | |
(let [{:keys [user-name]} (om/props this)] | |
(dom/span nil user-name)))) | |
(def user-component (om/factory User {:keyfn :user-id})) | |
(defui Class | |
static om/Ident | |
(ident [this {:keys [class-id]}] | |
[:class/by-id class-id]) | |
static om/IQuery | |
(query [this] | |
[:class-id :class-name | |
{:teacher (om/get-query User)} | |
{:students (om/get-query User)}]) | |
Object | |
(render [this] | |
(let [{:keys [class-id class-name teacher students]} (om/props this)] | |
(dom/div nil | |
(dom/div nil | |
(dom/div nil (dom/span nil "Class Id:") | |
(dom/span nil class-id)) | |
(dom/div nil (dom/span nil "Class Name:") | |
(dom/span nil class-name)) | |
(dom/div nil (dom/span nil "Teacher: ") | |
(user-component teacher)) | |
(dom/div nil (dom/span nil "Students: ") | |
(dom/ol nil | |
(map-indexed (fn [idx student] | |
(dom/li #js {:key (str "stid-" idx)} (user-component student))) | |
students)))))))) | |
(def class-component (om/factory Class {:keyfn :class-id})) | |
(defui Class-Select-Option | |
Object | |
(render [this] | |
(let [{:keys [class-id class-name]} (om/props this)] | |
(dom/option #js {:value class-id} class-name)))) | |
(def class-option (om/factory Class-Select-Option {:keyfn :class-id})) | |
(defn select-class | |
[component event] | |
(let [val (.-value (.-target event))] | |
(if (= val "unsel") | |
(om/transact! component `[(classes/unchoose-class) :selected-class]) | |
(let [class-id (js/parseInt val 10)] | |
(om/transact! component `[(classes/choose-class {:new-selected-class ~class-id}) :selected-class]))))) | |
(defui Class-Select | |
Object | |
(render [this] | |
(let [classes (om/props this) | |
{:keys [select-option-fn]} (om/get-computed this)] | |
(dom/div nil | |
(if (= :not-found classes) | |
(dom/div nil "No Classes") | |
(dom/div nil | |
(dom/select #js {:onChange select-option-fn} | |
(dom/option #js {:value "unsel"} "Please select a class: ") | |
(map #(class-option %) classes)))))))) | |
(def class-select-component (om/factory Class-Select)) | |
(defui App | |
static om/IQuery | |
(query [this] | |
[{:current-user (om/get-query User)} | |
{:classes (om/get-query Class)} | |
{:selected-class (om/get-query Class)} | |
]) | |
Object | |
(render [this] | |
(let [{:keys [current-user classes selected-class]} (om/props this)] | |
(dom/div nil | |
(header-component current-user) | |
(dom/div #js {:className "offset-top"} | |
(if (= classes :not-found) | |
(dom/div nil nil) | |
(class-select-component (om/computed classes {:select-option-fn (partial select-class this)}))) | |
(if (= selected-class :not-found) | |
(dom/div nil nil) | |
(class-component selected-class))))))) | |
(defmethod read :current-user | |
[{:keys [state query]} key _] | |
(let [st @state] | |
(if (nil? (get st key)) | |
{:value :not-found} | |
(let [val (om/db->tree query (get st key) st)] | |
{:value val})))) | |
(defmethod read :classes | |
[{:keys [state query]} key _] | |
(let [st @state] | |
(if (nil? (get st key)) | |
{:value :not-found} | |
(let [val (om/db->tree query (get st key) st)] | |
{:value val})))) | |
(defmethod read :selected-class | |
[{:keys [state query]} key _] | |
(let [st @state] | |
(if (nil? (get st key)) | |
{:value :not-found} | |
(let [val (om/db->tree query (get st key) st)] | |
{:value val})))) | |
(defmethod mutate 'users/set-current-user | |
[{:keys [state]} _ {:keys [new-current-user]}] | |
(let [db-vals (om/tree->db App {:current-user new-current-user} true)] | |
{:value :current-user | |
:action #(swap! state merge db-vals)})) | |
(defmethod mutate 'classes/set-classes | |
[{:keys [state]} _ {:keys [classes-for-user]}] | |
(let [db-vals (om/tree->db App {:classes classes-for-user} true)] | |
{:value :classes | |
:action #(swap! state merge db-vals)})) | |
(defmethod mutate 'classes/unchoose-class | |
[{:keys [state]} _ _] | |
{:value :selected-class | |
:action #(swap! state dissoc :selected-class)}) | |
(defmethod mutate 'classes/choose-class | |
[{:keys [state]} _ {:keys [new-selected-class]}] | |
{:value :selected-class | |
:action #(swap! state assoc :selected-class [:class/by-id new-selected-class])}) | |
(om/add-root! reconciler App (gdom/getElement "app")) |
anmonteiro
commented
May 13, 2016
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment