8.14 Copying Form Data Between Pages
NN 4, IE 4
8.14.1 Problem
You want to convey all form
control settings from one page to another.
8.14.2 Solution
Use the stringForms.js library shown in the Discussion to
convert all values in a form to a string that can be passed to
another page via URLs or cookies. Invoke the
form2ArrayString( ) function, passing as an
argument a reference to the form in need of conversion. The function
returns a string whose format is of a shortcut constructor of an
array of objects. Each object represents a form control in the
following format:
{name:'elemName',id:'elemID',type:'elemType',value:value}
To distribute the values to a form with the same control structure,
invoke string2FormObj( ), passing parameters for a
reference to the destination form and to the string originally
created by the form2ArrayString( ) function.
8.14.3 Discussion
Example 8-3 shows the code for the
stringForms.js library (applied in Recipe 10.6).
The library provides two main functions that your scripts invoke:
form2ArrayString( ), which converts a
form's content to a string formatted like a
JavaScript array of objects, and string2FormObj(
), which copies values from the array to form controls in
another page that have the same names or IDs.
Example 8-3. The stringForms.js library
// Read the name, id, type, and value of one form control element
// as requested by form2ArrayString( )
function formObj2String(obj) {
var output = "{";
if (obj.name) {
output += "name:'" + obj.name + "',";
}
if (obj.id) {
output += "id:'" + obj.id + "',";
}
output += "type:'" + obj.type + "',";
switch (obj.type) {
case "radio":
if (obj.name) {
obj = document.forms[0].elements[obj.name];
var radioVal = "value:false,index:-1";
for (var i = 0; i < obj.length; i++) {
if (obj[i].checked) {
radioVal = "value:true,index:" + i;
i = obj.length;
}
}
output += radioVal;
} else {
output += "value:" + obj.checked;
}
break;
case "checkbox":
output += "value:" + obj.checked;
break;
case "select-one":
output += "value:" + obj.selectedIndex;
break;
case "select-multiple":
output += "value:" + obj.selectedIndex;
break;
case "text":
output += "value:'" + escape(obj.value) + "'";
break;
case "textarea":
output += "value:'" + escape(obj.value) + "'";
break;
case "password":
output += "value:'" + escape(obj.value) + "'";
break;
case "hidden":
output += "value:'" + escape(obj.value) + "'";
break;
default:
output += "";
}
output += "}"
return output;
}
// Convert a passed form reference to a string formatted like
// a JavaScript array of objects
function form2ArrayString(form) {
var elem, lastName = "";
var output = "[";
for (var i = 0; i < form.elements.length; i++) {
elem = form.elements[i];
if (elem.name && (elem.name != lastName)) {
output += formObj2String(form.elements[i]) + ",";
lastName = elem.name;
}
}
output = output.substring(0, output.length-1) + "]";
return output;
}
// Distribute form control values from another source to the
// controls in this page's form, whose names/ids match those
// of the original form controls
function string2FormObj(form, str) {
var elem, objArray = eval(str);
for (var i = 0; i < objArray.length; i++) {
elem = (objArray[i].name) ? form.elements[objArray[i].name] :
document.getElementById(objArray[i].id);
switch (objArray[i].type) {
case "radio":
if (objArray[i].name && objArray[i].value && objArray[i].index >= 0) {
elem = elem[objArray[i].index];
}
elem.checked = objArray[i].value;
break;
case "checkbox":
elem.checked = objArray[i].value;
break;
case "select-one":
elem.selectedIndex = objArray[i].value;
break;
case "select-multiple":
elem.selectedIndex = objArray[i].value;
break;
default:
elem.value = unescape(objArray[i].value);
}
}
}
The form2ArrayString( ) function manages the
conversion process by iterating through all elements of a form. For
each element, it invokes the support function,
formObj2String( ), which does the hard work of
this library. The purpose of the formObj2String( )
function is to convert basic specifications about a passed form
control element to a string formatted as a shortcut object creation
sequence. Each of these objects contains four properties:
name, id,
type, and value. Each control
type that accepts user input and can be read without security
violations is accounted for.
Your scripts invoke the form2ArrayString(
) function to obtain the string
specification of the form's controls. Pass a
reference to the form on the source page whose values you want to
preserve. The function returns a string that looks like shortcut
array notation. Each array entry is a string representation of an
object whose properties define a single form control. This string may
be passed as a search string in a URL or saved as a cookie for
reading by another page from the same server and domain.
When it's time to reapply the values to a form on
another page, use the string2FormObj( ) function
of this library. Pass to this function a reference to the form on the
current page and the string containing the array syntax. Although
normally avoided for performance reasons, you need the eval(
) function here to convert the array string into an actual
array object. Form controls with the same name (or, lacking a name,
the ID) of the original form are populated with the same values
reported previously. Other form controls with unique names are not
disturbed.
While the stringForms.js library takes into
account the peculiar ways that radio buttons share the same name, it
does not preserve multiple selection values of a
select-multiple type of select
element. Instead, the function relies exclusively on the
selectedIndex property of the element. You could
modify the library to accommodate multiple selections by preserving
the value as an array (in string format, of course) of options whose
selected property is true.
The importance of preserving form specifications in string format
becomes evident when you need to convey the data across pages. As
described in Recipe
10.4 and Recipe 10.6, two of the three ways to pass
data from one page to the next (URLs and cookies) require that the
data be in string format. The JavaScript shortcut syntax for creating
arrays and objects comes in very handy here, because the strings are
very compact (compared to other kinds of formats) making it less
likely that you'll overrun the 512-character limit
of URLs, or the practical 1 KB limit of a single cookie value.
8.14.4 See Also
Recipe 3.1 and
Recipe 3.8 for more about shortcut array and object creation
syntax; Recipe 3.13 for a similar type of object-to-string conversion
for custom objects; Recipe 10.4 for passing string data between pages
via cookies; Recipe 10.6 for data passing via URL search
strings.
|