Mini To-Do List MVP in Nextjournal

Instructions: To start the mini to-do list app, run all the cells in this notebook once. Control-Alt-Enter will evaluate all the cells, or click on the dropdown caret next to the triangle play button, and select 'Run all' from the dropdown options. The app interface will appear below the code cell with the contents [g-todo-app] inside.

Original Inspiration: Hiccup/Reagent demo by OrgPad

Version of this tiny app in Klipse

Version of this tiny app in Maria Dot Cloud

{:deps {org.clojure/clojure {:mvn/version "1.10.3"}
        ;; complient is used for autocompletion
        ;; add your libs here (and restart the runtime to pick up changes)
        compliment/compliment {:mvn/version "0.3.9"}}}
Extensible Data Notation
(def g-todos (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}]))
(def g-done-items (atom #{0}))
(def g-input-val (atom ""))
(defn g-todo-app []
  "Renders a list of all todos.
  Done todos are crossed.
  Deleted todos are hidden from display."
  (let []
    (fn []
      (let [dummy1 @g-todos
            dummy2 @g-done-items]
      [:section {:style {:margin "0"}}
   [:span {:style {:font-weight 600}} "List of todos for today:"]
   [:ul
    (for [todo @g-todos]
      (when (not (:deleted todo))
      ^{:key (:id todo)}
      [:li (when (contains? @g-done-items (:id todo))
             {:style {:text-decoration "line-through"}}) 
       [:span {:style {:margin-right "0.25em"}} (:text todo)]
       (if (contains? @g-done-items (:id todo))
         [:button
          {:on-click #(swap! g-done-items disj (:id todo))
             :style {:padding "0.25em" 
                     :margin-bottom "0.5em"}} "↺"]
         [:button
            {:on-click #(swap! g-done-items conj (:id todo))
             :style {:padding "0.25em" 
                     :margin-bottom "0.5em"}} "✔"])
       [:button
            {:on-click #(swap! g-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 @g-input-val
            :on-change #(reset! g-input-val (-> % .-target .-value))}]
   [:button 
    {:on-click #(let [new-todo {:text @g-input-val
                                :id (count @g-todos)}]
                     (swap! g-todos conj new-todo)
                     (reset! g-input-val ""))} "Add item"]
   ]))))
^{:nextjournal/viewer :reagent}
[g-todo-app]

Room For Improvement

  • Add padding to 'Add item' button

  • Enable 'submit on pressing Enter' behavior for input field

  • Add sources and links to original code inspiration, Klipse version, Maria Dot Cloud version, etc..

Runtimes (2)