Side bar

  Colour editing
  Image creation
  JS Tricks
HTML³: Forms |


This page now has two main sections:


...although if you're not familiar with forms at all, read the HTML documentation before even trying to attempt WML.

HTML Forms - The Basics

When I originally started writing the forms section for HTML³ I only had a slender grasp as to what each function did, because I only had a few example scripts to work from. I've since become a Perl programmer and so work with forms more often, but you should be warned that forms can be a little complex - it might just be best to use example code that should be provided with the documentation to go with the cgi program you're using. If you're writing your own CGI, well, I'll do my best...

Anyway, on with the show. A form looks something like this:

Enter something:


  Enter something:<br>
  <input type="text" name="parameter" size="32">
  <p align="center">
    <input type="submit"> |
    <input type="reset">

You're encasing the block of HTML to do the form in a <form>...</form> structure, in much the same way as, for instance, a table structure - you define the area of the form, and then put the actual controls that displays stuff inside this, which means you can have more than one form on a page and each form will know what buttons etc. belongs to it.

This example form also has some other fairly common, but by no means compulsory, elements in it. These are the text box - a simple one-line text entry area - created using <input type="text" name="parameter" size="32">, then there's the two buttons, one to submit the form data to whatever controlling program is running on a web server waiting to receive this data, and another to wipe clean any data you might have entered so that you can start again. These are created using <input type="submit"> and <input type="reset">.

See the pattern emerging? Most controls in forms are via
<input type="something">
More on that later.

Creating a Form

All form data gets sent to a program running on a computer somewhere - usually a program in a directory called cgi-bin on the same server your webpages are uploaded to. CGI stands (in this case) for Common Gateway Interface, which basically means a standard way of sending data to a web-based program (also known as a "script").

So, if the program we're using is located at you tell the Web browser to use this program via the following command:
<form method="get" action="">

