cybercoded.com | Articles | Form -> Cookie
-> Form | back
Introduction
The code described here is generic, i.e. it can be used
with any type of form you wish to produce.
It supports the storing of information from the
following form element types:
- text, i.e. TYPE="text" or
"textarea" or "password" or "hidden"
- select
- radio
- checkbox
Form Elements
It is important to distinguish the type of element when
setting its value, as its type dictates how the value is set.
To set the value of a text element, the following
syntax is used:
document.formName.elementName.value = elementValue;
|
To set a select element, the following syntax is used:
document.formName.elementName.selectedIndex = elementValue;
|
To set a radio element, the following syntax is used:
document.formName.elementName[elementValue].checked = true;
|
To set a checkbox element, the following syntax is
used:
document.formName.elementName.checked = true;
|
One limitation that has to be observed when using a
group of radio elements, as the group of radio elements all have the same name
(that's why they are a group), the only way the individual radio elements within
the group can be accessed is via their index, which must be a numeric integer.
Therefore the elementValue used in the above syntax must be a numeric integer
that corresponds to the required radio elements index. More about this later.
Rather than create a whole stack of JavaScript
functions to vet the element values, and pack them together in preparation to
store them as a cookie - we will cheat!
The Search String
One feature of forms, is that when the form is
submitted it will pass the value of all its forms elements as a string. This
string is passed as the search property of the location object. This nicely
bundles up all the names of the elements with their values, which is then passed
to the next document.
Within the next document, we can strip the search
property and store it whole as the value of new cookie.
Instead of loading a new document, if no new target is
specified in the form, it will pass the form string to the current document.
When passing values of checkboxes, when a checkbox is
ticked the value "on" is passed, when the checkbox is not ticked no
value, and indeed no reference to the checkbox is passed. Therefore one must be
careful when marking checkboxes as "checked", because this may
override the intention of the user.
Psuedo Code
This then gives up the basis for the code, which can be
described by the following psuedo code:
- create store variable
- If search property contains info:
- store search property as cookie
- copy search property to store variable
- Attempt to get cookie info
- If cookie exists:
- copy cookie to store variable
- Display form using HTML
- When page loaded (using onLoad=""):
- Interrogate store variable - and update form
- If submit button pressed - pass form values back to
same document
This then gives us several distinct types of entry to
the document:
- 1st time in - no search string passed - no existing
cookie
Which shows the default form values and sets us up
for:
- 2nd time in - search string passed - no existing
cookie
Which will now create the new cookie and redisplay
the form values.
- 3rd time in - no search string passed - existing
cookie
Which will retrieve the cookie details and populate
the form, ready for:
- 4th time in - search string passed - existing cookie
Which will replace the existing cookie and
redisplay the form values.
Escaped Characters
One final point to raise - when form field value which
contains spaces is passed as a search string, the spaces are converted by the
browser to '+' characters. This is a feature of the browser that converts all
non alphanumeric characters to escape characters. For example:
Webmaster !"£$%^&*()_+
is converted to:
Webmaster+%21%22%A3%24%25%5E%26*%28%29_%2B
The spaces are convert to '+' characters and the '+'
characters are converted to '%2B'. This is so that search engines can tell which
individual words were entered in a search field.
This is not usually a problem as we can convert the
string back to its original using the unescape() method, which is this example
will convert it back to:
Webmaster+!"£$%^&*()_+
Which as you can see hasn't reverted back to the
original value. What is required is a simple find and replace function that
finds all instances of the '+' character and replaces it with a space character
before it is passed to the unescape() method.
Working Example
Right, now that we have got all the "ifs",
"buts" and assumptions out of the way, we can now produce some code.
As there has been too much waffle so far why not try
out this
example which will show the end
result. The example is a self contained document, with all HTML and JavaScript
functions. All that is required is an understanding of how to adapt it for your
own needs.
The JavaScript Source Code
The source code for the above example is show below. It
is broken up into pieces to enable us to understand what is going on:
<HTML>
<HEAD>
<LINK REL=STYLESHEET HREF="../../utility/main.css"
TYPE="text/css">
|
The above line refers out to a Cascading Style Sheet -
currently supported in Internet Explorer 3+ and Netscape Navigator 4+. Can be
removed if not required, or you could copy and adapt it for your own purposes.
<SCRIPT LANGUAGE="JavaScript"><!--
function Get_Cookie(name) {
var start = document.cookie.indexOf(name+"=");
var len = start+name.length+1;
if ((!start) && (name != document.cookie.substring
(0,name.length))) return null;
if (start == -1) return null;
var end = document.cookie.indexOf(";",len);
if (end == -1) end = document.cookie.length;
return unescape(document.cookie.substring(len,end));
}
function Set_Cookie(name,value,expires,path,domain,secure) {
document.cookie = name + "=" +escape(value) +
( (expires) ? ";expires=" + expires.toGMTString() : "") +
( (path) ? ";path=" + path : "") +
( (domain) ? ";domain=" + domain : "") +
( (secure) ? ";secure" : "");
}
|
The two cookie functions Get_Cookie() and Set_Cookie()
as described in Chocolate Chip Cookies article.
function setupForm() {
if (userProfile) getValues(userProfile);
}
|
The setupForm() function is invoked by the onLoad=""
event within the <BODY> tag, see further below.
This checks to see if userProfile has been
created (i.e. the store variable, as described in the psuedo code), and if it
has repopulates the form by invoking the getValues() function by
passing the contents of the userProfile.
function getValues(string) {
getValue(string,"user", document.profileForm.user, "text");
getValue(string,"email", document.profileForm.email, "text");
getValue(string,"country",document.profileForm.country,"select");
getValue(string,"age", document.profileForm.age, "select");
getValue(string,"sex", document.profileForm.sex, "radio");
for (var i=0;i<7+1;i++)
getValue(string,"i"+i, eval("document.profileForm.i"+i), "checkbox");
}
|
The getValues() function is the one place
where you may need to adapt the contents to populate your form.
The current contents sets the form profileForm
elements user, email, country, age, sex
and i0 through to i7.
The getValues() function is passed the
parameter string which holds the contents of the userProfile.
This is then used by each call to getValue along with the name of the
form element, a reference to the element (which includes the name of the form
and the name of the form element) and the type of the element, i.e. text,
select, radio, or checkbox
The last two lines of the getValues() function
show a simple means of looping through a list of like named form elements, by
just changing the i suffix each time. It requires the use of the eval()
method to convert a string into the actual reference of the element.
To adapt this function for your own form, requires you
to add a call to the getValue() function for each of your forms
elements, changing the name of the element, the name of the form, and the
element type.
function replace(string,text,by) {
// Replaces text with by in string
var i = string.indexOf(text);
var newstr = '';
if ((!i) || (i == -1)) return string;
newstr += string.substring(0,i) + by;
if (i+text.length < string.length)
newstr += replace(string.substring
(i+text.length,string.length),text,by);
return newstr;
}
|
The replace() function simply replaces any occurrences
of the text string within the string string with the by
string.
function onCheck(string) { if (string == "on")
return true; return false; }
|
The onCheck() function is used by the
following getValue() function to return true if passed "on".
function getValue(string,elementName,object,elementType) {
// gets value of elementName from string and populates
// object of elementType
var startPos = string.indexOf(elementName + "=")
if (startPos > -1) {
startPos = startPos + elementName.length + 1;
var endPos = string.indexOf("&",startPos);
if (endPos == -1) endPos = string.length;
var elementValue = unescape(string.substring(startPos,endPos));
if (elementType == "text") object.value = elementValue;
if (elementType == "password") object.value = elementValue;
if (elementType == "select") object.selectedIndex = elementValue;
if (elementType == "checkbox") object.checked = onCheck(elementValue);
if (elementType == "radio") object[elementValue].checked = true;
}
}
|
The getValue() function is the guts of the
whole code. It attempts to find the elementName, within the passed string
(i.e. the store variable as described in the psuedo code). It does so by
searching for the name of the element plus the "=" character
using the indexOf() method.
If it is not found it simply returns to the invoking getValues()
function.
If it is found then it searches for the "&"
character, which is used to append the form name value pairs together, again
using the indexOf() method.
If the "&" character is not
found then it is assumed to be the last form name value pair within the string.
The elementValue of the element is then
extracted using the substring() and unescape() methods.
Then based on the elementType passed to getValue
it sets the value of the object (i.e. reference to element) as
required.
Where the elementType is a "checkbox"
it uses the onCheck() function to set the value of the checked
property to true, it eh elementValue is "on".
Where the elementType is a "radio"
the assumption is that the name of the radio element is the same as its index
number.
All the JavaScript functions are placed within the HTML
<HEAD> and </HEAD> tags. This ensures they are all
loaded by the browser before they are invoked.
The following line of code, includes the onLoad=""
event which invokes the setupForm() function when the whole page has
been fully loaded.
<BODY onLoad="setupForm()">
<SCRIPT LANGUAGE="JavaScript"><!--
var today = new Date();
var expires = new Date(today.getTime() + (56 * 86400000));
var searchString = replace(self.location.search.substring(1),"+"," ");
if (searchString.length > 0) Set_Cookie
("userProfile",searchString,expires);
var userProfile = Get_Cookie("userProfile");
if (!userProfile) {
document.write('<P>Welcome,<P>According to your records ');
document.write('you have not set your user profile:');
}
else {
document.write('<P>Welcome back,<P>According to your records ');
document.write('the following settings are held in your profile:');
}
//--></SCRIPT>
|
Finally, some inline JavaScript which is invoked as the
page is being laid out. First two dates are created today and expires
which is based on today plus 56 days, or 8 weeks.
The search property of the current location,
i.e. self.location.search is stripped of its initial "?"
using the substring() method, and passed to the replace()
function to replace all "+" characters with a space
character. And is eventually stored in the searchString variable.
If the length of the searchString is greater
than 0 then a cookie called "userProfile" is stored
with the value of the searchString and with the expiry date expires
using the Set_Cookie() function.
Following this an attempt is made to acquire the value
of the "userProfile" using the Get_Cookie()
function.
If the cookie is not retrieved then the value of null
is returned to the userProfile variable.
This is then tested using !userProfile so that
an appropriate message is written to the document.
The remainder of the document is made up of the
required form.
Note, to enable us to easily access the option and
radio arrays, the value of the options and radio buttons are always set to
elements index number.
<FORM NAME="profileForm">
<TABLE width=595 BGCOLOR="#AAAAFF" BORDER=0
CELLSPACING=0 CELLPADDING=5><TR><TD>
<P>Name:
<BR><INPUT TYPE="TEXT" NAME="user" VALUE="" SIZE=40>
<P>Email Address:
<BR><INPUT TYPE="TEXT" NAME="email" VALUE="" SIZE=40>
<P><TABLE WIDTH=100%><TR>
<TD VALIGN=TOP WIDTH=50%>
<P>Country:
<BR><SELECT NAME="country">
<OPTION VALUE="0">Argentina
<OPTION VALUE="1">Australia
<OPTION VALUE="2">Austria
<OPTION VALUE="3">Belgium
<OPTION VALUE="4">Bermuda
<OPTION VALUE="5">Bolivia
<OPTION VALUE="6">Brazil
<OPTION VALUE="7">Brunei Darussalam
<OPTION VALUE="8">Canada
<OPTION VALUE="9">Caribbean
<OPTION VALUE="10">Chile
<OPTION VALUE="11">China
<OPTION VALUE="12">Colombia
<OPTION VALUE="13">Croatia
<OPTION VALUE="14">Czech Republic
<OPTION VALUE="15">Denmark
<OPTION VALUE="16">Estonia
<OPTION VALUE="17">Europe
<OPTION VALUE="18">Finland
<OPTION VALUE="19">Former USSR
<OPTION VALUE="20">France
<OPTION VALUE="21">Germany
<OPTION VALUE="22">Greece
<OPTION VALUE="23">Hong Kong
<OPTION VALUE="24">Hungary
<OPTION VALUE="25">Iceland
<OPTION VALUE="26">India
<OPTION VALUE="27">Indonesia
<OPTION VALUE="28">Ireland
<OPTION VALUE="29">Israel
<OPTION VALUE="30">Italy
<OPTION VALUE="31">Japan
<OPTION VALUE="32">Korea
<OPTION VALUE="33">Latin America
<OPTION VALUE="34">Luxemburg
<OPTION VALUE="35">Macedonia
<OPTION VALUE="36">Malaysia
<OPTION VALUE="37">Mexico
<OPTION VALUE="38">Middle East
<OPTION VALUE="39">Netherlands
<OPTION VALUE="40">New Zealand
<OPTION VALUE="41">North Africa
<OPTION VALUE="42">Norway
<OPTION VALUE="43">Peru
<OPTION VALUE="44">Philippines
<OPTION VALUE="45">Poland
<OPTION VALUE="46">Portugal
<OPTION VALUE="47">Russia
<OPTION VALUE="48">Russian Federation
<OPTION VALUE="49">Singapore
<OPTION VALUE="50">Slovak Republic
<OPTION VALUE="51">Slovakia
<OPTION VALUE="52">Slovenia
<OPTION VALUE="53">Slovenija
<OPTION VALUE="54">South Africa
<OPTION VALUE="55">South Korea
<OPTION VALUE="56">Spain
<OPTION VALUE="57">Sweden
<OPTION VALUE="58">Switzerland
<OPTION VALUE="59">Taiwan
<OPTION VALUE="60">Thailand
<OPTION VALUE="61">Turkey
<OPTION VALUE="62">United Kingdom
<OPTION VALUE="63" SELECTED>United States
<OPTION VALUE="64">Uruguay
<OPTION VALUE="65">Venezuela
<OPTION VALUE="66">Yugoslavia
</SELECT>
</TD><TD VALIGN=TOP WIDTH=25%>
<P>Age:
<BR><SELECT NAME="age">
<OPTION VALUE="0"> < 10
<OPTION VALUE="1"> 10 - 15
<OPTION VALUE="2"> 16 - 19
<OPTION VALUE="3" SELECTED> 20 - 29
<OPTION VALUE="4"> 30 - 39
<OPTION VALUE="5"> 40 - 49
<OPTION VALUE="6"> 50 - 59
<OPTION VALUE="7"> 60 - 69
<OPTION VALUE="8"> 70+
</SELECT>
</TD><TD VALIGN=TOP WIDTH=25%>
<P>Sex:
<BR><INPUT TYPE="RADIO" NAME="sex" VALUE="0" CHECKED> Male
<BR><INPUT TYPE="RADIO" NAME="sex" VALUE="1"> Female
</TD></TR></TABLE>
<HR>
<TABLE WIDTH=100%>
<TR><TD WIDTH=10%><P>Interests:</TD>
<TD ALIGN=RIGHT WIDTH=45%><P>JavaScript:
<INPUT TYPE="CHECKBOX" NAME="i0"></TD>
<TD ALIGN=RIGHT WIDTH=45%><P>Java:
<INPUT TYPE="CHECKBOX" NAME="i1"></TD></TR>
<TR><TD WIDTH=10%> </TD>
<TD ALIGN=RIGHT WIDTH=45%><P>JScript:
<INPUT TYPE="CHECKBOX" NAME="i2"></TD>
<TD ALIGN=RIGHT WIDTH=45%><P>VBScript:
<INPUT TYPE="CHECKBOX" NAME="i3"></TD></TR>
<TR><TD WIDTH=10%> </TD>
<TD ALIGN=RIGHT WIDTH=45%><P>ActiveX:
<INPUT TYPE="CHECKBOX" NAME="i4"></TD>
<TD ALIGN=RIGHT WIDTH=45%><P>HTML:
<INPUT TYPE="CHECKBOX" NAME="i5"></TD></TR>
<TR><TD WIDTH=10%> </TD>
<TD ALIGN=RIGHT WIDTH=45%><P>Dynamic HTML:
<INPUT TYPE="CHECKBOX" NAME="i6"></TD>
<TD ALIGN=RIGHT WIDTH=45%><P>Style Sheets:
<INPUT TYPE="CHECKBOX" NAME="i7"></TD></TR>
</TABLE>
<HR>
<P><TABLE WIDTH=100%><TR><TD ALIGN=RIGHT><P>
<INPUT TYPE="RESET" VALUE="Default Profile">
<INPUT TYPE="SUBMIT" VALUE="Update Profile">
</TD></TR></TABLE>
</TD></TR></TABLE>
</FORM>
<P><SMALL><BR>The information you provide here will NOT
be passed to any third party,
<BR>or used to send unsolicated email,
or stored in a database.</SMALL>
<P><A HREF="index.htm">Return</A>
|
You can try out the above example.
References
Chocolate Chip
Cookies
Accessing
cookies via JavaScript by Bill Dortch
Official
HTTP Cookie Spec or the Netscape
version
cybercoded.com | Articles | Form -> Cookie
-> Form |
back
|