In HTML, the form concept is simple and static. This is one reason why people often use client-side scripting, usually in JavaScript, to enhance the functionality of forms. In some cases, this is just fine: it might give extra comfort to some users, without disturbing others. But it is important to know the limitations. Specifically, one should never rely on JavaScript alone in the processing of data entered by user; to make sure things work reliably, such processing needs to be repeated by a server-side script.
NAME
attribute
Please consult my document How to write HTML forms for general information on forms, such as tutorials, references, and basic notes on processing form data by server-side scripts. This section will just make a few additional notes.
The form concept in HTML is simple, if not simplistic. You might have difficulties in seeing this when you look at the description of forms in HTML specifications, especially in the most extensive one (HTML 4). The complexity of the specifications in this area is however mostly related to details.
A form in HTML is essentially just a data structure describing the fields of possible user input at a rough level. You can specify the generic type of an input field (one line of text, several lines of text, choice between given alternatives, form submission request, request to clear the form).
It is probably useful to state explicitly some examples of what you cannot do with forms in HTML:
Despite the limitations, forms have turned out to be very useful. In a sense, they are largely useful thanks to being simple and limited: almost all browsers have supported forms for a long time, so they are widely accessible in various browsing situations.
The work in progress as regards to enhancing the HTML form concept illustrates the above-mentioned limitations in the current form concept. See XHTML Extended Forms Requirements.
Generally speaking, client-side scripting in relation to HTML means that some relatively simple code, which is embedded into an HTML document or referred to in it, is executed by the user's Web client (browser, such as Netscape, Opera, or Internet Explorer). The code might, for example, dynamically modify the HTML document (more exactly, a copy of it as processed and displayed by the browser), or it might open a new window on the user's screen. The code is written in some specific language designed for the purpose.
Section Scripts in the HTML 4.0 specification describes the different interfaces between HTML and scripting languages. In particular, it specifies some "intrinsic events" which are part of the interface.
Currently the most popular client-side scripting language is JavaScript. See JavaScript meta FAQ for sources of information on JavaScript and its possibilities. It especially recommends the extensive JavaScript FAQ (by Martin Webb) which is divided into sections, such as JavaScript Form FAQ. The FAQs are large, but there is a nice search form, replicated here for convenience:
Martin Webb's JavaScript Guidelines and Best Practice is a good overview and summary, and it helps in avoiding common errors.
There is a newer FAQ document, comp.lang.javascript FAQ, which is less extensive but more carefully written and probably better maintained than the FAQ resources mentioned above.
For references, see Netscape's JavaScript documentation, especially JavaScript Guide and JavaScript Reference, with the usual caveats: there are differences in JavaScript support between vendors and browsers and browser versions. See also JScript documentation, which describes the Microsoft's equivalent to JavaScript.
The international
Usenet newsgroup for JavaScript is
comp.lang.javascript
. Please check the FAQs
mentioned above before posting. You can also search from
the group using
Deja.com:
To take a simple example, you could use the following for focusing on a form field:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<TITLE>Form test</TITLE>
<META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
<BODY ONLOAD="document.theform.Comments.focus();">
<FORM ACTION="http://jkorpela.fi/cgi-bin/echo.cgi"
NAME="theform"
METHOD="POST">
<P>
Enter data:
<INPUT TYPE="TEXT" SIZE="40" NAME="Comments">
<BR>
<INPUT TYPE="SUBMIT" VALUE="Send">
</FORM>
</BODY>
You may wish to view a document containing the example on your current browser. If the browser does not support JavaScript or has JavaScript disabled, it may or may not focus on the input field, depending on browser's default behavior; if it does not, the user probably has to click on the input area before starting to type. A browser which executes JavaScript code should automatically focus on the input area when the document is loaded. This is a very simple example of JavaScript code written for extra comfort to some users; the form would still work without it, although perhaps slightly less comfortably. (This also implies that we are not very worried about situations where the focusing does not take place, but see question The onLoad event handler does not always set the focus in a form field, are there any workarounds? in the JavaScript Forms FAQ .)
However, there is the view that automatic focusing is undesirable and that focusing should be left to the user. And especially on large pages it might really happen that the part of a page, including a form, has loaded, the user starts filling out the form, and then the page finishes loading and focus is moved away from the field where the user was!
The META
element is used to
specify the scripting language used.
In principle, the ONLOAD
attribute value could be written in any scripting language.
However this is mainly theoretical; browsers that support
scripting languages imply JavaScript as the default.
NAME
attributeThe HTML 4.0 Specification did not allow a NAME
attribute for a FORM
or IMG
element.
This means that such attributes give validation errors when
validating against any HTML 4.0 DTD. However, the
HTML 4.01 Specification
(approved 1999-12-24),
which contains several
changes
(usually small ones) as compared with HTML 4.0, allows
the NAME
attribute for those
FORM
and for IMG
elements. Thus, you can
now use the following
document type declaration if you use
those attributes:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html40/loose.dtd">(or perhaps
Transitional
removed
and loose
replaced by strict
, if you don't use
deprecated features; or Transitional
replaced by
Frameset
and loose
replaced by
frameset
for frameset
documents).
Although this was expected to resolve the issue, the
XHTML 1.0 specification
re-introduced the problem, in the following sense:
In XHTML 1.0, the Transitional version allows the
name
for form
and img
,
the Strict version does not. Apparently, you can switch to the
Transitional DTD if this is a problem.
Some historical notes on previous solutions and background:
Browsers which support JavaScript generally let you refer,
in your JavaScript code,
to a specific form element using
uses a NAME
attribute in
the FORM
tag, as in
the
focusing example above.
However, the logical way to uniquely identify an element
would be via an ID
attribute - which is
allowed by HTML 4.0 but unfortunately supported
by browsers less widely than the NAME
attribute.
See
the thread NAME is an IMG tag
in
December 1998 in the
comp.infosystems.www.authoring.html
newsgroup.
The
WDG Validator documentation contains
instructions for using a customized DTD.
In this case it would suffice to use
an HTML 4.0 DTD with the simple extension which
allows NAME
for FORM
; see
our example modified to refer to that DTD -
it validates.
But currently this is not needed
any more, since you can just use
the HTML 4.01 DTDs.
When referring to
images in JavaScript e.g. in order to
dynamically replace an image by another
one normally uses
by using a NAME
attribute
in an IMG
element.
The causes validation problems as explained above.
One solution used was
to refer to images in JavaScript using their numbers
(e.g. document.images[0]
when referring to the first image on a page). This could be feasible
if there are just a few images on the page. But using numbers
for such purposes is error-prone (do you remember to change
the numbers if you add images? even when in hurry to meet a deadline?),
and it is discouraged in
Martin Webb's
JavaScript Guidelines and Best Practice;
and since the approval of HTML 4.01, there's no reason any more
to use that method.
One of the most usual simple uses of JavaScript is to open a linked resource in a new browser window with specific properties like width and height. It is highly questionable whether this is a useful feature (see item 2 in The Top Ten New Mistakes of Web Design) but here we concentrate on the technical question of doing it the best way. This hopefully also illustrates the general idea of coding such things robustly.
So let's assume that you wish to make the word "foo" a link
so that when the user clicks on it, the page
somepage.html
will open in a new browser window which is 150 pixels wide and
150 pixels high. (Just simple properties, for illustration; see
JavaScript window FAQ for other possibilities
and
Window Spawning and
Remotes at
WebReference for some
illustrations.)
Let's start from the wrong way of doing it:
<script><!-- function popup(){ newwin = window.open('somedoc.html','','width=150,height=150');} //--></script> ... <a href="javascript:popup()">foo</a>
The problem with this is that when a browser does not
support JavaScript, the link does not work at all.
The user will see "foo" as a link but clicking on it does nothing.
(By the way, search engines are probably "JavaScript challenged",
so they won't find somedoc.html
through that construct.)
It won't help to do something like the following
in place of an <a href="javascript:
.. link:
<a href="#" onClick="popup()">foo</a>
This approach is for some reason popular, but of course
href="#"
makes no sense.
Although #
is technically a URL reference, it means
a reference to the start of the focument. When JavaScript
is disabled, the "link" thus degrades to something that causes the
document to be positioned at the start, potentially confusing the
user thoroughly.
<script type="text/javascript"><!-- function popup(){ newwin = window.open('','somename', 'width=150,height=150,resizable=1');} //--></script> ... <a href="somedoc.html" target="somename" onclick="popup();">foo</a>
There is a simple example page using this method. It also contains some further caveats and notes.
When the browser supports JavaScript (and the support is enabled),
clicking on the link will cause the value of the onclick
attribute to be executed first. This will create a new window
with the desired properties but not load anything into it yet.
Next (or as the only operation, if JavaScript is not supported)
the browser does normal link processing,
getting somedoc.html
and then
target
attribute
with the name of the window) or
target
attribute is
As an alternative method, you could write:
<a href="somedoc.html" target="somename" onclick= "return !window.open('somedoc.html','somename', 'width=150,height=150,resizable=1')">foo</a>
If the window is successfully opened, the window.open
function returns the value true
, which is changed to
false
by the negation operator !
.
Thus, on successful opening, the entire expression returns
false
, and thius tells the browser not to perform the
normal link processing (since here the JavaScript code is intended
to replace rather than precede it).
Historical remark:
This feature is not supported by browsers such as IE 3
which support JavaScript 1.0 only. This means that despite
the return value false
,
they would try to follow the link normally
after executing the JavaScript code. For our example, this would be
just unnecessary extra operation; but with the target
attribute
omitted, it would result in opening somedoc.html
both in a new
window and in the original window!
The discussion above is largely based on the ideas in a news article by Nick Kew, applied to a particular purpose of using JavaScript.
Similar
considerations apply to directing output
from form submission to a new window with some specific
properties. You would use an onsubmit
attribute
in a FORM
tag, together with a target
attribute in the same tag. Example:
<FORM ACTION="http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi" target="FOLDOC" onsubmit= "window.open('','FOLDOC','resizable=1,scrollbars=1,width=400,height=300')" > <INPUT NAME="query"> <INPUT TYPE="submit" NAME="action" VALUE="Search"> </FORM>
Try it (it will search for a word definition in the Free On-Line Dictionary of Computing)
Web authors who wish to open new windows rather often also ask how to create a button for closing a window. The short answer is that there is not need for that. If new windows can be opened in user's systems, then they can be closed by the user. You can create e.g. a "close button" using JavaScript - but you should then generate the markup and code for that using JavaScript, to avoid creating a button that looks like a close button but does not do anything when JavaScript is off. And the user could still, depending on the security settings of his browser, get a message telling that a page tries to close a window and asking for user's confirmation. So you would very easily end up with creating something confusing and more difficult to use than the normal way of closing windows in the user's system. (There are several items in the JavaScript windows FAQ which discuss various issues related to closing windows. It is rather technical and complicated, and the complexity illustrates how problems arise if you try to interfere with browsers' normal user interfaces).
A rather common special case of opening a new window in
a specific size is a link to an image. It is natural
to try to make the window as small as possible. One problem with
this is that browsers may use different amounts of padding around an
image, if you only link to an image as such. You can't affect that
padding, but you might affect the padding around an image if it is part
of an HTML page (or the sole content of an HTML page).
Moreover, you might wish to have some explanatory text (image caption)
in the window, too.
Hence it might be better
to make the link point to an HTML document containing the image (and little
or nothing else). You might find it comfortable to construct the HTML
document "on the fly" using JavaScript. Just remember to have
an href
attribute pointing to the image, as a fallback
for non-JavaScript browsing.
Suppose that you have an input field where a user should specify a date and that you would like to set the default to current date. The first question is: current as of what? The time of creating the document, or the server sending it, or the user filling out the form? Cf. to How do I display the current date or time in my document? But note that if you'd like to set the default to the date of filling out the form, then using JavaScript is quite suitable, and doesn't cause problems when it doesn't work; after all, it's just a matter of optionally setting a default.
The simplest approach is to write an input field normally,
and use separate JavaScript code to assign an initial value to it.
That is, you would not use a value
attribute
in an input
element in HTML markup
but assign the date (as a string)
to the element's value
property in JavaScript.
The next question is how to construct the date string. This depends on the desired date format. Beware that manipulation of dates in JavaScript is somewhat awkward due to browser incompatibilities and Y2K problems (they are real in JavaScript, especially after the start of 2000); see JavaScript Date FAQ.
Especially on the WWW, there are good reasons to use ISO 8601 date format (sample: 2000-11-06). The following code initializes a form field to current date in that format, when JavaScript is enabled, and leaves it initially blank otherwise:
<form ... name="testform"> <input name="datefield" size="10"> <script type="text/javascript"><!-- function getCorrectedYear(year) { year = year - 0; if (year < 70) return (2000 + year); if (year < 1900) return (1900 + year); return year;} var today = new Date(); var d = today.getDate(); if(d < 10) d = '0' + d; var m = today.getMonth() + 1; if(m < 10) m = '0' + m; var y = getCorrectedYear(today.getYear()); var dateString = y + '-' + m + '-' + d; document.testform.datefield.value = dateString; //--></script> ... </form>
It is generally best to put JavaScript code into
separate files (referred to via
script src="..."
elements in HTML)
or into script
elements in the document head,
whenever feasible,
instead of "inlining" it as above. The code above is just a compact
illustration.
Assume that your form has some fields for numeric input by the user, such as quantity of items he is about to purchase. You might wish to include, as extra convenience to some users, a client-side script which dynamically calculates and displays a running total.
To illustrate the basic idea, we consider an extremely
simplified version where the data to be displayed
is just the sum of two fields.
Let us assume that user input is via selecting an option
from a SELECT
menu, which means that he has
a predefined set of alternatives.
If data input is via a text input field, there will be more
complications. You would probably want to
check
the data for being numeric, and it would be more difficult
to make the sum information change in a manner which cannot
mislead the user.
Note that the onchange
attribute is
handled by browsers so that
an event is not interpreted to occur just because
the user uses the mouse to move the cursor away from the input field,
but it occurs when you focus on another field
(e.g. by clicking on another field in order to start typing there,
or by "tabbing" to the next field).
The code for it could be the following:
<script type="text/javascript"><!--
function updatesum() {
document.form.sum.value =
(document.form.s1.options[document.form.s1.selectedIndex].text-0) +
(document.form.s2.options[document.form.s2.selectedIndex].text-0); }
//--></script>
<form name="form" action="address of server-side script">
Select a number:
<select name="s1" onChange="updatesum()">
<option selected>0<option>1<option>2<option>3<option>4
<option>5<option>6<option>7<option>8<option>9
</select>
and another number:
<select name="s2" onChange="updatesum()">
<option selected>0<option>1<option>2<option>3<option>4
<option>5<option>6<option>7<option>8<option>9
</select>
Their sum is:</th> <td><input name="sum" readonly style="border:none"
value="(not computed)">
</form>
It looks like the following on your browser: