finally sunset old binding
This commit is contained in:
@@ -106,26 +106,6 @@
|
||||
(when d
|
||||
(format/parse f d)))
|
||||
|
||||
(defn dispatch-date-change [event]
|
||||
(fn [e]
|
||||
(re-frame/dispatch (conj event
|
||||
(if (str/blank? e)
|
||||
e
|
||||
(date->str (t/from-default-time-zone (c/from-date e)) standard))))))
|
||||
|
||||
(defn dispatch-cljs-date-change [event]
|
||||
(fn [e]
|
||||
(re-frame/dispatch (conj event
|
||||
(if (str/blank? e)
|
||||
e
|
||||
(c/to-local-date e))))))
|
||||
|
||||
;; TODO inline on-changes causes each field to be rerendered each time. When we fix this
|
||||
;; let's make sure that we find away not to trigger a re-render for every component any time any form field
|
||||
;; changes
|
||||
(defmulti do-bind (fn [_ {:keys [type]}]
|
||||
type))
|
||||
|
||||
(defn with-keys [children]
|
||||
(map-indexed (fn [i c] ^{:key i} c) children))
|
||||
|
||||
@@ -178,290 +158,6 @@
|
||||
0.0)}}
|
||||
child])))])])))
|
||||
|
||||
|
||||
(defn multi-field [{:keys [value]} ]
|
||||
(let [value-repr (reagent/atom (mapv
|
||||
(fn [x]
|
||||
(assoc x :key (random-uuid) :new? false))
|
||||
value))]
|
||||
(fn [{:keys [template on-change allow-change? disable-new? disable-remove?]} ]
|
||||
(let [value @value-repr
|
||||
already-has-new-row? (= [:key :new?] (keys (last value)))
|
||||
value (if (or already-has-new-row? disable-new?)
|
||||
value
|
||||
(conj value {:key (random-uuid)
|
||||
:new? true}))]
|
||||
[:div {:style {:margin-bottom "0.25em"}}
|
||||
(for [[i override] (map vector (range) value)
|
||||
:let [is-disabled? (if (= false allow-change?)
|
||||
(not (boolean (:new? override)))
|
||||
nil)]
|
||||
]
|
||||
^{:key (:key override)}
|
||||
[:div.level {:style {:margin-bottom "0.25em"}}
|
||||
[:div.level-left {:style {:padding "0.5em 1em"}
|
||||
:class (cond
|
||||
(and (= i (dec (count value)))
|
||||
(:new? override))
|
||||
"has-background-light"
|
||||
|
||||
(:new? override)
|
||||
"has-background-info-light"
|
||||
:else
|
||||
"")}
|
||||
(let [template (if (fn? template)
|
||||
(template override)
|
||||
template)]
|
||||
|
||||
[:<> (for [[idx template] (map vector (range ) template)]
|
||||
^{:key idx}
|
||||
|
||||
[:div.level-item
|
||||
(update template 1 assoc
|
||||
:value (let [value (get-in override (get-in template [1 :field])) ;; TODO this is really ugly to support maps or strings
|
||||
value (if (map? value)
|
||||
(dissoc value :key :new?)
|
||||
value)]
|
||||
(if (= value {})
|
||||
nil
|
||||
value))
|
||||
:disabled (or is-disabled? (get-in template [1 :disabled]))
|
||||
:on-change (fn [e]
|
||||
(reset! value-repr
|
||||
(into []
|
||||
(filter (fn [r]
|
||||
(not= [:key :new?] (keys r)))
|
||||
(assoc-in value
|
||||
(into [i] (get-in template [1 :field]))
|
||||
(let [this-value (if (and e (.. e -target))
|
||||
(.. e -target -value )
|
||||
e)]
|
||||
(if (map? this-value)
|
||||
(update this-value :key (fnil identity (random-uuid)))
|
||||
this-value))))))
|
||||
(on-change (mapv
|
||||
(fn [v]
|
||||
(dissoc v :new? :key))
|
||||
@value-repr))))])
|
||||
])
|
||||
(when-not disable-remove?
|
||||
[:div.level-item
|
||||
[:a.button.level-item
|
||||
{:disabled is-disabled?
|
||||
:on-click (fn []
|
||||
(when-not is-disabled?
|
||||
(reset! value-repr (into []
|
||||
(filter (fn [{:keys [key ]}]
|
||||
(not= key (:key override)))
|
||||
(filter (fn [r]
|
||||
(not= [:key :new?] (keys r)))
|
||||
value))))
|
||||
|
||||
(on-change (mapv
|
||||
(fn [v]
|
||||
(dissoc v :new? :key))
|
||||
@value-repr))))}
|
||||
[:span.icon [:span.icon-remove]]]])
|
||||
]])]))))
|
||||
|
||||
|
||||
|
||||
(defmethod do-bind "select" [dom {:keys [field allow-nil? subscription event class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (dispatch-value-change (conj event field))
|
||||
|
||||
:value (or (get-in subscription field) "")
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)
|
||||
options (if allow-nil?
|
||||
(with-keys (conj rest [:option {:value nil}]))
|
||||
(with-keys rest))]
|
||||
(into [dom (dissoc keys :allow-nil?)] options)))
|
||||
|
||||
|
||||
(defmethod do-bind "radio" [dom {:keys [field subscription event class value spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (dispatch-value-change (conj event field))
|
||||
:checked (= (get-in subscription field) value)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field ))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind "checkbox" [dom {:keys [field subscription event class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (dispatch-event (-> event
|
||||
(conj field)
|
||||
(conj (not (get-in subscription field)))))
|
||||
:checked (boolean (get-in subscription field))
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field ))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind "multi-field" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (fn [value]
|
||||
(re-frame/dispatch (conj (conj event field) value)))
|
||||
:value (get-in subscription field)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
|
||||
|
||||
(defmethod do-bind "typeahead-v3" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (fn [selected]
|
||||
(re-frame/dispatch (conj (conj event field) selected))
|
||||
#_(when text-field
|
||||
(re-frame/dispatch (conj (conj (or text-event event) text-field) text-value))))
|
||||
:value (get-in subscription field)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind "date" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
selected (get-in subscription field)
|
||||
keys (assoc keys
|
||||
:on-change (fn [v]
|
||||
(re-frame/dispatch (-> event (conj field) (conj v))))
|
||||
|
||||
:value selected
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind "expense-accounts" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:value (get-in subscription field)
|
||||
:event (conj event field)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
|
||||
(defmethod do-bind "button-radio" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:value (get-in subscription field)
|
||||
:on-change (fn [v]
|
||||
(re-frame/dispatch (-> event (conj field) (conj v))))
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :event :subscription :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind "number" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (fn [e]
|
||||
(.preventDefault e)
|
||||
(re-frame/dispatch (-> event
|
||||
(conj field)
|
||||
(conj (let [val (.. e -target -value)]
|
||||
(cond (and val
|
||||
(re-matches #"[\-]?(\d+)(\.\d{2})?" val))
|
||||
(js/parseFloat val)
|
||||
|
||||
(str/blank? val )
|
||||
nil
|
||||
|
||||
:else
|
||||
val))))))
|
||||
:value (get-in subscription field)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind "textarea->table" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (fn [x]
|
||||
(re-frame/dispatch (-> event
|
||||
(conj field)
|
||||
(conj x))))
|
||||
:value (get-in subscription field)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind "money" [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (fn [x]
|
||||
(re-frame/dispatch (-> event
|
||||
(conj field)
|
||||
(conj x))))
|
||||
:value (get-in subscription field)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defmethod do-bind :default [dom {:keys [field event subscription class spec] :as keys} & rest]
|
||||
(let [field (if (keyword? field) [field] field)
|
||||
event (if (keyword? event) [event] event)
|
||||
keys (assoc keys
|
||||
:on-change (dispatch-value-change (conj event field))
|
||||
:value (get-in subscription field)
|
||||
:class (str class
|
||||
(when (and spec (not (s/valid? spec (get-in subscription field))))
|
||||
" is-danger")))
|
||||
keys (dissoc keys :field :subscription :event :spec)]
|
||||
(into [dom keys] (with-keys rest))))
|
||||
|
||||
(defn bind-field [all]
|
||||
(apply do-bind all))
|
||||
|
||||
|
||||
|
||||
(defn horizontal-field [label & controls]
|
||||
[:div.field.is-horizontal
|
||||
(when label
|
||||
[:div.field-label
|
||||
label
|
||||
])
|
||||
(into
|
||||
[:div.field-body]
|
||||
(with-keys (map (fn [x] [:div.field x]) controls)))])
|
||||
|
||||
(defn coerce-date [d]
|
||||
(cond (and (string? d)
|
||||
(some->> (re-find #"^(\d{4})" d)
|
||||
|
||||
Reference in New Issue
Block a user