 
 (def el-value #(-> % .-target .-value))
 
+(def is-float (comp not js/window.isNaN js/window.parseFloat))
+
 (defn amount-input []
   (let [amount (r/track #(-> @app-state :expense-form :amount))
-        error-class (r/track #(if (not (re-matches #"[\d,.]*" @amount)) "has-error"))
+        valid-amount #(or (empty? %1) (is-float %1))
+        error-class (r/track #(if (not (valid-amount @amount)) "has-error"))
         on-change #(dispatch [:change-amount (el-value %)])]
     (fn []
       [:div {:class (s/join " " ["form-group" @error-class])}

            [goog.events :as events]
            [reagent.core :as r]
            [ajax.core :refer [GET]]
            [clojure.string :as s])
  (:import [goog.net Jsonp]
           [goog Uri]))

(extend-type js/NodeList
  ISeqable

(defn event-handler [state [event-name value]]
  (case event-name
    :group-info (-> state
                    (update :group-info merge (update value :members sort))
                    (assoc-in [:expense-form :shared-with]
                              (into {} (map #(vec [% true]) (:members value))))
                    (assoc-in [:expense-form :payed-by] (first (:members value))))
    :shared-with (update-in state [:expense-form :shared-with value] not)
    :change-amount (assoc-in state [:expense-form :amount] value)
    :change-payed-by (assoc-in state [:expense-form :payed-by] value)
