|  | @@ -19,8 +19,11 @@
 | 
	
		
			
				|  |  |                    {:row 11 :col "D" :value "2495"}
 | 
	
		
			
				|  |  |                    {:row 15 :col "E" :value "8968"}])
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +(def data-atom (r/atom sample-data))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  (defn highest [dir data] (apply max (map dir data)))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +; COLUMN NAMES
 | 
	
		
			
				|  |  |  (defn upgrade-letter-code [s]
 | 
	
		
			
				|  |  |    (let [l (last s)]
 | 
	
		
			
				|  |  |      (cond
 | 
	
	
		
			
				|  | @@ -31,12 +34,24 @@
 | 
	
		
			
				|  |  |    (apply str (map char (upgrade-letter-code (mapv #(.charCodeAt % 0) lc)))))
 | 
	
		
			
				|  |  |  (def col-letters (iterate next-letter "A"))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +; CHANGE VALUE FUNCTIONS
 | 
	
		
			
				|  |  | +(defn update-value [c r datum value]
 | 
	
		
			
				|  |  | +  (if (nil? datum)
 | 
	
		
			
				|  |  | +    (swap! data-atom conj {:row r :col c :value value})
 | 
	
		
			
				|  |  | +    (swap! data-atom (fn [d] (map #(if (and (= r (:row %)) (= c (:col %))) (assoc % :value value) %) d)))))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  ;; -------------------------
 | 
	
		
			
				|  |  |  ;; Views
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  (defn cell [c r data]
 | 
	
		
			
				|  |  |    (let [datum (some #(if (and (= c (:col %)) (= r (:row %))) %) data)]
 | 
	
		
			
				|  |  | -    ^{:key (str c r)} [:td (or (:value datum) "")])
 | 
	
		
			
				|  |  | +    ^{:key (str c r)} [:td [:input {:value (or (:value datum) "")
 | 
	
		
			
				|  |  | +                                    :on-change #(update-value c r datum (.. % -target -value))
 | 
	
		
			
				|  |  | +                                    :on-blur (fn [e] (println (str "blur! " c r)))
 | 
	
		
			
				|  |  | +                                    :on-focus (fn [e] (println (str "focus! " c r)))}]]
 | 
	
		
			
				|  |  | +    )
 | 
	
		
			
				|  |  |    )
 | 
	
		
			
				|  |  |  (defn row [r cols data]
 | 
	
		
			
				|  |  |    ^{:key (str "row-" r)} [:tr
 | 
	
	
		
			
				|  | @@ -52,7 +67,7 @@
 | 
	
		
			
				|  |  |  (defn sheet [data]
 | 
	
		
			
				|  |  |    [:table [:tbody
 | 
	
		
			
				|  |  |             (let [maxrow (highest :row data)
 | 
	
		
			
				|  |  | -                 cols (take-while (partial not= (next-letter (highest :col sample-data))) col-letters)]
 | 
	
		
			
				|  |  | +                 cols (take-while (partial not= (next-letter (highest :col data))) col-letters)]
 | 
	
		
			
				|  |  |               (cons
 | 
	
		
			
				|  |  |                 (header-row cols)
 | 
	
		
			
				|  |  |                 (map #(row % cols data) (range 1 (inc maxrow)))))
 | 
	
	
		
			
				|  | @@ -60,8 +75,8 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  (defn app []
 | 
	
		
			
				|  |  |    [:div
 | 
	
		
			
				|  |  | -   [:h3 "Microtable"]
 | 
	
		
			
				|  |  | -   [sheet sample-data]])
 | 
	
		
			
				|  |  | +   [:h3 "Microtables"]
 | 
	
		
			
				|  |  | +   [sheet @data-atom]])
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ;; -------------------------
 | 
	
		
			
				|  |  |  ;; Initialize app
 |