The method for forms is usually get, where the data is sent as part of the URL you are fetching - you'll see it encoded in a type of MIME encoding appearing in the box near the top of the browser where the current URL is displayed (it's actually called URL encoding as it's slightly different). This is probably the most common type of form method in use, but it depends on the form. Note that because the data is put into the URL, you're usually limited in the amount of text that can be sent off - fine for simple push-button programs, but not good for message boards where people might want to write long missives (as I've found to my cost in the past).

post is another method, where the data is pushed to the CGI without you seeing an outward echo of the information; the CGI may need to be written slightly differently to handle this method (unless it's been written using the Perl CGI module's param function), so don't assume that, for instance, simply because you want more security you can send the data via the post method. If you do not know the method used, try get first.

One of the nice things about writing in Perl, however, is that if you use CGI qw(param);, all you need to do is use the param command you can use either method without having to worry about what method was used to get the information there! For example, $variable=param("textinput");, where "textinput" was the name of a text input box (or any form item), and $variable is the variable you're loading with the data posted from that form item.

A last option is the post via email method - and this is really the weapon of last resort. Instead of using a CGI to handle the data, this attempts to send the information in email form. However, it is not well supported - a few PC browsers may handle it - and should only really be attempted where no other option is open to you. Hopefully you will never be that desperate, but far be it from me to suggest that ArgoNet don't check if their form is being used by people not subscribing to their service...

This is simply the URL that will handle the data - the location of the program, or the mailto: for a post method mailing. It's exactly like the href of a link, or the src of an image. Try the following:

  • Argo new form:
    (or /cgi-bin/newmail)
  • Argo old form:
  • Demon form:

Not a widely used option, this allows you to tell the CGI how the data is encoded - the post method uses the "encoding" of text/plain, which is MIME speak for a plain text email; I guess it's superfluous in most cases, but I included it for completeness in my post example as it was in the example I pinched copied it from.

Finally, you end the form by using the end form option, which simply outputs </form>. Nothing to it!

Hidden commands
<input type="hidden"...>

To set up a mail form for instance, there are certain commands which have to be passed to the CGI script to tell it who you are and how you want it to work. Although you can pass all of these using text boxes, there's really no need for the user to see these, or indeed be able to edit them. This is where hidden inputs come in:
<input type="hidden" name="mailto" value="">
You'll often find these used to tell a program what function to carry out, what password and username the user used to log in to the web site, and so on. To all intents and purposes they arrive at the other end as if the data came from a text entry box - you can handle it in a program as such - but the user should never have been able to alter it, or even see it, unless they've fiddled with the HTML source of the web page.

Single line text boxes
<input type="text"...>

(also "password" and "file")

Text boxes are probably the most commonly used type of form input - they allow the user to type in a short piece of text, such as their name, email address, street name and so on. For convenience I've also included two other similar tags in with this option: passwords and file upload, which both look and act very similar to text input boxes.

<input type="text" name="mailfrom">

The name section can be anything - if it's not one of the options the script recognises then it will be put into the email, so...
<input type="text" name="my_name">
...will result in something like this showing up in the email you receive:
"Richard Goodwin"

You can enter some text automatically by using the value="..." attribute:
<input type="text" name="mailfrom" value="">

You can set the size of the box on screen by using the size=".." attribute, and set the maximum number of characters that can be entered by using maxlength=".." - for instance, size="32" maxlength="64" (note that they don't have to be the same!)

If you use type="password" instead of type="text", you will still be able to enter text in exactly the same way as with regular text boxes but it will not show up when the user is typing his or her input in, some other character will be displayed instead (asterisks, dashed line, whatever). HTML³ allows you to specify this just by ticking the password option.


File upload
If you use type="file" instead of type="text" you should get what looks like a text input box, but in actual fact is to take a filename for uploading to the server. On PCs you get a Browse button next to this box, so take that into account when you design your page; on RISC OS browsers you just drag the file to this part of the web page.

Currently Oregano works fine with file uploads; WebsterXL should also work, although I've been unable to test this myself; and Fresco is broken, sending the file data where it should be sending the file name, which could be worked around if only it didn't miss off the last two bytes. Older browsers don't seem to work at all.

File upload CGIs are fairly complex beasts to write (compared to the one-line code to get data from other types of form inputs), so supporting this option is not for the faint of heart.


Multiple line text areas

For larger text boxes, the rules change a little - you use <textarea>...</textarea> tags, with the default text in between the tags.

You can set the height and width using rows="5" and cols="32"; there are also a few different ways of set how text wraps inside the box, the main two being: wrap="virtual"|"physical"> - virtual just wraps while the user is typing, whereas physical means that the text that is received at the other end is formatted in the same way.


<textarea name="message" rows="5" cols="32" wrap="virtual">
 Some default text

Not available in WML mode; uses plain text box instead.

Tick boxes and radio icons
<input type="checkbox"|"radio">

(not available in WML mode)

Tick (or "check") boxes and radio icons are very similar - the user clicks on them to select or deselect them, and any selected items are listed in result received at the other end. You can have any number of tick boxes, all of which should have a different name to differentiate them; radio icons, however, are for multiple choice questions where selected one icon with the same name unselects any others with the same name. If you want to have more than one group of radio icons, just give the second set a different name.

You can change the value that is sent through by using the value="..." attribute - vital for radio icons to tell one from the other, but for tick boxes perhaps you can use it to give it an easier-to-read value (usually it returns either "on" or doesn't appear at all if switched off); and you can select an icon by default simply by adding checked - this is done by selecting the Selected tick box in HTML³, as I can say with very little chance of contradiction that HTML³ won't go down big in America.


Untick this box if you do not want to be added to our mailing list

<input type="checkbox" name="maillist" checked>
 Untick this box if you do not
 want to be added to our mailing list

Decision time:

Decision time:
<input type="radio" name="decision" value="yes" checked>
<input type="radio" name="decision" value="no">;
<input type="radio" name="decision" value="maybe">


You can create menus by putting <option...> tags inside a <select..></select> pair.

The opening <select...> tag should have a name="..." to identify it; you can also add multiple (with no extra parameters) so that more than one option can be selected in the list. Some computers also allow you to add size=".." so that a box with more than one line is shown - instead of using a separate menu to select an option, the user can select from one (or more) of the options displayed inside the box.

Options are added using the <option> tag. These tags are immediately followed by the plain text which is used as that option's display in the menu. This text is returned as the value of this selection, unless you define another piece of text using the value="..." attribute. Similar to the tick boxes and radio icons you can add selected (with no extra parameters) to choose an option other than the first in the list to be the default. Finally you can close the tag using </option>, which is required under xHTML (HTML 4) but not really necessary under HTML 3.

This URL changing script is a good example of a selection form:

<form method="get" action=
<select name="url"> <option value="/support/">General support</option> <option value="/support/acorn/">Acorn support</option> <option value="/support/pc/">PC support</option> <option value="/support/mac/">Mac support</option> <option value="/support/web">Web stuff</option> <option value="">ArgoNet home</option> <option value="users">User pages</option> <option value="links">Links elsewhere</option> </select><input type="submit" value="Go!"> </form>

In the above code, the cgi script is passed url= and then the value of whatever option was selected - for instance, if the General support option was selected, url=/support/ is passed on.

Further info
To embellish this drop-down script, you can bypass the need for a cgi script altogether and use the faster JavaScript method; or use a combination of JS and "regular" methods for cross-browser compatibility. There's code to show you how in the JavaScript tricks section.

<input type="submit"|"reset">

There are basically two buttons you should be aware of - a submit button in the form of a <input type="submit"> tag will probably be needed on all forms to send the data off (although you can use images instead - see below), and it's usually nice to have <input type="reset"> so that the user has a way of resetting the form back to the default values in one easy step. Some people maintain that clear buttons are more trouble than they're worth - if someone's just spent ages filling out a form they can correct it by hand, but will be much vexed if they accidentally click clear instead of submit and have to start from scratch.

Both of these can have the text displayed on the button changed by using the value="..." attribute. For instance:

You can or you can
You can
<input type="submit" value="send this">
or you can
<input type="reset" value="wipe it clean">

<input type="image"...>

You can also use an image instead of a submit button; its attributes should be familiar to those of you who have used the <img...> tag with its attributes.

The main attribute you need is to tell the browser where to get the image from; as with the <img...> tag this is done using the src="..." attribute. You can also include width=".." and height=".." tags to tell the browser how big the image will be before it is downloaded. One change however is that to change the text displayed if the image can't load, you don't use the alt="..." attribute; here it is value="..." instead.

However, by using an image instead of a "proper" submit button, you also get extra information sent along with the form data - the x and y coordinates of where you clicked on the image, which obviously with the right cgi script is used to make imagemaps work. You can change the name of this data from x and y using the name="..." attribute, so for instance name="wubble" will return wubble_x and wubble_y. This could be useful to differentiate between different images in the same form, although don't forget that, due to the image acting like a submit button, you will only be able to get the data from one image at a time.

An example from real life is a site I designed to automatically edit web pages; by changing some text boxes and clicking submit the user updates their site. However, using image buttons it was possible to go to another page and pick some clipart, then go back to editing the site without losing any text changes. This is because the clipart image button submitted the same data, but I was able to tell the difference between a "real" submission and a "hold on to this data while I choose a picture" submission.

Also remember that HTML³ allows you to drag-and-drop images onto the Forms window to get all the data you need, including sizing.

Sending CGI data manually

Here are two examples of either sending data to a CGI which does not rely on forms, and a fake CGI URL that can help out with keeping track of how popular a mailing is.
  1. Hand coding a CGI URL
    The most obvious use of this is to get a CGI generated image - a web counter or similar - or use it in links to get to a CGI-generated page.

    Basically, you access the CGI by using the path -
    - and then the first parameter you send must be preceded by a question mark:
    Any subsequent parameters however must be preceded instead by the ampersand (&) character, such as:
    (actually you should really encode that ampersand as &amp;, as some browsers get confused; and it's good practice as some of the simpler languages like WML require it).

    To put it all together into a working example:
    <img src=
    " &amp;fore=10&amp;back=7&amp;brdr=1&amp;size=1">

    If you want to get further into it, any spaces must be replaced by pluses (+); if the text includes pluses, ampersands, question marks, equals signs and any characters above character 127 (that is, any extended characters or foreign letters) they must be encoded in the usual MIME way, that is by using an equals sign followed by two hexadecimal characters, for instance =3D is the code for an equals sign; however, you replace the = with a percentage mark, so a space (character 32, or 20 in hex) could also be %20.

    If you can't convert ASCII characters into hex in your head (shame on you! Smiley) then I suggest you try and get a copy of the scientific calculator (SciCalc) by E. Spier (my copy is 1.06c 12-Sep-90) which allows you to pick characters from a !Chars-like layout and display them in whatever base you need - decimal, hex, binary, whatever. The Acorn/RISC OS scientific calculator doesn't seem to have this function I'm afraid, so scour those PD libraries and FTP sites.

  2. Faked URLs
    It's a little known fact that you can have this kind of data attached to any page URL, and if the page doesn't know what to do with it, it will be ignored. So for instance I could have and it will work just like the regular URL.

    So what good is this, I hear you cry? Well, the browser might ignore this extra data, but the server doesn't when it's logging accesses to that page - it shows up as a whole different URL. So, if you have access to your web logs, and send out regular emails pointing people to your site, you can see how popular these emails are by adding a unique code to the end of all URLs in that message and see how many hits this modified URL gets over the next few days. I'll be greping for index.html?html3 in my web logs real soon now...

Putting it all together

The following form is an example mailing system. If you examine the source of this document you should be able to find it right at the bottom of the file and copy it for your own use.

Don't forget to change the mailto, mailsubject and linkto options - it won't do anything useful unless you do change them. Also, to change the colours you should do a search and replace for the light blue (#CCCCFF), dark blue (#3300AA) and possibly the white text (#FFFFFF).

If you don't subscribe to ArgoNet's service, well, if you use this script on your own head be it...

Quick message
Use this to send a short message to NOBODY
Your name: Your email:

WML Forms

Forms in WML are a little different to HTML; they don't have some options like tick boxes and radio icons, but you do get cool stuff like variables which means you can do some simple scripting on a device whose browser is only 1.3KB in size!

The more usual way of doing forms, which takes up less space, you need to construct a URL with all the names of the variables you're using throughout the form, such as:

 <a href="/cgi-bin/formhandler?


<do type="accept" label="Submit">
 <go href="/cgi-bin/formhandler?

...which is both the submit button and the data usually contained in the <form> tag in HTML.

Obviously I can't capture all of that information before outputting the first tags, so I'm having to use <postfield> tags all over the place to try and get around this. You should be able to remove the <go>...</go> tags, add in the <do>...</do> tag at the top of the form as described above, generate the URL and then remove all the <postfield> tags if you really want that tidier version.

Be aware that you MUST use &amp; in the URL, not just the & symbol, as this will cause errors; variables must be encased in brackets; and <select> lists with multiple selections don't return a CGI parameter per selection (&food=cake&food=crisps&food=chips), it strings them all into a semi-colon separated list (&amp;food=cake;crisps;chips). Plus the lack of radio icons and tick boxes means you'll have to get creative with select lists anyway.

Here's a bit of PERL that'll convert standard HTML multiple selections into the WML style (or leave unaltered any WML styled ones passed to it), so you only have to parse the WML style in programs. Note that @multiples=param("multiples"); means that only the parameter with the name "multiples" will be processed, so you might want to alter the code so that the subroutine will use any parameter name that's passed to it.
use CGI qw(param);


sub munge_multiples {
  # convert HTML-style multiple list into WML style...
  @multiples = param("multiples");
  if ($afcount > 1) {
    for ($afloop=0; $afloop<$afcount; $afloop++) {
    $afmore =~ s~^;~~s;
  } else {

  # ...$multiples now holds a semi-colon separated list.

Finally, a couple of tips for text/password input boxes: format="*N" will only allow numbers to be entered (useful if you don't want people to have to press every button four or five times just to enter a number; numeric passwords might be easier on them as well); and emptyok="false" means that a form must be filled in before submission.

HTML³: © Richard Goodwin 1997-2002