How can I submit a form via email, without using CGI?
Forms are great tools for collecting information from web surfers passing through a site. Unfortunately, because most forms require CGI programs for processing, people with little or no programming experience are often unable to implement them. Additionally, some users who actually do understand CGI may not be authorized to run CGI programs on their web sites.
For these people, the mailto
form submission protocol, which enables clients to submit completed forms via email, is an invaluable substitute. When used by itself, however, this protocol generates extremely difficult-to-process email -- so difficult, in fact, that it is really not fit for human consumption. In this article, I will describe a technique in which the mailto protocol is combined with JavaScript to produce forms that are submitted via human-readable email.
In new browsers, this can be done by specifying the recipient's email address in the "action
" field of the <form>
tag, as shown in the following example:
Note that when an email address is given as a URL, it must be prefixed with the<form method="post" action="mailto:sharky@sharky.com"> . . . (form elements) . . . </form>
mailto:
protocol identifier. In the example above, the form data will emailed to sharky@sharky.com.
You may also wish to send the email with a particular subject. This is done by appending a subject specifier to the end of the mailto
URL:
A subject specifier consists of the keyword "action="mailto:sharky@sharky.com?subject=your web site"
subject
," followed by an equals sign, and then by the actual subject text. As shown, the email address and the subject field must be separated by a question mark. Except for the actual subject text, a properly formed mailto
URL should not have any spaces in it.
would be transmitted to a CGI program asname = "Sharky" comment = "It's hard to read!"
We certainly don't want our email to look like this! To send the form data in a human-readable format, we must set thename=Sharky?comment=It%27s%20hard%20to%20read%21
<form>
tag's enctype
field (i.e., the form's encoding type) to "multipart/form-data
." This option instructs the browser to send the data as a plain text, multiple-attachments email message. In this format, the first data item in the form becomes the body of the message, and each additional item is included as an attachment. In both the main message body and in the attachments, identifiers are stripped from the data, leaving only the values.
...and that you want it to produce the following email message:
Because the multipart/form-data encoding type will send each item of the form as a separate email attachment, formatting the data so that it all appears in the main message body -- and in an intelligent, human-readable format -- is not a trivial task. If you're thinking, "This is a job for JavaScript!," you are right.Greetings. I have a comment for you. It is: I like it. Sincerely, Sharky
The basic idea is to use two forms: an input form and a proxy form. The input form contains the actual form elements through which the user inputs data -- text fields, radio buttons, check-boxes, etc. -- everything, that is, except for the actual submit button. The submit button is part of the second form, or the proxy form. When pushed, it activates a JavaScript routine that transforms input data from the first form into human-readable email. Let's discuss the procedure in greater detail.
Don't forget to name each element of the form, including the form itself, so that JavaScript can be used to access them later. In this example, the form's name is "<form name="form_data"> <pre> Name: <input name="username" type="text"> Comment: <input name="comment" type="text"> </pre> </form>
form_data
," and the two input fields are called "username
" and "comment
."
It is not necessary, nor is it useful, to specify the input form's action
, method
, or enctype
, since the input form itself will never be submitted.
method
set to "post
," its enctype
set to "multipart/form-data
," and its action
set to a valid mailto
URL:
Take special note that the<form name ="proxy_form" method ="post" enctype ="multipart/form-data" action ="mailto:sharky@sharky.com?subject=your web site" onSubmit="return update_message_body ();">
<form>
tag has an onSubmit
event handler that calls a function named "update_message_body
." The purpose of this event handler will be explained in step (3).
In order send the data as a normal email message, without attachments, the proxy form should have only one named field. Furthermore, this field should be a "hidden
" field so that the user cannot interact with it.
As mentioned earlier, the submit button is also included in the proxy form:<input type="hidden" name="message_body">
It should appear to the user as if the submit button will send the input form created in step (1). (When pushed, however, it will actually send the proxy form.)<input type="submit" value="send mail">
onSubmit
event handler will be executed. Since the form cannot be mailed until after the event handler has completed, the event handler can be used to generate the email message just before it is sent!
Here is a function that generates a formatted message from data entered in the original form:
This function, called by the<script> function update_message_body () { var username = document . input_form . username . value; var comment = document . input_form . comment . value; document . proxy_form . message_body . value = "Greetings.\n" + "\n" + "I have a comment for you. It is:\n" + "\n" + "\t" + comment + "\n" + "\n" + "Sincerely,\n" + username + "\n"; return true; } </script>
onSubmit
event handler, reads fields from the main form to build a single message string, which is then copied into the proxy form's hidden element.
Whenever false
is returned by an onSubmit
event handler, the submit process is aborted. Since the value returned by update_message_body
is also returned by the event handler, update_message_body
should return true
only if it is OK to send the form. This is your chance to validate the information entered into the form before sending it.
By the way, you should use great care when programming the onSubmit
event handler. If the JavaScript interpreter encounters an error while processing the event handler, the entire event handler will be aborted, and the form will be submitted anyway -- even if the proxy form's message_body element has not been properly initialized.
action
field on the fly, there is no reason why you can't change the email message's subject or destination address within the event handler. All you need to do is generate a new action string and copy it into the proxy form's action property:
When the form is submitted (mailed), the new action string will be used instead.new_action = "mailto:" + new_destination_address + "?subject=" + new_subject; document . proxy_form . action = new_action;
Form's submitted via email, unfortunately, are not automatically followed by a response page. When a user pushes the submit button, the mail will indeed be sent, but the browser window will just "sit there" and not show a response (except in the status bar, which provides information about the progress of the email being sent). Confused, some users will push the submit button over and over again, desperately hoping for a response, and send multiple copies of the same form before finally giving up!
This means that you should provide the user with instructions about what to do after mailing the form. (I.e., "Click here after you have submitted the form.") It would be nice if JavaScript provided methods for detecting when the browser has finsihed sending email. If these were available, then JavaScript could be used to automatically load a response page after sending the mail. At the time of this writing, however, there is no way for JavaScript to detect when the browser has finished sending email.
One possible work-around is to activate a window timer that loads the response page some arbitrary time after the submit button has been pressed. This solution, however, cannot work for everyone because the amount of time required to send mail is different from browser to browser and user to user, and cannot be predicted accurately.
If you find a good solution to this problem, I would like to hear about it.
Charlton Rose
March 25, 1997