1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- (ns microtables-frontend.core
- (:require
- [reagent.core :as r]))
- ; to generate random values
- ;for(let i = 0, s = new Set(); i < 10; i++){ let r = Math.floor(Math.random() * 15)+1, c = a[Math.floor(Math.random() * a.length)], k = `${c}${r}`; if(s.has(k)){ i--; continue; } s.add(k); v.push(`{:row ${r} :col "${c}" :value "${Math.floor(Math.random() * 10000)}"}`); }
- (def sample-data [{:row 1 :col "A" :value "59"}
- {:row 5 :col "C" :value "269"}
- {:row 4 :col "B" :value "7893"}
- {:row 2 :col "F" :value "8650"}
- {:row 6 :col "D" :value "4065"}
- {:row 7 :col "F" :value "5316"}
- {:row 1 :col "A" :value "4910"}
- {:row 12 :col "A" :value "2405"}
- {:row 5 :col "B" :value "7863"}
- {:row 9 :col "E" :value "3144"}
- {:row 10 :col "D" :value "8272"}
- {:row 2 :col "F" :value "3013"}
- {: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
- (empty? s) [65]
- (= l 90) (conj (upgrade-letter-code (subvec s 0 (dec (count s)))) 65)
- :else (conj (subvec s 0 (dec (count s))) (inc l)))))
- (defn next-letter [lc]
- (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 [: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
- (cons
- ^{:key (str "row-head-" r)} [:th (str r)]
- (map #(cell % r data) cols))])
- (defn header-row [cols]
- ^{:key "header"} [:tr
- (cons
- ^{:key "corner"} [:th]
- (map (fn [c] ^{:key (str "col-head-" c)} [:th c]) cols))])
- (defn sheet [data]
- [:table [:tbody
- (let [maxrow (highest :row data)
- cols (take-while (partial not= (next-letter (highest :col data))) col-letters)]
- (cons
- (header-row cols)
- (map #(row % cols data) (range 1 (inc maxrow)))))
- ]])
- (defn app []
- [:div
- [:h3 "Microtables"]
- [sheet @data-atom]])
- ;; -------------------------
- ;; Initialize app
- (defn mount-root []
- (r/render [app] (.getElementById js/document "app")))
- (defn init! []
- (mount-root))
|