Skip to content

Instantly share code, notes, and snippets.

@avidrucker
Last active March 16, 2023 14:13
Show Gist options
  • Save avidrucker/0fb9fb5fa3ce69ea95959725dab313dd to your computer and use it in GitHub Desktop.
Save avidrucker/0fb9fb5fa3ce69ea95959725dab313dd to your computer and use it in GitHub Desktop.
minimal Klipse to-do list app in ClojureScript with Reagent
;; Instructions:
;; 1. go to http://app.klipse.tech/?container=1
;; 2. Paste this entire gist into the upper left code window
;; 3. Wait 3 seconds for the code to evaluate - the to-do list app should appear in the upper right window
;; original program source: https://orgpad.com/o/BSZ05PGN1PMbIjmwIT3Vhs?s=clojure-tutorial
(require
'[reagent.core :as r]
'[reagent.dom :as r-dom])
(defn todo-app []
"Renders a list of all todos.
Done todos are crossed.
Deleted todos are hidden from display."
(let [todos (r/atom
[{:text "Start Clojure tutorial" :id 0}
{:text "Finish Clojure tutorial" :id 1}
{:text "Create a video for it" :id 2}
{:text "Fix bugs in OrgPad" :id 3}])
done-items (r/atom #{0})
input-val (r/atom "")]
(fn []
(let [dummy1 @todos
dummy2 @done-items]
[:section {:style {:margin "0"}}
[:span {:style {:font-weight 600}} "List of todos for today:"]
[:ul
(for [todo @todos]
(when (not (:deleted todo))
^{:key (:id todo)}
[:li (when (contains? @done-items (:id todo))
{:style {:text-decoration "line-through"}})
[:span {:style {:margin-right "0.25em"}} (:text todo)]
(if (contains? @done-items (:id todo))
[:button
;; TIL: How to remove items from a set in Clojure
{:on-click #(swap! done-items disj (:id todo))
:style {:padding "0.25em"
:margin-bottom "0.5em"}} "↺"]
[:button
{:on-click #(swap! done-items conj (:id todo))
:style {:padding "0.25em"
:margin-bottom "0.5em"}} "✔"])
[:button
{:on-click #(swap! todos update-in [(:id todo) :deleted] nil?)
:style {:padding "0.25em"
:margin-bottom "0.5em"}} "×"]
]))]
[:input {:type "text"
:placeholder "Enter new item text here"
:value @input-val
:on-change #(reset! input-val (-> % .-target .-value))}]
[:button
{:on-click #(let [new-todo {:text @input-val
:id (count @todos)}]
(swap! todos conj new-todo)
(reset! input-val ""))} "Add item"]
]))))
(r-dom/render [todo-app] js/klipse-container)
((todo-app))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment