Skip to content

Commit 7b857cb

Browse files
committed
[forms] Input and Input! handle maxlength again, use in demos
This commit: c968305 introduced 2 changes in `Input` and `Input!`: 1. it removed the default 100 maxlength 2. it removed maxlength handling altogether 1 was harmful, users complained, it wasn't generic. 2 was useful, because DOM inputs can have a larger value than the maxlength property allows them to. The input honors the limit when typing but doesn't enforce it programmatically. We implemented 1 to guard inputs that end up stored on the server. Dropping it we lost this guard. This commit reinstates 2 in `Input` and `Input!` without reinstating 1. 1 is implemented in userland where needed by passing in `:maxlength 100` manually. We expect to improve this in the future by providing better, sanitized input components.
1 parent 30ffde6 commit 7b857cb

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

src/hyperfiddle/electric_forms5.cljc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313

1414
;;; Simple controlled inputs (dataflow circuits)
1515

16-
(e/defn Input [v & {:keys [type label id] :as props :or {type "text", id (random-uuid)}}]
16+
(defn ?substring [s maxlength] (cond-> s maxlength (subs 0 maxlength)))
17+
18+
(e/defn Input [v & {:keys [type label id maxlength] :as props :or {type "text", id (random-uuid)}}]
1719
(e/client
1820
(e/When label (dom/label (dom/props {:for id}) (dom/text label)))
1921
(dom/input
@@ -23,7 +25,7 @@
2325
;; event handler can't be guarded by focus – <input type=number> renders a
2426
;; ↑↓ mouse control over the text input to increment/decrement a number.
2527
;; Clicking those buttons don't focus the input.
26-
(dom/On "input" #(-> % .-target .-value) (str v)) ; (str v) passes through
28+
(dom/On "input" #(-> % .-target .-value (?substring maxlength)) (str v)) ; (str v) passes through
2729
)))
2830

2931
(e/defn Checkbox [checked & {:keys [id type label] :as props
@@ -120,7 +122,7 @@ Simple uncontrolled checkbox, e.g.
120122
(defn tx-error? [error] (and error (not= ::discard error))) ; we are (ab)using the error channel to signal discard. This is an implementation detail. TODO revisit.
121123

122124
(e/defn Input! [field-name ; fields are named like the DOM, <input name=...> - for coordination with form containers
123-
v & {:keys [as name type label id Parse Unparse] :as props
125+
v & {:keys [as name type label id Parse Unparse maxlength] :as props
124126
:or {as :input, type "text", id (random-uuid) Parse Identity, Unparse (Lift str)}}]
125127
(e/client
126128
v ; ensure v is consumed to prevent surprising side effects on commit discard or dirty/not dirty (lazy let)
@@ -134,7 +136,7 @@ Simple uncontrolled checkbox, e.g.
134136
error? (tx-error? err)
135137
dirty? (e/Reconcile (or editing? waiting? error?))
136138
unparsed-v (e/Reconcile (if waiting? ((fn [] (-> e .-target .-value))) (str (Unparse v)))) ; user input has precedence
137-
parsed-v (Parse unparsed-v)]
139+
parsed-v (Parse (?substring unparsed-v maxlength))]
138140
(SetValidity dom/node parent-node parsed-v)
139141
(when-not dirty? (set! (.-value dom/node) unparsed-v)) ; TODO - submit must reset input while focused
140142
(when error? (dom/props {:aria-invalid true})) ; not to be confused with CSS :invalid. Only set from failed tx (err in token). Not set if form fail to validate.

0 commit comments

Comments
 (0)