Form Validation with Clojure Spec
-
Upload
alexanderkiel -
Category
Software
-
view
12 -
download
0
Transcript of Form Validation with Clojure Spec
General Idea
• We like to use the same specs for validating user input and for server-side validation
• We use an error-formatter to generate human-readable error messages from explain-data
Error Formatter• multi-method with hierarchic dispatch on
[normalized-pred id via] [normalized-pred id] [normalized-pred]
• Predicates are normalised by removing all numbers
(<= (count %) 10) ==> (<= (count %))
• default error formatters are available
• no need to write an error formatter for each input
Default Error Formatters;; Matches on (not (blank? %)) predicate (defmethod error-formatter '[(not (blank? %))] [_ _] "Wert erforderlich”)
;; Matches on normalised (<= (count %)) predicate and ;; uses full predicate and val from problem for error msg (defmethod error-formatter '[(<= (count %))] [_ {:keys [pred val]}] (let [max-length (last pred)] (gstr/format "Maximale Länge von %s Zeichen um %s Zeichen überschritten" max-length (- (count val) max-length))))
Match Error Formatters by ID
(defmethod error-formatter '[(re-matches %)] [_ _] "Ungültiger Barcode.")
(defmethod error-formatter '[(re-matches %) "in-insert-pos"] [_ _] "Ungültige Position.")
(defmethod error-formatter '[(re-matches %) "out-group-id"] [_ _] "Ungültige Gruppe.")
Usage in TextField• TextField uses default error formatters which match
the used predicate.
(s/def ::name #(not (blank? %))) (form/validating-text-field {:id "sso-name" :auto-focus true :floating-label-text "Name" :spec ::name :on-change #(update-order! ::name %)})
Conforming Values• one can normalise input values through s/conform
• in this example, users don’t have to input positions uppercase
(def upper-case-conformer (s/conformer (fn [x] (if (string? x) (str/upper-case x) ::s/invalid))))
;; A 2D position from A1 to D7 (s/def ::pos (s/and upper-case-conformer #(re-matches #"[A-D][1-7]" %)))
GitHub Project
https://github.com/alexanderkiel/material-comp