Fork me on GitHub

@seantempesta: experimented with something similar a few days ago, do you have specs for entire forms or for fields? How do you determine if an input is valid or invalid? I'm scanning for the path in :cljs.spec/problems but for finding missing fields this isn't very helpful.


For valid I just use s/valid?


I’ve only tested it with a single field, but I assume cross form should work as long as you spec it appropriately.


right, that question was a bit unspecific. If you have a spec for a form with many fields, how do you find out if individual forms are valid? (to display errors etc)


ugh, I’m embarrassed to show this (as it’s rough), but I think you’ll get the idea.

(defn input-field-wrapper
  ([props source-data k update-path editing? required?] (input-field-wrapper props source-data k update-path editing? required? nil))
  ([props source-data k update-path editing? required? onSubmitEditing-next-ref]
   (trace :timbre/raw "input-field-wrapper: init" props source-data k update-path editing? required? onSubmitEditing-next-ref)
   (let [initial-value (get source-data k nil)
         focused? (r/atom false)
         dirty? (r/atom false)
         current-value (r/atom initial-value)
         valid? (r/atom (s/valid? k initial-value))
         show-error-state? (r/atom (and (not @focused?) @dirty? (not @valid?)))]
     (fn [props source-data k update-path editing? required?]
       (let [db-value (get source-data k nil)]
         (trace :timbre/raw "input-field-wrapper: render" initial-value db-value @focused? @dirty? @current-value @valid? @show-error-state?)
         [@input-field (merge props
                              (when (not= db-value @current-value) {:value db-value})
                              {:containerStyle  {:backgroundColor (if @show-error-state? "#FBE3E4" "white")}
                               :style           {:color (if @show-error-state? "white" "black")}
                               :ref             (name k)
                               :editable        editing?
                               :initialValue    initial-value
                               :clearButtonMode "while-editing"
                               :onBlur          #(do (reset! focused? false)
                                                     (reset! show-error-state? (and (not @focused?) @dirty? (not @valid?))))
                               :onChangeText    #(do (reset! dirty? true)
                                                     (reset! current-value %)
                                                     (reset! valid? (s/valid? k %))
                                                     (dispatch [:update-form-data update-path k %]))
                               :onFocus         #(do (reset! focused? true)
                                                     (reset! show-error-state? false))
                               :iconRight       (r/create-element right-view-c #js {:size (if @focused? 25 60) :editing? editing? :focused? @focused? :required? required?})})])))))


basic idea, is to have a couple of different states: focused, dirty, valid and to not validate annoyingly (like when you’re typing)


yeah, I tried to cover the same things, this article is really good: 🙂


@seantempesta: do you have any plans how to determine if a collection of these fields are all valid?


I’m not sure I see the problem? Don’t you just define a form level spec that includes all of the fields and then call it with a data structure that has all of the form fields with each individual’s spec name as a key?


@seantempesta: that's one wide snippet kappa


@seantempesta: btw, will extracting all those event-handlers (:onChangeText, etc.) as a named functions make code noticeably faster? (by avoiding defining them on each render)


@misha, I don't think anonymous functions are defined on invocation


anonymous vs named (var-bound) functions is mainly a stylistic difference


cljs.user=> (defn a [txt] (str "a-" txt "-b"))
cljs.user=> (defn b [txt] (a txt))
cljs.user=> (defn c [txt] (#(str "a-" % "-b")))

cljs.user=> (time (dotimes [n 1000000] (b n)))
"Elapsed time: 1269.000000 msecs"
cljs.user=> (time (dotimes [n 1000000] (c n)))
"Elapsed time: 980.000000 msecs"
cljs.user=> (time (dotimes [n 1000000] (b n)))
"Elapsed time: 1283.000000 msecs"
cljs.user=> (time (dotimes [n 1000000] (c n)))
"Elapsed time: 974.000000 msecs"


cljs.user=> (defn a [])
cljs.user=> (defn b [] a)
cljs.user=> (defn c [] #())

cljs.user=> (time (dotimes [n 1000000] (b)))
"Elapsed time: 215.000000 msecs"
cljs.user=> (time (dotimes [n 1000000] (c)))
"Elapsed time: 134.000000 msecs"


dnolen [6:14 PM]  
<@U051HUZLD> not enough to matter for event handlers


greetings! I am trying to call this.requestAnimationFrame() as described here: but can't actually find this method/function neither on react, nor on react component, nor on this (within (this-as this) block). send help.


is it js/window.requestAnimationFrame()?