Chapter 6: Beginning JavaScript
Controlling Data Entry Using Form Fields
Passing data from one form to another
Addressing Form Field Validation with Regular Expressions and JavaScript 1.2
You are here: irt.org | Articles | JavaScript | Form | Creating 'Encoded' Name & Value Pairs [ previous next ]
Published on: Tuesday 13th April 1999 By: Martin Webb
Have you ever wanted to submit form data without using a form? Have you tried and failed? Or have you gotten fed up with handcrafting the encoded URL data and given up? Then this article is for you.
This article will show you how to create your own JavaScript tool to perform all the encoding automatically. We'll present a form that you can use and extend to prepare your own encoded URLs.
Why would you want to send form data without a form? Well, you could provide a text or image link that passes data back to the server or to another page, perhaps as a generic feedback form where the title and author of the document is passed to the generic feedback form.
Before we get too carried away, we need to examine how form data is handled by the server. There are two basic methods of passing data to the server, using either the GET or POST method, as specified in the form's METHOD attribute:
<FORM ACTION="/cgi-bin/feedback.pl" METHOD="GET">
Or:
<FORM ACTION="/cgi-bin/feedback.pl" METHOD="POST">
The program on the server can be written to handle both method types. Before we do this, let's examine the differences between GET and POST.
GET encodes the data and appends it to the end of the URL. For example the following form:
<FORM ACTION="feedback.pl" METHOD="GET"> <INPUT TYPE="TEXT" NAME="title" VALUE="Creating 'Encoded' Name & Value Pairs"> <INPUT TYPE="TEXT" NAME="author" VALUE="Martin Webb"> <INPUT TYPE="SUBMIT"> </FORM>
Once submitted, it requests the following document from the server:
feedback.pl?title=Creating+%27Encoded%27+Name+%26+Value+Pairs&author=Martin+Webb
The request is to GET the document, and at the same time pass the encoded name/value pairs of the form to the document. It is then up to the document to retrieve the name/value pairs passed to itself.
Note that the encoding of the data replaces any spaces with a "+" character, and any punctuation, or any characters outside of the standard ANSI character set with the two digit hexidecimal number of the characters' Latin-1 (ISO-8859-1) encoding value. The "%" character indicates that the following number is hexidecimal.
The following table shows the Latin-1 and hexidecimal values of the more common non-standard ANSI characters:
ANSI | Latin-1 | Hex | ANSI | Latin-1 | Hex | |
---|---|---|---|---|---|---|
! | 33 | %21 | < | 60 | %3c | |
" | 34 | %22 | = | 61 | %3d | |
# | 35 | %23 | > | 62 | %3e | |
$ | 36 | %24 | ? | 63 | %3f | |
% | 37 | %25 | @ | 64 | %40 | |
& | 38 | %26 | [ | 91 | %5b | |
' | 39 | %27 | \ | 92 | %5c | |
( | 40 | %28 | ] | 93 | %5d | |
) | 41 | %29 | ^ | 94 | %5e | |
* | 42 | %2a | _ | 95 | %5f | |
+ | 43 | %2b | ` | 96 | %60 | |
, | 44 | %2c | { | 123 | %7b | |
- | 45 | %2d | | | 124 | %7c | |
. | 46 | %2e | } | 125 | %7d | |
/ | 47 | %2f | ~ | 126 | %7e | |
: | 58 | %3a | | 127 | %7f | ; | 59 | %3b |
With POST, the form name/value pairs are sent after the URL request has been sent. Generally, POST is only used when posting data to the server. The process on the server uses the standard input to retrieve the name/value pairs.
As the name/value pairs are not part of the URL, it is impossible to simulate a form submission using the POST method without using a form. The rest of this article will concentrate on the GET method.
Suppose we wanted to capture feedback on this current article. Instead of placing a feedback form at the bottom of the article, which might only get filled in and returned by a few visitors, we could link to a generic feedback form.
This reduces the file size of the article, the bandwidth necessary to send it, and the time it takes to display. What's more, we only have to maintain one feedback form.
The disadvantage is that, unless we pass the details of the article to the feedback form, we wouldn't know which article the feedback was for.
We could use a form with a single submit button and several hidden form fields to pass the data from the article to the feedback form, but this involves the submission of two forms, with two warnings to the user that they are submitting form data over the Internet.
Using a text link to the feedback form with the data already encoded in the URL will overcome this problem.
Each time an article is created, the author will have to hand-craft the encoded URL. The encoding ensures that the data arrives at its destination, regardless of the character encodings used by the many computers and networks that the data may pass through.
The manual approach will require you to translate each non-standard ANSI character to the Latin-1 hexidecimal character. So:
Creating 'Encoded' Name & Value Pairs
is manually edited, step by step:
Creating+'Encoded' Name & Value Pairs Creating+%27Encoded' Name & Value Pairs Creating+%27Encoded%27 Name & Value Pairs Creating+%27Encoded%27+Name & Value Pairs Creating+%27Encoded%27+Name+& Value Pairs Creating+%27Encoded%27+Name+%26 Value Pairs Creating+%27Encoded%27+Name+%26+Value Pairs Creating+%27Encoded%27+Name+%26+Value+Pairs
Are you sure you've converted all the characters to the correct value? Have you missed any? Why not automate the process?
The following text link, when clicked, will alter the URL in a JavaScript-enabled browser, to include an encoded title name/value pair:
<A HREF="feedback.pl" onClick="this.href='feedback.pl?title =' + escape('Creating \'Encoded\' Name & Value Pairs')">Feedback</A>
The problem is, not everyone uses a JavaScript-enabled browser, and some who do disable JavaScript. Without JavaScript, the page is loaded but it won't receive any data telling which article the feedback is about. Do you want to take the risk that the one person who might provide valuable feedback didn't have JavaScript switched on? The problem is, that not everyone uses a JavaScript enabled browser, or
It would be better to encode the data beforehand.
The final part of this article will demonstrate a simple tool that you can adapt and extend for your own purposes. You'll be able to use it with a JavaScript-enabled browser to automate the production of encoded name/value URLs, which you can then simply cut and paste into the article before you publish it.
The following form shows how to encode a single name/value pair, where the name of the data is "title" and the value is whatever is entered in the Title text field:
There is, however, one subtle difference between the data encoded by the JavaScript escape() method, and the data encoded when a form is submitted. The escape() method replaces the space character, not with the "+" character, but with the Latin-1 hexidecimal %20. This shouldn't normally cause any problems, as most CGI scripts can decode either correctly.
The HTML and JavaScript code to perform the encoding is extremely simple:
<FORM> <P> Title: <BR> <INPUT TYPE="TEXT" NAME="title" SIZE="60" VALUE="Creating 'Encoded' Name & Value Pairs"> <P> <INPUT TYPE="BUTTON" onClick="this.form.output.value='title=' + escape(this.form.title.value)" VALUE="Create"> <P> Encoded URL: <BR> <INPUT TYPE="TEXT" NAME="output" SIZE="60"> </FORM>
In fact, it's too simple. It doesn't allow for any additional name/value pairs.
The following example demonstrates a form that allows you to select which name/value pairs are added to the encoded URL. It shows how to select values from a select form field, and allows you to add an additional name and value:
The HTML and JavaScript code to create the form looks like this:
<SCRIPT LANGUAGE="JavaScript"><!-- function createEncodedNameValuePairs(what) { var output = ''; if (what.titleChecked.checked) { output += escape(what.titleName.value) + '=' + escape(what.titleValue.value); } if (what.authorChecked.checked) { if (output != '') output += '&'; output += escape(what.authorName.value) + '=' + escape(what.authorValue.options[what.authorValue.selectedIndex].text); } if (what.unknownChecked.checked) { if (output != '') output += '&'; output += escape(what.unknownName.value) + '=' + escape(what.unknownValue.value); } return output; } //--></SCRIPT> <FORM> <P> <INPUT TYPE="RESET"> <P> <INPUT TYPE="CHECKBOX" NAME="titleChecked" CHECKED> Title: <INPUT TYPE="TEXT" NAME="titleName" SIZE="7" VALUE="title"> Value: <INPUT TYPE="TEXT" NAME="titleValue" SIZE="40" VALUE=""> <P> <INPUT TYPE="CHECKBOX" NAME="authorChecked" CHECKED> Author: <INPUT TYPE="TEXT" NAME="authorName" SIZE="7" VALUE="author"> Value: <SELECT NAME="authorValue"> <OPTION>Martin Webb <OPTION>Chuck Toporek </SELECT> <P> <INPUT TYPE="CHECKBOX" NAME="unknownChecked"> Unknown: <INPUT TYPE="TEXT" NAME="unknownName" SIZE="7" VALUE=""> Value: <INPUT TYPE="TEXT" NAME="unknownValue" SIZE="40" VALUE=""> <P> <INPUT TYPE="BUTTON" onClick="this.form.output.value=createEncodedNameValuePairs(this.form)" VALUE="Create"> <P> Encoded URL: <BR> <INPUT TYPE="TEXT" NAME="output" SIZE="60"> </FORM>
As you can see, this small but effective tool is extremely useful. It will save time when pre-encoding data for use on text links.
The last time I wrote an article on forms, I was criticized for not providing a CGI script example to handle the form submission. So for all those who need one, here is a simple CGI script that can accept the encoded title and author URL data from the previous example and then display it on a feedback page:
#!/usr/local/bin/perl $buffer = $ENV{'QUERY_STRING'}; @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/<!--(.|\n)*-->//g; $FORM{$name} = $value; } print "Content-type: text/html\n\n"; print << "(END HTML)"; <HTML> <HEAD> <TITLE>Feedback: $FORM{title}</TITLE> </HEAD> <BODY> <FORM ACTION="mailto:martin\@irt.org" METHOD="POST" ENCTYPE="text/plain"> <P> Title: <BR> <INPUT TYPE="TEXT" NAME="title" SIZE="60" VALUE="$FORM{title}"> <P> Author: <BR> <INPUT TYPE="TEXT" NAME="author" SIZE="60" VALUE="$FORM{author}"> <P> Your Name: <BR> <INPUT TYPE="TEXT" NAME="name" SIZE="60" VALUE=""> <P> Your Email Address: <BR> <INPUT TYPE="TEXT" NAME="email" SIZE="60" VALUE=""> <P> Comments: <BR> <TEXTAREA NAME="COMMENTS" COLS="60" ROWS="10" WRAP="VIRTUAL"></TEXTAREA> <P> <INPUT TYPE="RESET"> <INPUT TYPE="SUBMIT"> </FORM> </BODY> </HTML> (END HTML) exit;
The above CGI script will present a form with the title and author fields pre-filled, which will, when submitted, send an e-mail with the feedback comments.
Chapter 6: Beginning JavaScript
Controlling Data Entry Using Form Fields
Passing data from one form to another
Addressing Form Field Validation with Regular Expressions and JavaScript 1.2