Created
May 24, 2015 07:00
-
-
Save hugooliveirad/34833b4f023c664f2f9a to your computer and use it in GitHub Desktop.
My first 100 lines of ClojureScript
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 ^:figwheel-always om-tut.core | |
(:require-macros [cljs.core.async.macros :refer [go]]) | |
(:require [om.core :as om :include-macros true] | |
[om.dom :as dom :include-macros true] | |
[cljs.core.async :refer [put! chan <!]] | |
[clojure.data :as data] | |
[clojure.string :as string])) | |
(enable-console-print!) | |
(println "Edits to this text should show up in your developer console.") | |
;; define your app data so that it doesn't get over-written on reload | |
(defonce app-state | |
(atom | |
{:contacts | |
[{:first "Ben" :last "Bitdiddle" :email "[email protected]"} | |
{:first "Alyssa" :middle-initial "P" :last "Hacker" :email "[email protected]"} | |
{:first "Eva" :middle "Lu" :last "Ator" :email "[email protected]"} | |
{:first "Louis" :last "Reasoner" :email "[email protected]"} | |
{:first "Cy" :middle-initial "D" :last "Effect" :email "[email protected]"} | |
{:first "Lem" :middle-initial "E" :last "Tweakit" :email "[email protected]"}]})) | |
(defn parse-contact [contact-str] | |
(let [[first middle last :as parts] (string/split contact-str #"\s+") | |
[first last middle] (if (nil? last) [first middle] [first last middle]) | |
middle (when middle (string/replace middle "." "")) | |
c (if middle (count middle) 0)] | |
(when (>= (count parts) 2) | |
(cond-> {:first first :last last} | |
(== c 1) (assoc :middle-initial middle) | |
(>= c 2) (assoc :middle middle))))) | |
(defn add-contact [data owner] | |
(let [new-contact (-> (om/get-node owner "new-contact") | |
.-value | |
parse-contact)] | |
(when new-contact | |
(om/transact! data :contacts #(conj % new-contact)) | |
(om/set-state! owner :text "")))) | |
(defn middle-name [{:keys [middle middle-initial]}] | |
(cond | |
middle (str " " middle) | |
middle-initial (str " " middle-initial "."))) | |
(defn display-name [{:keys [first last] :as contact}] | |
(str last ", " first (middle-name contact))) | |
(defn handle-change [e owner {:keys [text]}] | |
(let [value (.. e -target -value)] | |
(if-not (re-find #"[0-9]" value) | |
(om/set-state! owner :text value) | |
(om/set-state! owner :text text)))) | |
(defn contact-view [contact owner] | |
(reify | |
om/IRenderState | |
(render-state [this {:keys [delete]}] | |
(dom/li nil | |
(dom/span nil (display-name contact)) | |
(dom/button #js {:onClick (fn [e] (put! delete @contact))} "Delete"))))) | |
(defn contacts-view [data owner] | |
(reify | |
om/IInitState | |
(init-state [_] | |
{:delete (chan)} | |
{:text ""}) | |
om/IWillMount | |
(will-mount [_] | |
(let [delete (om/get-state owner :delete)] | |
(go (loop [] | |
(let [contact (<! delete)] | |
(om/transact! data :contacts | |
(fn [xs] (vec (remove #(= contact %) xs)))) | |
(recur)))))) | |
om/IRenderState | |
(render-state [this state] | |
(dom/div nil | |
(dom/h2 nil "Contact list") | |
(apply dom/ul nil | |
(om/build-all contact-view (:contacts data) | |
{:init-state state})) | |
(dom/div nil | |
(dom/input #js {:type "text" :ref "new-contact" :value (:text state) | |
:onChange #(handle-change % owner state)}) | |
(dom/button #js {:onClick #(add-contact data owner)} "Add contact")))))) | |
(om/root contacts-view app-state | |
{:target (. js/document (getElementById "contacts"))}) | |
(defn on-js-reload [] | |
;; optionally touch your app-state to force rerendering depending on | |
;; your application | |
;; (swap! app-state update-in [:__figwheel_counter] inc) | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment