In HTML, the readonly
attribute
for a
form
field specifies that the field should not be
changeable by the user. However, this feature is not universally
supported yet.
As a workaround, one can additionally
use simple JavaScript code via
onfocus="this.blur()"
,
or a cleverer code which focuses on the next field,
though such methods of course do not
work in all browsing situations.
Depending on the reason for making a field readonly,
a more robust method of using hidden fields might be feasible.
readonly
attributeonfocus="this.blur()"
tabindex
There are several reasons why a Web page author might wish to make a form field readonly:
textarea
element
just to create a "scrollable subwindow" of text, i.e. for
data display, without actually using a form at all.
Note that this isn't such a great idea, and using
inline frames might
do the job better (though you'd still need some fallback
for browsers not supporting iframe
).
The methods used to make a field readonly, especially the workaround methods, need to be selected according to the purpose.
In addition to limitations listed below, there is a more fundamental restriction. Even if all browsers supported the HTML way of declaring a field as readonly, a user could still create his private copy of the author's form, edit it, making the field a normal input field, and using that form to submit data. (The author cannot hide the HTML source.) Or the user might write a form of his own from scratch, based on information or assumptions about what the form handler expects to get.
It is true that the server-side form handler could be written
so that it checks the Referer
field
in the HTTP transaction. Specifically, it could check that the
Referer
field matches the address of the document
containing the form to be used. This approach is not without
problems though. It could limit usability (e.g. by preventing the
fair use of local copies of that document), and it wouldn't protect
against browsers or other programs which have been written to
send faked Referer
fields.
Thus, do not rely on readonly fields actually remaining readonly. In particular, when such fields will be used in server-side form handlers, normal data presence and integrity tests should be performed.
readonly
attributeIn HTML 4, the
readonly
attribute can be used
for input
and textarea
elements.
It is defined as follows in the specification:
No value is needed for the readonly
attribute. But
to conform to XHTML,
a restricted version of HTML where
"attribute minimization" is not allowed, you can write
readonly="readonly"
.
However, this attribute is currently supported (among widely used browsers) only by Internet Explorer 4 and newer.
You can see whether your current browser supports readonly
if you try to modify the second field in the following form
(you should not be able to focus on it, still less to change its content;
submitting the form causes just an echo of the form data):
Note the difference between readonly
and
disabled
. The latter, which lacks universal support, too,
also implies that the field cannot be changed, but
additionally it means that the field is currently not part of the
form data at all. That is, if the form is submitted, disabled
fields are not included into the submitted data (but readonly
fields are, according to
normal rules).
In case 1 among the reasons discussed
above in the Why readonly? section,
one could also use a hidden field, i.e.
input type="hidden"
.
Hidden fields are supported universally among browsers,
practically speaking. But since they are not displayed
at all, you need to consider whether you need to include their
content as normal text into the document.
It depends on the case whether you should inform the user about
some data being transmitted automatically.
For example, if you wish to include a field, say
surname
, containing the user's surname, say
Korpela
,
which you
have got from somewhere (e.g. previous form submission), you
could include
Surname: <input type="text" name="surname" value="Korpela">
into a form, thereby letting the user fix it if it is wrong.
But it might be the case that such fixing is undesirable;
perhaps you want to make the user go back in a chain of form
submissions to fix it where it went wrong, instead of just
fixing it here. Then you could make the field readonly:
Surname: <input type="text" name="surname" value="Korpela" readonly>
But this isn't particularly effective, due to limited browser support.
It would be better to use a hidden field and normal text:
Surname: Korpela
<input type="hidden" name="surname" value="Korpela">
The normal text and the hidden field need not be consecutive. The positioning of a hidden field within a form is immaterial. But it's natural to put things together when they contain the visible and invisible presentation of the same data.
If the data to be included is not relevant to the user but e.g. just some technical data for bookkeeping purposes, there's no reason to include it visibly, i.e. you'd use hidden fields only. Things like customer or order numbers require due consideration. Perhaps they are potentially relevant to the user e.g. when he wishes to report a failure in the form functionality.
onfocus="this.blur()"
In JavaScript,
you can use the
blur()
method to make
a form field lose focus. And by invoking that in an
onfocus
event handler, you would effectively prevent the field from
ever gaining focus.
The following example uses this technique, i.e.
input onfocus="this.blur()"
...:
In JavaScript, the
this
keyword denotes the "current object", which here means the
browser's internal data structure corresponding the input
element where the onfocus
attribute occurs.
However, in addition to the general limitations of JavaScript approaches (the browser might not have JavaScript enabled), there's the specific problem that not being focusable does not logically imply being unchangeable; some browsers might, now or in the future, provide a method of changing form field content without focusing on it. Moreover, there seem to be bugs in Netscape in this area; a test of mine failed to make the field readonly on Netscape 4.0 on WinNT, but that problem disappeared when I removed the stylesheet (which should of course have no effect on focusing). See also problems with tabbing discussed below.
Note that there is no reason not to use the readonly
attribute too. (Our example above lacks it just to let you test
the effect of the JavaScript method in separation.)
Specifically, on IE 4+ or Netscape 6+ with JavaScript disabled,
readonly
makes a difference.
See also
JavaScript
Form FAQ section
Protecting
Field Values, which discusses issues not covered here,
such as making select
elements "readonly"
and dynamically turning readonly status on or off.
tabindex
Browsers generally support "tabbing" in forms, so that the user can get from one field to another using the tab key. This is often very convenient and users might be accustomed to it, therefore annoyed when it does not work. And it can be more than just a convenience; see Web Content Accessibility Guidelines, especially guideline 9: Design for device-independence.
One might expect that setting a field readonly removes it from
the "tabbing ring" so that tabbing in the previous field
takes us to the field after the readonly field. This however is
not the case in the IE implementation for the readonly
attribute. Moreover, the JavaScript this.blur()
operation doesn't have such an effect either. For both of them,
tabbing in a field preceding the readonly field will take us to
an indeterminate state (no focus), and only after another tab do we
get to the next field.
(On one browser, I observed that tabbing in a field when the next
field has
onfocus="this.blur()"
took me to a state where that
next field is colored but nothing can be typed, and tabbing
does not work at all!)
This is rather clumsy and confusing; well, try it
yourself (type something into the first field and press tab):
<form action="http://jkorpela.fi/cgi-bin/echo.cgi"> <input name="fld1"><br> <input type="text" name="readonly-field" value="read-only" readonly onfocus="this.blur()" ><br> <input name="fld3"><br> <input type=submit> </form> |
A better approach uses this.form.nextfield.focus()
instead of this.blur()
as well as
tabindex
attributes so that the readonly field is skipped
in the tabbing order:
<form action="http://jkorpela.fi/cgi-bin/echo.cgi"> <input name="fld1" tabindex=1><br> <input type="text" name="readonly-field" value="read-only" readonly onfocus="this.form.fld3.focus()" ><br> <input name="fld3" tabindex=2><br> <input type=submit tabindex=3> </form> |
This is just a little more laborious to write than the
simpler method. Instead of mechanically using this.blur()
you need to pick up the name (nextfield)
of the next field or,
more generally,
the next non-readonly field in the form.
The tabindex
attribute is supported by some browsers only
only, so even this combined method is far from 100 % sure, but
it works on most JavaScript-enabled browsers and on
e.g. IE 4+ and Netscape 6+
even with JavaScript disabled.
Jim Ley has remarked that code like
this.form.fld3.focus()
should be avoided and a safer
construct like
document.forms['formname'].elements['fld3'].focus()
should be used instead.
The visual appearance of readonly fields on IE (and Netscape 6) is the same as for normal fields, whereas disabled fields look different. This isn't quite natural. You may wish to suggest a change using style sheets, e.g. using a different background color. Be careful: a readonly field should not resemble the default appearance of a disabled field!
The following example
contains various fields, one of which is
a readonly field with the attribute
style="background:#eee none; color:#222; font-style: italic"
suggesting a light grey background color and not quite black
text color as well as an italics version of the font in use:
If you have several readonly fields on a page, you probably wish
to put the stylistic suggestions into a style
element
or an external style sheet instead of including a copy of them
into each field. Then you would invent a suitable class name
(it could be ro
for example) and use class="ro"
in the elements which have the readonly
attribute.
Unfortunately it is currently not possible to specify in a style
sheet that some rules are to be applied to all elements which have
a certain value for a certain attribute. (Such possibilities exist
in CSS2, but they are not supported yet by browsers.)
Note that the possibilities of affecting form field appearance are relatively limited. The CSS methods for it work to some extent on IE 4+ but not on many other browsers. In our example, Netscape 4.0 shows the readonly field with CSS so that the text is in italics but the appearance is otherwise that of a normal input field, i.e. the color and background suggestions are ignored.
Depending on your
reason for trying to make field
readonly, you might wish to suppress the border around the field, so that
it does not really look like a field at all. This is technically simple
(using border:none
in a style sheet) but works on some
browsers only. For a simple example (for JavaScript-enabled browsers),
see
Yet another example: dynamically displaying the sum of fields.
This document is part of my material on HTML forms.
Date of last update: 2002-07-25.
Jukka Korpela