Skip to content

Instantly share code, notes, and snippets.

@CatTail
Last active September 22, 2015 10:25
Show Gist options
  • Save CatTail/80a2b9efe149eb635b99 to your computer and use it in GitHub Desktop.
Save CatTail/80a2b9efe149eb635b99 to your computer and use it in GitHub Desktop.
Clojure script and https://github.com/omcljs/om/ tryout
(defproject vote "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.6.0"]
[org.clojure/clojurescript "0.0-2755"]
[figwheel "0.2.2-SNAPSHOT"]
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
[sablono "0.2.22"]
[org.omcljs/om "0.8.6"]
[secretary "1.2.3"]
[cljs-ajax "0.3.11"]]
:plugins [[lein-cljsbuild "1.0.4"]
[lein-figwheel "0.2.2-SNAPSHOT"]]
:source-paths ["src"]
:clean-targets ^{:protect false} ["resources/public/js/compiled"]
:cljsbuild {
:builds [{:id "dev"
:source-paths ["src"]
:compiler {:output-to "resources/public/js/compiled/vote.js"
:output-dir "resources/public/js/compiled/out"
:optimizations :none
:main vote.core
:asset-path "js/compiled/out"
:source-map true
:source-map-timestamp true
:cache-analysis true }}
{:id "min"
:source-paths ["src"]
:compiler {:output-to "resources/public/js/compiled/vote.js"
:optimizations :advanced
:pretty-print false}}]}
:figwheel {
:http-server-root "public" ;; default and assumes "resources"
:server-port 3449 ;; default
:css-dirs ["resources/public/css"] ;; watch and update CSS
;; Server Ring Handler (optional)
;; if you want to embed a ring handler into the figwheel http-kit
;; server
;; :ring-handler hello_world.server/handler
;; To be able to open files in your editor from the heads up display
;; you will need to put a script on your path.
;; that script will have to take a file path and a line number
;; ie. in ~/bin/myfile-opener
;; #! /bin/sh
;; emacsclient -n +$2 $1
;;
;; :open-file-command "myfile-opener"
;; if you want to disable the REPL
;; :repl false
;; to configure a different figwheel logfile path
;; :server-logfile "tmp/logs/figwheel-logfile.log"
})
(ns vote.core
(:require [figwheel.client :as fw]
[om.core :as om :include-macros true]
[om.dom :as dom :include-macros true]
[secretary.core :as secretary :refer-macros [defroute]]
[goog.events :as events]
[goog.history.EventType :as EventType]
[ajax.core :refer [GET POST json-response-format]])
(:import goog.History))
(enable-console-print!)
(println "Edits to this text should show up in your developer console.")
(defonce app-state (atom {:current {} :votes {} :id ""}))
(def history (History.))
(defn debug [value]
(do
(println value)
value))
; fetch vote list
(GET "http://localhost:3000/vote"
{:response-format (json-response-format {:keywords? true})
:handler (fn [response]
(om/update! (om/root-cursor app-state) :votes
(apply merge
(map (fn [vote]
{(keyword (str (:id vote))) vote})
response))))})
(defn modify-choice [event data index owner]
(let [li (.-target event)]
(om/transact! data [:current :choices]
(fn [choices] (assoc choices index (.-textContent li))))))
(defn add-choice [event data owner]
(if (= (.-key event) "Enter")
(let [input (om/get-node owner "input") new-choice (.-value input)]
;; add choice have length
(if (> (.-length new-choice) 0)
(do
(om/transact! data [:current :choices] (fn [choices] (vec (conj choices new-choice))))
(set! (.-value input) ""))))))
(defn change-name [event data owner]
(let [li (.-target event)]
(om/update! data [:current :name] (.-value li))))
(defn add-vote [event data owner]
(let [current (:current data)]
(POST "http://localhost:3000/vote"
{:params current
:format :json
:handler (fn [response]
; add vote to vote list
(om/transact! data :votes (fn [votes]
(merge votes {(keyword (:id current)) current})))
(om/update! data :current {})
(set! (.-href js/location) "#/vote"))})))
(defn vote-view [vote owner]
(reify
om/IRender
(render [_]
(dom/div nil
(dom/h1 nil
(dom/a #js {:href (str "#/vote/" (:id vote))} (str (:name vote))))
(apply dom/ul nil
(map (fn [choice]
(dom/li nil (str choice)))
(:choices vote)))))))
(defn vote-page [data owner]
(reify
om/IRender
(render [_]
(str "hello world")
(debug data)
(dom/div nil
(let [vote (or
((keyword (:id data)) (:votes data))
{:choices []})]
(debug vote)
(om/build vote-view vote))))))
(defn create-page [data owner]
(reify
om/IRender
(render [_]
(if-not (:id (:current data))
(om/update! data :current {:id (.now js/Date) :name "somename!" :choices []}))
(dom/div nil
(dom/input #js {:placeholder "vote name" :onBlur #(change-name % data owner)})
(apply dom/ul nil
(map-indexed (fn [index choice]
(dom/li #js {:contentEditable "true"
:onBlur #(modify-choice % data index owner)}
(str choice))) (:choices (:current data))))
(dom/input #js {:ref "input" :placeholder "new choice" :onKeyPress #(add-choice % data owner)})
(dom/br nil)
(dom/input #js {:style #js {:backgroundColor "red"}
:type "button"
:value "create"
:onClick #(add-vote % data owner)})))))
(defn index-page [data owner]
(reify
om/IRender
(render [_]
(apply dom/div nil
(concat (map (fn [vote]
(om/build vote-view (second vote)))
(take 3 (:votes data)))
[(dom/a #js {:href "#/vote"} (str "all votes"))])))))
(defn votes-page [data owner]
(reify
om/IRender
(render [_]
(apply dom/div nil
(dom/a #js {:href "#/vote/create"} (str "create vote"))
(map (fn [vote]
(om/build vote-view (second vote)))
(:votes data))))))
(defroute "/" []
(om/root
index-page
app-state
{:target (. js/document (getElementById "app"))}))
(defroute "/vote" []
(om/root
votes-page
app-state
{:target (. js/document (getElementById "app"))}))
(defroute "/vote/create" []
(om/root
create-page
app-state
{:target (. js/document (getElementById "app"))}))
(defroute "/vote/:id" {:as params}
(om/update! (om/root-cursor app-state) :id (:id params))
(om/root
vote-page
app-state
{:target (. js/document (getElementById "app"))}))
(do
(goog.events/listen history EventType/NAVIGATE #(secretary/dispatch! (.-token %)))
(doto history (.setEnabled true)))
(fw/start {
:on-jsload (fn []
;; (stop-and-start-my app)
)})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment