HTML Form Fields: Readonly vs. Disabled
I've been tinkering with the form element once again as web developers often do and lately, I've been using the FormData to parse the values and validate the collected form data with Malli. I often default to using disabled="true"
when sketching the forms and I want to block the user from altering a static value, but this week, it hit me that read-only and disabled HTML attributes have different implications.
Here's a simple example of what I mean.
(defnc app []
(d/form
{:id "form"}
(d/input {:name (str :static)
:default-value "non-mutable"})
(d/fieldset
{:name "demo"}
(d/div
(d/label "one")
(d/input {:name (str [:data :value-1])
:default-value "value-one"}))
(d/div
(d/label "two")
(d/input {:name (str [:data :value-2])
:default-value "value-two"})))))
And here's a naive form parser.
(defn naive-form-parser [^js/HTMLFormElement form]
(reduce
(fn [form-data [k v]]
(let [path (edn/read-string k)]
(if (sequential? path)
(assoc-in form-data path v)
(assoc form-data path v))))
{}
(for [entry (.entries (js/FormData. form))]
entry)))
(naive-form-parser form)
;; =>
{:static "non-mutable",
:data {:value-1 "value-one",
:value-2 "value-two"}}
Now if we set the static field as disabled
(d/input {:name "static"
:disabled true
:default-value "non-mutable"})
;; ...
(naive-form-parser form)
;; =>
{:data {:value-1 "value-one",
:value-2 "value-two"}}
The disabled=true
makes the input field "invisible" to the FormData, but when using the readonly=true
it will be visible.
(d/input {:name "static"
:read-only true
:default-value "non-mutable"})
;; ...
(naive-form-parser form)
;; =>
{:static "non-mutable",
:data {:value-1 "value-one",
:value-2 "value-two"}}
And of course, this is pretty clear if you read through the docs:
The Boolean disabled attribute, when present, makes the element not mutable, focusable, or even submitted with the form. The user can neither edit nor focus on the control, nor its form control descendants.
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled
These details can be easy to forget when working with React and other libraries. There's nothing new in this post. I just thought that this was curious since I don't remember paying attention before to this small detail.
If you were wondering the code examples are in Helix.
Subscribe to my newsletter
Read articles from Toni Väisänen directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Toni Väisänen
Toni Väisänen
Software engineer @ Metosin Ltd Need help with a project, contact: first.last@metosin.com As a 𝐜𝐨𝐧𝐬𝐮𝐥𝐭𝐚𝐧𝐭, I help clients find technical solutions to their business problems and facilitate communication between the stakeholders and the technical team. As a 𝐟𝐮𝐥𝐥-𝐬𝐭𝐚𝐜𝐤 𝐝𝐞𝐯𝐞𝐥𝐨𝐩𝐞𝐫, I build technical solutions for client's problems from user interfaces, and backend services to infrastructure-as-code solutions. As a 𝐦𝐚𝐜𝐡𝐢𝐧𝐞 𝐥𝐞𝐚𝐫𝐧𝐢𝐧𝐠 𝐞𝐧𝐠𝐢𝐧𝐞𝐞𝐫, I create, validate and deploy predictive models.