Progress Bar
Subscribe to a paid plan to get instant access to this lesson.
Download  Video time: 29m38s

Progress Bar

Try it out yourself (editable code)


(ns student.progress-bar
  (:require [reagent.core :as reagent]
            [re-frame.core :as rf]))

(rf/reg-event-db
  :initialize
  (fn [_ _]
    {}))

(defn ui []
  [:div
   "23.3%"])

(defonce _init (rf/dispatch-sync [:initialize]))
(reagent/render [ui] (js/document.getElementById "student-container"))

Here's my version (editable code)


(ns teacher.progress-bar
  (:require [reagent.core :as reagent]
            [re-frame.core :as rf]))

(rf/reg-event-db
  :initialize
  (fn [_ _]
    {:done 0 :total 100}))

(rf/reg-event-db
  :set-total
  (fn [db [_ total]]
    (assoc db :total total :done 0)))

(rf/reg-event-db
  :inc-done
  (fn [db [_ done]]
    (if (>= (+ done (:done db)) (:total db))
      (assoc db :done (:total db))
      (update db :done + done))))

(rf/dispatch-sync [:set-total 100])

(defonce _interval (js/setInterval
                    #(rf/dispatch-sync [:inc-done 3])
                    1000))

(rf/reg-sub
  :total
  (fn [db] (:total db)))

(rf/reg-sub
  :done
  (fn [db] (:done db)))

(defn progress [done]
  (let [s (reagent/atom {})]
    (fn [done]
      (let [done (str (.toFixed (* 100 done) 1) "%")]
        [:div {:style {:position :relative
                       :line-height "1.3em"}}
         [:div {:style {:background-color :green 
                        :top 0
                        :bottom 0
                        :transition "width 0.1s"
                        :width done
                        :position :absolute
                        :overflow :hidden}}
          [:span {:style {:margin-left (:left @s)
                          :color :white}}
           done]]
         [:div {:style {:text-align :center}}
          [:span 
           {:ref #(if %
                    (swap! s assoc :left (.-offsetLeft %))
                    (swap! s assoc :left 0))}
           done]]]))))

(defn ui []
  [:div
   [progress (/ @(rf/subscribe [:done]) @(rf/subscribe [:total]))]])

(defonce _init (rf/dispatch-sync [:initialize]))
(reagent/render [ui] (js/document.getElementById "teacher-container"))

Next lesson: Password Box

We live code a reusable password box with validation and lots of user feedback component in ClojureScript with re-frame. Read more.

Progress Bar