clojurescriptre-frame

changing db value in input form in reframe


I've been trouble by an updating issue in reframe.

db.cljs:

{:apple 16}

event.cljs

(rf/reg-event-db
:update-apple-size
  (fn [ db [_ size] ]
    (assoc db :apple size)))

subs.cljs

(rf/reg-subs
 ::apple-size
 (fn [ db ]
    (get db :apple))) 

views.cljs

[:input {:type :text
         :on-change (rf/dispatch [:update-apple-size (.. % -target -value js/parseFloat))]
         :value @(rf/subscribe [::apple-size] }]

The issue happed when user udpating with decimal number of the size. When user try to update current 16 to 16.5.

User will strike . ,but this will be trigger on-change event and wont' update the db value. ( {:apple 16} => {:apple 16.0} ) ?. Then the subscribe will render "16.0" to UI as "16" ?

that's why user can't really append decimals after an integer in input element ?

Any advise will be helpful !


Solution

  • Note that js/parseFloat parses a string with a decimal dot into an integer:

    cljs.user=> (js/parseFloat "16.")
    16
    

    One solution can be to save into db two values:

    Then input will display a string with a decimal dot. See example:

    Db:

    (def default-db
      {:input-val "5"
       :input-num 5})
    

    Views:

     [:input {:type "string"
                         :value @(re-frame/subscribe [::subs/input-val])
                         :on-change #(re-frame.core/dispatch [:change-val (-> % .-target .-value)])}]
                [:div
                 [:p @(re-frame/subscribe [::subs/input-num])]]
    

    Subs:

    (re-frame/reg-sub
      ::input-val
      (fn [db] (:input-val db)))
    
    (re-frame/reg-sub
      ::input-num
      (fn [db] (:input-num db)))
    

    Events:

    (re-frame/reg-event-db
      :change-val
      (fn [db [_ val]]
          (-> db
              (assoc :input-val val)
              (assoc :input-num (js/parseFloat val)))))