Skip to content

Instantly share code, notes, and snippets.

@noprompt
Created January 19, 2014 23:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save noprompt/8512620 to your computer and use it in GitHub Desktop.
Save noprompt/8512620 to your computer and use it in GitHub Desktop.
(ns ingredient.core
(:require [clojure.browser.repl]
[om.core :as om :include-macros true]
[sablono.core :as html :refer [html] :include-macros true]
[cljs.core.async :refer [put! chan close! sliding-buffer]])
(:require-macros [cljs.core.async.macros :refer [go]]))
(enable-console-print!)
(def app-state
(atom {:posts [{:id 1 :title "Foo"}
{:id 2 :title "Bar"}
{:id 3 :title "Baz"}
{:id 4 :title "Quux"}]}))
(defn sortable-thead [data owner opts]
(let [{:keys [fields ch]} opts]
(om/component
(html
[:thead
[:tr
(for [field fields]
[:th (name field)
[:button {:onClick
(fn [_]
(put! ch {:field field, :direction :ascending}))}
"Ascending"]
[:button {:onClick
(fn [_]
(put! ch {:field field, :direction :descending}))}
"Descending"]])]]))))
(defn post-table [data owner]
(let [sort-posts (fn [posts]
(let [key (or (om/get-state owner :sort-key)
identity)
f (if (= (om/get-state owner :sort-direction)
:descending)
reverse
identity)]
(f (sort-by key posts))))]
(reify
om/IInitState
(init-state [_]
{:sort-key :id
:sort-direction :ascending
:ch (chan (sliding-buffer 1))})
om/IWillMount
(will-mount [_]
(go (while true
(let [{:keys [field direction]} (<! (om/get-state owner :ch))]
(om/set-state! owner :sort-key field)
(om/set-state! owner :sort-direction direction)))))
om/IRender
(render [_]
(html
[:table
(om/build sortable-thead data
{:opts {:fields [:id :title]
:ch (om/get-state owner :ch)}})
[:tbody
(for [post (sort-posts (:posts data))]
[:tr
[:td (:id post)]
[:td (:title post)]])]]))
om/IWillUnmount
(will-unmount [_]
(comment
;; This will lock up the browser.
(close! (om/get-state owner :ch)))))))
(defn hello-world [_ _]
(om/component
(html [:h1 "Hello World"])))
(defn show-page [data owner]
(reify
om/IInitState
(init-state [_]
{:page :posts})
om/IRender
(render [_]
(html
[:div
[:button {:onClick (fn [_] (om/set-state! owner :page :posts))}
"Posts"]
[:button {:onClick (fn [_] (om/set-state! owner :page :hello-world))}
"Hello"]
(case (om/get-state owner :page)
:posts (om/build post-table data)
(om/build hello-world data))]))))
(defn app []
(om/root
app-state
(fn [data owner]
(om/component
(html
[:div
(om/build show-page data)])))
(js/document.getElementById "app")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment