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

Progress Bar

We create a simple progress bar to track the progress of downloads and other processes. All you need is a percentage or a numerator and denominator.

We even do some cool DOM tricks to give it a nice professional look. Just try to do them in jQuery! I dare you!

Code is available: lispcast/building-re-frame-components

You can checkout the code in your local repo with this command:

$CMD git clone git@github.com:lispcast/building-re-frame-components.git
$CMD cd building-re-frame-components          

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

(rf/reg-event-db
  :initialize
  (fn [db _]
    (select-keys db (filter #(= "teacher" (namespace %)) (keys db)))))

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

(defonce _init (rf/dispatch-sync [:initialize]))
(reagent/render [ui] (js/document.getElementById "student-container"))            
          
Loading compiler
              
                (ns teacher.progress-bar
  (:require [reagent.core :as reagent]
            [re-frame.core :as rf]))

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

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

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

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

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

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

(rf/reg-sub
  :teacher/done
  (fn [db] (:teacher/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 [:teacher/done]) @(rf/subscribe [:teacher/total]))]])

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

Building Re-frame Components

Collapsible Panel free 25 min
Sortable Table 34 min
Inline Editable Field 29 min
Progress Bar 30 min
Password Box 26 min
Sortable Table in the Database 25 min
Tag Editor 26 min
Markdown Editor with Live Preview 9 min
Externally Managed Components 12 min
Accordion Component 27 min
Draggable List 36 min
Expanding Table 13 min
Filterable List 22 min
Username Box 1 hr
Username and Password Refactoring 22 min
User-Password Further Refactoring 17 min
User Registration 1 16 min
User Registration 2 28 min
User Registration 3 25 min
Next lesson:

Password Box