Fill out our sample form
(Hint - watch the status bar at the bottom of your browser)!
What is your Name? (Given name)
(Surname)
 
Your e-mail address?
What did you think of our JavaScript tutorial?
I enjoy ..............
C++ )
) Check one or more
)
Java
Self-flagellation
Whom do you support for US president?  
Al Gore
Saddam Hussein
Robert Mugabe
Any comments?

     

Checking inputs

The form should actually work - so perhaps it's not a good idea to send us twenty copies filled with garbage (Just a tiny request)! Clearly the quality of the form design determines the information you get out, the usual GIGO equation. We're not going to go into that here - we will simply give a few hints about how to check the form inputs.

The first advice is "don't" ! Most users hate being second-guessed, and if you do put in all sorts of checks, make sure they are reasonable (We've been as guilty as anyone of this error). For example, Malcolm X couldn't get the above form to submit unless he fudged his surname somehow.

It should be clear how we've designed the above form. You can always view the source, and we've previously explained (part 3) the various form components, almost all of which are represented above. The check functions we've defined need a bit of explanation. Here goes..

Checking the surname

Okay, this is rather silly, but at least we check that there is something in the surname field (We have no check of the given name field). We attach the function ValidSurname to the input box thus:

The text input
  <input type="text" name="surname" size="30" 
         onChange="ValidSurname(this, true)">

All pretty straightforward and above board - we have a text input called "surname", and when the contents change, we invoke the function ValidSurname with two arguments. The second argument is just the Boolean value true - we'll explain how we use this in a moment. The first argument is more interesting. What does this mean? It's rather special - we use this to refer to the current object - here the text input itself! Let's see how ValidSurname handles this:

The ValidSurname() function
function ValidSurname (name, chirp)
  { var okay = true;
    if (name.value.length < 2)  
          okay = false;
    if ( (! okay) && chirp )
         { alert ("Hmm. '"
                  + name.value
                  + "' - a very strange surname. Try again!");
           name.select();
           name.focus();
         };
    return okay;
  }

The first argument, name is clearly just the text input box we passed as "this" - we extract the surname that was typed in using name.value, and then rather clumsily display a message on the screen if the length is under 2 characters. Note that we now understand the second argument passed to ValidSurname - if 'chirp' is true, then the message is displayed, otherwise not. In any case, we return true if the surname is valid, and false otherwise.

See how we can use the select and focus methods to transfer control to the offending name (if an error occurs). Most useful!

Checking the email address

Similarly, the email checker is rudimentary. If you go out there on the web, you'll find oodles of semi-intelligent email address checkers. If you use one, just remember to update it now that the new top-level domains are out!

Our email checker satisfies itself with:

  1. Checking the length of the address (under 5 characters would be a bit strange);
  2. Checking that there is an "@" sign;
  3. Checking that there is a "." after the "@" sign.

And that I am afraid is that! Here our simple code is:

Checking the e-mail address
function ValidEmail (addr, chirp)
  { var fail = false;
    if (addr.value.length == 0) return false;
    var atpos = addr.value.indexOf('@',0);
    if( (addr.value.length < 5) || (atpos == -1)  )
        fail = true;              // too short or no '@'
    if (! fail)
       { if (addr.value.indexOf('.',atpos) == -1)
            fail = true;          // no '.' in address after the @
       };
    if ( (fail) && (chirp) )
        { alert ("Warning!\n The email address "
                 + addr.value
                 + " is invalid!");
          addr.select();
          addr.focus();
        };
    return (! fail);
  }

Nothing really fancy here, is there? (Incidentally, you might note that previously we've been too pedantic with putting curly braces in our if statements - a single statement after an if doesn't require these).

Checking the form before sending

If you tried out the form, you had to confirm sending. A good idea. Here is how the form invoked this checking function:

The form
<FORM name="demoform" 
      ACTION="/cgi-bin/FormMail.pl"
      METHOD="POST"
      onSubmit="return CheckInput(this)" >

      /* our form inputs etc go here */

</FORM>

We'll discuss the method and action in the next two sections. Here we look at the CheckInput function, which we provide with the whole FORM object (by giving it a 'this'). Here is CheckInput:

Checking the Input
function CheckInput (thisform)
  { var errors = 0;                             //error count
    var duditem = "";                           //remember where it failed!
    var message = "\n";                         //error message

  if (! ValidEmail (thisform.email, false) )
        { errors ++;
          duditem = thisform.email;
          message += "Your email address is invalid!\n"; 
        };

  if (! ValidSurname (thisform.surname, false) )
        { errors ++;
          duditem = thisform.surname;
          message += "Your Surname appears inaccurate!\n"; 
        };

  if (errors == 0)
     { if ( ! confirm ("Dear "
                   + thisform.forename.value + " "
                   + thisform.surname.value
                   + "\nYour form is about to submitted."
                   + "\n Are you sure you want to do this?" ) )
           { errors ++; };
     } else
     { message += "\nPlease FIX THIS AND RETRY\n(Click on OK, fix errors)!";
       if (errors == 1)
           { alert  ("There was an error in your submission\n"
                     + message);
           } else
           { alert ("There were errors in your form\n" + message);
           };
       duditem.select();
       duditem.focus();
     };

  if (errors != 0) return (false);
  return (true);      
  }

Although rather long, there are few surprises. We set up an error message (initially blank) and an error count. We then invoke the functions we previously defined (with no 'chirping'), and confirm sending of the form, unless there are errors. We also remember the most recent object where an error occurred, which tells us something about the order in which we should check our inputs! And that is that!

Adding options

Sometimes you may wish to dynamically add options to a selection.

An example of creating a new option:

polly = new Option("Parrot", "pol1", false, true);
birds.options[4] = polly;

To delete an option from the options array, set it to null - the other options are then RE-INDEXED.

Such altering of options, and the Option() constructor are only available from JS 1.1.

If you add Options in older browsers, you MUST refresh the page using eg. window.history.go(0)

Send!

In part 3 of our tutorial we introduced forms and their properties. Here we look at them in more detail. Here are form properties again:

form properties
Property Meaning
action (specifies where form data are sent - a common destination is e.g. "/cgi-bin/FormMail.pl" - to a Perl script)
elements Each form element is represented here! (See below)
length Tells us the number of elements
encoding MIME encoding
method (how is information sent to the server? "GET" or "POST")
name useful in referring to the form by name
target Say where 'responses' should go (usually the name of a window)

The form method

There are two different ways that your browser can send information from a form. They are called GET and POST. The usual method is POST - the browser opens up communication with a Common GateWay Interface or 'CGI' script (usually written in an elegant language called Perl) that lives on the computer hosting your web-page. With POST, data are written to the 'standard input' of the CGI script, allowing virtually unlimited amounts of data to be sent. The second method is called GET, and is much more restrictive, as data are encoded and attached to the URL of the CGI program as an 'environment variable' - the length of the information is limited.

The action

The method property (GET or POST) can be reset in JavaScript. Not only can you change the method, but also the action attribute. This allows one to dynamically change the CGI program you are routing the information to! In our form above, we use:

ACTION="/cgi-bin/FormMail.pl"

which sends the information (using POST) to the popular form handling program called FormMail. We look at FormMail in detail below.

MIME encoding

There are several different methods of MIME encoding. The usual MIME type is "application/x-www-form-urlencoded", but other types are possible (and at present beyond the scope of this discussion). You don't have to worry about this - it's just fine print.

Hidden fields

If you view the source of our sample form, then you'll see that we use hidden fields extensively. These are used to pass additional information to the CGI program. Here they are:

Hidden fields
 <input type=hidden name="subject" value="Feedback Form">
 <input type=hidden name="recipient" value="feedb@anaesthetist.com">
 <input type=hidden name="redirect"
    value="http://www.anaesthetist.com/mnm/javascript/doform.htm#check">

Let's find out how we use these hidden fields, by finding out more about FormMail.

Using FormMail

FormMail is a deservedly popular, general-purpose CGI script (written in Perl) which converts form information into an e-mail. The really great thing is that you don't have to know anything about CGI scripts. FormMail was written by Matt Wright, and is Copyright, but may be used free of charge.
(If you use it you should read the copyright notice, which is freely available all over the web, together with the script itself)!

Installing FormMail yourself

Most grown-up servers will have a copy in the relevant (cgi-bin) directory - if yours doesn't your administrator should be able to sort this out, otherwise change your host! We're not here going to discuss setting up the FormMail script, as this information is readily available on the Web if you have to do so.

Hidden Fields

There is only ONE field you MUST have for FormMail to work. This is the

<input type="hidden" name="recipient" value="somebody@xyz.xxx">

field. (You have to fill in a real email address in place of "somebody@xyz.xxx"). All other hidden fields are optional, and use the same format as the "recipient field". Here they are:

Optional FormMail fields
Field Use
subject This appears as the subject field in the resulting e-mail.
email This is the return email address of the person filling out the form.
realname Put into the "From" line of the e-mail.
redirect This says where the user will be sent once the form has been sent off. (Several options are available to customise the form that results if redirect is NOT set up, including background, bgcolor, text_color, link_color, vlink_color, alink_color, as well as title, return_link_url, return_link_title. You will probably never use these, so ignore them).
required Most useful. In the value="" field you put the names of all the fields that MUST be filled in, separated by commas. If the user left one out, they will be sent an 'error message', and the e-mail won't go off! But we can do better with JavaScript pre-processing. The missing_fields_redirect option allows you to specify the URL the user is sent to if there is an error, rather than the program generating a generic 'error' web-page.
env_report FormMail tells you (in the e-mail) something about the browser environment the user is working in! You can for example specify:
<input type="hidden" name="env_report" value="REMOTE_HOST,REMOTE_ADDR" >

There are more options (for CGI version 1.1) for example: AUTH_TYPE (authentication scheme that validates the user), CONTENT_LENGTH (number of characters passed via standard input), CONTENT_TYPE (the MIME type), GATEWAY_INTERFACE (CGI version), HTTP_* (where * represents the various HTTP headers received by the server, for example HTTP_ACCEPT and HTTP_USER_AGENT ), PATH_INFO (extra path information), PATH_TRANSLATED (full path from URL), QUERY_STRING, REMOTE_IDENT (verified name of host associated with the browser requesting information), REMOTE_USER (name of user!), REQUEST_METHOD (our old friends GET, POST, ..), SCRIPT_NAME (path and name of CGI program), SERVER_NAME (namve of Web server host), SERVER_PORT (the HTTP port, commonly 80), SERVER_PROTOCOL (name and version of protocol used by requesting browser), SERVER_SOFTWARE (web server software)

sort Allows you to sort alphabetically ( value="alphabetic" ), or in a given order by listing the field names ( value="order:fieldname1,fieldname2" )
print_config Allows you to 'print' certain configuration variables in the body of the email. For example:
<input type="hidden" name="print_config" value="email">
print_blank_fields By default, FormMail does not include blank fields in the e-mail it generates. This (with value="1") allows you to do so.

Now the hidden fields we used above should make sense. Here they are again!

Hidden fields
 <input type=hidden name="subject" value="Feedback Form">
 <input type=hidden name="recipient" value="feedb@anaesthetist.com">
 <input type=hidden name="redirect"
    value="http://www.anaesthetist.com/mnm/javascript/doform.htm#check">

Summary

You now have a sample form that you can mutilate and abuse to your own ends, as well as a brief introduction to FormMail. Enough of forms! Let's
find out about frames.


Webpage author jvs@anaesthetist.com Last update: 2000-10-7