Created
February 3, 2014 14:57
-
-
Save mpereira/03bd0a1c943a00cb30db to your computer and use it in GitHub Desktop.
This file contains hidden or 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 om-laboratory.core | |
(:require [om.core :as om :include-macros true] | |
[om.dom :as dom :include-macros true] | |
[clojure.string :as string])) | |
(enable-console-print!) | |
(defn index-of [coll val] | |
(first (keep-indexed #(if (= %2 val) %1) coll))) | |
(def application-state | |
(atom {:tasks [{:text "buy milk" :done true} | |
{:text "pay bills" :done true} | |
{:text "do statistics" :done false} | |
{:text "learn clojure properly" :done false}]})) | |
(defn task-text-form-view [props owner] | |
(defn class-names [] | |
(string/join " " (cons "task-text-form" (om/get-state owner :class-names)))) | |
(defn handle-on-submit! [event] | |
(.preventDefault event) | |
(let [input-node (om/get-node owner "task-text-input")] | |
(when-let [task-text (.-value input-node)] | |
(set! (.-value input-node) nil) | |
((om/get-state owner :on-submit!) {:text task-text | |
:done (get @props :done false)})))) | |
(reify | |
om/IRenderState | |
(render-state [this state] | |
(dom/form | |
#js {:className (class-names) :onSubmit handle-on-submit!} | |
(dom/input #js {:className "task-text-input" | |
:ref "task-text-input" | |
:name "task[text]" | |
:placeholder (get-in state [:input :placeholder]) | |
:required (get-in state [:input :required]) | |
:defaultValue (:text props)}))))) | |
(defn task-view [props owner] | |
(defn class-names [] | |
(string/join " " ["task" (if (:done props) "done")])) | |
(defn toggle-being-edited! [& [event]] | |
(if event (.preventDefault event)) | |
(om/set-state! owner :being-edited? (not (om/get-state owner :being-edited?)))) | |
(defn on-task-text-form-submit [task-delta] | |
(toggle-being-edited!) | |
((om/get-state owner :update-task!) @props task-delta)) | |
(defn update-task-done [event] | |
(.preventDefault event) | |
((om/get-state owner :update-task!) @props {:done (.-checked (.-target event))})) | |
(reify | |
om/IInitState | |
(init-state [this] | |
{:being-edited? false}) | |
om/IRenderState | |
(render-state [this {:keys [remove-task! being-edited?]}] | |
(apply | |
dom/li #js {:className (class-names)} | |
(cond | |
being-edited? [(om/build task-text-form-view | |
props | |
{:init-state | |
{:class-names ["update-task-text-form"] | |
:on-submit! on-task-text-form-submit}})] | |
:else [(dom/input #js {:className "task-done-input" | |
:onChange update-task-done | |
:type "checkbox" | |
:name "task[done]" | |
:checked (:done @props)}) | |
(dom/span #js {:className "text" | |
:onDoubleClick toggle-being-edited!} | |
(:text props)) | |
(dom/button #js {:className "delete" | |
:onClick #(remove-task! @props)} | |
"Delete")]))))) | |
(defn tasks-view [props owner] | |
(reify | |
om/IRenderState | |
(render-state [this state] | |
(apply | |
dom/ul #js {:className "tasks"} | |
(om/build-all | |
task-view | |
(:tasks props) | |
{:init-state (select-keys state [:remove-task! :update-task!])}))))) | |
(defn todo-application [props owner] | |
(defn remove-task! [task] | |
(om/transact! props :tasks #(into [] (remove (partial identical? task) %)))) | |
(defn create-task! [task] | |
(om/transact! props :tasks #(into [] (conj % task)))) | |
(defn update-task! [task task-delta] | |
(om/transact! | |
props | |
:tasks | |
#(into [] (assoc % (index-of % task) (merge task task-delta))))) | |
(reify | |
om/IRender | |
(render [this] | |
(dom/div | |
#js {:className "todo-application"} | |
(dom/h1 #js {:className "title"} "Todo") | |
(om/build task-text-form-view | |
props | |
{:init-state | |
{:class-names ["create-task-text-form"] | |
:on-submit! create-task! | |
:input {:placeholder "What needs to be done?" | |
:required true}}}) | |
(om/build tasks-view | |
props | |
{:init-state {:remove-task! remove-task! | |
:create-task! create-task! | |
:update-task! update-task!}}))))) | |
(om/root | |
application-state | |
todo-application | |
(. js/document (getElementById "application"))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment