Inline Editing Field
Subscribe to a paid plan to get instant access to this lesson.
28m58s  Download  Speed: 1x 1.25x 1.5x 2x

Inline Editing Field

Try it out yourself (editable code)


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

(rf/reg-event-db
  :initialize
  (fn [_ _]
    {:movies {"tt0095989"
              {:title "Return of the Killer Tomatoes!"
               :description "Crazy old Professor Gangreen has developed a way to make tomatoes look human for a second invasion."}}}))

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

(defn ui []
  [:div
   (for [[movie-id movie] @(rf/subscribe [:movies])]
     [:div {:key movie-id}
      [:h3 (:title movie)]
      [:div (:description movie)]])])

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

Here's my version (editable code)


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

(rf/reg-event-db
  :initialize
  (fn [_ _]
    {:movies {"tt0095989"
              {:title "Return of the Killer Tomatoes!"
               :description "Crazy old Professor Gangreen has developed a way to make tomatoes look human for a second invasion."}}}))

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

(rf/reg-event-db
  :movie/title
  (fn [db [_ id title]]
    (assoc-in db [:movies id :title] title)))

(rf/reg-event-db
  :movie/description
  (fn [db [_ id description]]
    (assoc-in db [:movies id :description] description)))

(defn inline-editor [txt on-change]
  (let [s (reagent/atom {})]
    (fn [txt on-change]
      [:span
       (if (:editing? @s)
         [:form {:on-submit #(do
                               (.preventDefault %)
                               (swap! s dissoc :editing?)
                               (when on-change
                                 (on-change (:text @s))))}
           [:input {:type :text :value (:text @s)
                    :on-change #(swap! s assoc 
                                     :text (-> % .-target .-value))}]
          [:button "Save"]
          [:button {:on-click #(do
                                 (.preventDefault %)
                                 (swap! s dissoc :editing?))}
           "Cancel"]]
         [:span 
           {:on-click #(swap! s assoc
                            :editing? true
                            :text txt)}
            txt [:sup "✎"]])])))

(defn ui []
  [:div
   (for [[movie-id movie] @(rf/subscribe [:movies])]
     [:div {:key movie-id}
      [:h3  [inline-editor (:title movie)
             #(rf/dispatch [:movie/title movie-id %])]]
      [:div [inline-editor (:description movie)
             #(rf/dispatch [:movie/description movie-id %])]]])])

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

Next lesson: Progress Bar

We live code a reusable progress bar component in ClojureScript with re-frame. Read more.

Inline Editing Field