Sei sulla pagina 1di 14

A Quick Tutorial on JavaScript Variable Passing

By Joe Burns
One of the big questions people have is how they can carry information across pages. User A makes a choice on one page
and then goes to another. How can I "remember" what his or her choice was? Well, the best way is to set a cookie. The
cookie is placed right on the user's computer and can be recalled again and again. I have a tutorial on doing just that right
here.
The problem is that many people are scared of cookies. They don't like them and feel they're an invasion of their privacy. OK,
fine. So now how do I get information across pages? Well, you could do it through one page spawning another, then another,
then another. That would allow JavaScript variables to be transferred, but that opens a lot of windows.
To attempt to solve this little dilemma, I offer this down and dirty JavaScript method. Try this:
Type your first name:
Type your last name:

Click and See

How It Works
Let me start by showing you the code that made the small form just above:

<FORM METHOD="LINK" ACTION="jspass2.html">


Type your first name: <INPUT TYPE="text" NAME="FirstName">
Type your last name: <INPUT TYPE="text" NAME="LastName">
<INPUT TYPE="submit" VALUE="Click and See">
</FORM>
Look first at the main FORM tag. The METHOD is set to LINK and the ACTION simply points toward another page. Nowhere
in there does it say to send the user information anywhere. When you set up the form in this manner, what the user inputs is
carried along in the URL.
The information is separated from the actual address by a question mark so it doesn't harm the movement to another page.
This little quirk of the browser allows us to go to a totally new page and carry the user's input right along with us in the URL.
Pretty clever, no? Now all we have to do is find a method of extracting that information from the URL.

Limitations
Now might be a darn good time to discuss limitations to this process.
To begin with, the information is not saved after each surfing like it is with a cookie. In order for this to work, you must ensure
the user moves in a linear fashion. Returning and backing up can harm the information being carried.
Next, the way I have this set up, you can only transfer two variables from page to page. You'll see why in a moment.
Also, the method I have written here isn't very friendly to spaces. If the user puts a space in either of their two text boxes, that
space will be replaced by a plus sign. If you're going to accept spaces, you'll either have to live with that or write some extra
code to eliminate it.
In addition, this is done with JavaScript so there are browsers that will not be able to play with it. This code was written in
JavaScript 1.0, which was the standard when this article was written (2005), but it still works! As of June, 2008, the latest
version of JavaScript is version 1.9. I saw a suggestion on doing this by setting the answers to an array. The array method
allows for endless variables being passed, but older browsers would not be able to use it properly. My version allows for the
most number of browsers to be able to play with the code but only uses two variables. You decide.

Get The First Name


OK, since you've obviously chosen my method (or else you probably wouldn't be reading this far), let's look at the code that
grabs the first name. This code will be found on the page that the form above IS GOING TO.

<FORM NAME="joe">
<INPUT TYPE="hidden" NAME="burns">
</FORM>
<SCRIPT LANGUAGE="javascript">
var locate = window.location
document.joe.burns.value = locate
var text = document.joe.burns.value
function delineate(str)
{
theleft = str.indexOf("=") + 1;
theright = str.lastIndexOf("&");
return(str.substring(theleft, theright));
}
document.write("First Name is " +delineate(text));
</SCRIPT>
I'm going to tell you what the hardest part of this process is. It kept me at bay for a good hour. I knew the easiest method to
doing this was to use substring JavaScript commands and grab elements from the URL. I also knew I could grab the URL of
a page simply by using the command window.location. Here, this is the URL of this page using the command:
http://www.htmlgoodies.com/beyond/javascript/article.php/3471111/A-Quick-Tutorial-on-JavaScript-Variable-Passing.htm
No sweat right? There's the text string. Just grab what you want. The problem is...that display is not a text string. It's a
property and that means it cannot be acted upon like a text string. Oh that drove me nuts. Once I figured out how to get it
from a property to a text string I was fine. Let's look at that part first.
OK, JavaScript friends, I know there are other ways of doing this, this is just how I like to do it. The code starts with this:

<FORM NAME="joe">
<INPUT TYPE="hidden" NAME="burns">
</FORM>
You may remember that little blip of code for any number of forms you put together. It's basically a text box, but it's hidden.
See how the type is "hidden"? That's a great little trick to give yourself a place to store a value where no one can see it.
I figured if I take the property of the page's location and put it in a text box, the property then becomes the value of that text
box. When you grab the value from a text box it becomes...you guessed it...a text string. Let's look at the Script:

var locate = window.location


document.joe.burns.value = locate
var text = document.joe.burns.value

That is the beginning blip of code that changes the location into a text string. The property "window.location" is given to a
variable named "locate". Then the value of locate is put into the text box represented by document.joe.burns.value. See that
above? The NAME of the form itself is "joe", the NAME or the hidden text box is "burns". By adding "value" to the end of the
hierarchy statement, I basically forced a value into the box.
The next line grabs that value right back out of the hidden text box and assigns the variable name "text" to it. The location of
the page is now a text string and ready to be broken into parts.
Let's say it looks like this:

http://www.server.com/jspass2.html?FirstName=Super&LastName=Man
In order to grab things out of this line of code, we need to look for key elements looking from left to right and later, right to
left. In the example above, we want the text "Super" yanked out of this line of letters.
The keys would most likely be the equals sign (=) it's the first one counting from the left. The ending key would be the
ampersand (&). Again, it's the first one looking from the left. That bookends the text, so let's set up a JavaScript that knocks
everything off including that equals sign, and keeps the next letters until an ampersand shows up. It's not too hard.

function delineate(str)
{
theleft = str.indexOf("=") + 1;
theright = str.lastIndexOf("&");
return(str.substring(theleft, theright));
}
document.write("First Name is " +delineate(text));
First a function, named delineate(), is set up that will look for certain things.
The variable "theleft" is given the value of the first instance of an equals sign reading from the left. That's what indexOf()
does. Notice we add one because we don't want the equals sign. Adding one skips it. Notice that each line is acting upon
something called "str". At the moment "str" has no value. We'll pass it a value in the last line.
Next, the variable "theright" is given the value of looking for the first instance of & reading from the right. That's what
lastIndexOf() does.
So now we have our bookends set. Let's grab the text. The next line returns the substring of what appears between the
equals sign (theleft) and the & (theright). See that?
Finally, the value is grabbed using a document.write command. Remember that at this point, nothing has actually been done.
The document.write statement actually triggers the function to run. But look! When the function is triggered to run, now it is
being passed a new variable, "text". That's the text string of the location to be acted upon.
The return is the text Super.

Grab The Last Name


Grabbing the last name is a whole lot easier. If you look at the text string again, you'll see we only need to set one point to
look for. There's nothing following the last name so if we read from the right and basically chop off everything including the
second equal sign (from the right it's the first), then we'll be left with the last name. Here's the code that did it.

var locate = window.location


document.joe.burns.value = locate
var text = document.joe.burns.value
function delineate2(str)
{
point = str.lastIndexOf("=");

return(str.substring(point+1,str.length));
}
document.write("Last Name is " +delineate2(text));
The code is very much the same in that it grabs the window.location and turns it into text. Where it differs is that the text
string is only searching, from the right, for one item, the second equal sign.
The variable "point" is given the job of representing everything up to the second equal sign (first from the right - note I used
lastIndexOf()).
The return is that point plus one, again to not include the equal sign, and then the length of the string - that's everything that
follows and that's the last name.
A document.write statement again triggers the function and passes the variable "text" to it.

Placing the Value


At this point in time you can place the value anywhere you want by using the document.write where ever you want. I have
some text thrown in but that's easily taken out. Remember to remove the plus sign if you take the text out. Getting the name
into a text box is actually pretty easy. Here's the code I used on the example page.

<FORM NAME="bull">
Last Name: <INPUT TYPE="text" NAME="bear">
</FORM>
<SCRIPT LANGUAGE="javascript">
var zork = delineate2(text)
document.bull.bear.value = zork
</SCRIPT>
You might notice a big chunk of it from the other scripts. I created a box first. The box has to be first or the hierarchy
statement won't run. Error. The box is visible this time around. The value of the function is assigned to the variable "zork"
and then zork is put into the text box. Pretty straightforward.
Just remember to change out the NAMEs of each element if you put more than one text box on a page. You also have to
come up with a different variable name for the second text box. In other words you can't have two zorks on the same page.

That's That
And speaking of two zorks on the same page, remember the limitations of this. You can carry the same info across many
pages, but they all must be in order. If you take these variables to yet a third page, all this coding must be redone on the new
page. The variable does not carry across pages. The text in the URL carries. Once it gets to the new page, it has to be
assigned a new variable...each time.

<!DOCTYPE html>
<html>
<body>

<p>Click the button to call a function with arguments</p>

<button onclick="myFunction('Wazzzzup','Wizard')">Try it</button>

<script>
function myFunction(name,job)
{
alert("Welcome " + name + ", the " + job);
}
</script>

</body>
</html>

Output

Click the button to call a function with arguments


[Try it] //button

<html>
<head>
</head>
<body>
<div align="center">
<form name="nameTemp">
First Name: <input name="firstName" type="text"><br>
Last Name: <input name="lastName" type="text">
</form>
<form name="mainForm" onsubmit="return singleName(this)">
age: <input name="age" type="text" value="35"><br>
gender: <input name="gender" type="text" value="male"><br>
sex: <input name="sex" type="text" value="yes"><br>
<input name="firstLast" type="hidden">

<input type="submit">
</form>
</div>
<script type="text/javascript">
function singleName(form)
{
if (document.nameTemp.firstName.value == '')
{
alert('Please enter your first name.');
document.nameTemp.firstName.focus();
return false;
}
if (document.nameTemp.lastName.value == '')
{
alert('Please enter your last name.');
document.nameTemp.lastName.focus();
return false;
} else {
form.firstLast.value = document.nameTemp.firstName.value +
document.nameTemp.lastName.value;
}
return true;
}
</script>
</body>
</html>

2007-02-09: Your JavaScript page has retrieved some information from the user.

Now you want to display another JavaScript page, which should also use that
information. How do you pass it from the first page to the second? There are
three simple solutions. The first two are safe and effective, with advantages
and disadvantages to each. The third appears ideal but has a very serious
security problem and should be avoided.

1. Submitting form data to a server-side script that then outputs a new


JavaScript page containing the data. This is simple and reliable and works in
all browsers, but requires support for server-side scripting of some kind (PHP,
ASP, etc).

2. Passing form-style data in a URL to a new JavaScript page, without using


any server-side scripts. This works in all browsers but supports a limited
amount of data. It is the traditional way of solving the problem without serverside scripting.
3. Passing data via the window.name property. Although this is not the intended
purpose ofwindow.name, it seems to work quite well and supports larger
amounts of data than the second method. And it works in Safari, Firefox, and
Internet Explorer. So why not use it? Because it is highly insecure! If the user
follows a link to another website that doesn't belong to you, that other website
can still see the data stored in window.name, which was never meant to be a
secure, site-specific property. So I strongly discourage the use of this method.
When possible, it's best to use the first method, because the amount of data
you can pass is essentially unlimited. I'll demonstrate the first two methods
and give an overview of the third, but as I said, the third is unsafe and you
should not use it.
1. Using a Server-Side Script
When server-side scripting is available, this is the best approach. Let's
assume you have a JavaScript array of strings you'd like to pass to a new web
page:
<script>
var data = new Array();
data[0] = "one, a datum";
data[1] = "two, a deer";
data[2] = "three, a slash: \\";
data[3] = "four has quotes: \"I forget what four was for\"";
</script>

To pass this array to a script on a new page without packing it into a long URL
(remember, URLs are limited to a practical maximum of 2,083 characters in
the most popular web browser, and long URLs don't look very pretty either),
we can use a hidden form in the first page, and submit this form to a PHP
script on the server using the POST method. The GET and POST methods

differ in that a GET-method form submission packs everything in the URL,


which is nice for bookmarkable searches but a poor choice for large amounts
of data. The POST method submits the data outside of the URL, without a
length limit.
You could call the sendData function from any JavaScript code. Calling it
when a link is clicked is simply one example.
We'll use a hidden field in the hidden form to pass the information. A hidden
form field is a single string, so we'll pack the array into it by using a comma to
separate elements of the array. And since the data might also contain
commas, we'll use JavaScript's escape() function to encode these, so that they
can't be confused with our separators. We'll name both the form and the
hidden field within it data. When we do this, we access set the contents of the
hidden field using the JavaScript syntax document.data.data.value (read from
right to left: the value of the field named data, in the form named data, in the
document).
Want to test this technique on your own computer? You'll need a web server
with PHP support on your computer. PHP can't be tested on your local hard
drive, because PHP is a server side solution. See How do I test PHP, ASP,
server side include and CGI pages offline or at home?
The two listings that follow
are passdata1a.html and passdata1b.php.passdata1a.html passes an array of
JavaScript data topassdata1b.php when a link is clicked.
passdata1a.html
<script>
var data = new Array();
data[0] = "one, a datum";
data[1] = "two, a deer";
data[2] = "three, a slash: \\";
data[3] = "four has quotes: \"I forget what four was for\"";
</script>
<form name="data" method="POST" action="passdata1b.php">
<input type="hidden" name="data">

</form>
<script>
function sendData()
{
// Initialize packed or we get the word 'undefined'
var packed = "";
for (i = 0; (i < data.length); i++) {
if (i > 0) {
packed += ",";
}
packed += escape(data[i]);
}
document.data.data.value = packed;
document.data.submit();
}
</script>
<h1>This is what the array contains:</h1>
<ul>
<script>
for (i = 0; (i < data.length); i++) {
document.write("<li>" + data[i] + "</li>\n");
}
</script>
</ul>
<a href="javascript:sendData();">Go to passdata1b.php</a>
passdata1b.php
<?php
$packed = $_POST['data'];
$data = split(",", $packed);
for ($i = 0; ($i < count($data)); $i++) {
# Undo what JavaScript's escape() function did
$data[$i] = rawurldecode($data[$i]);
# Slashes need escaping when they appear in code
$data[$i] = str_replace("\\", "\\\\", $data[$i]);
# Quotes need escaping too
$data[$i] = str_replace("\"", "\\\"", $data[$i]);
}
?>
<script>
var data = new Array (
<?php
for ($i = 0; ($i < count($data)); $i++) {
if ($i > 0) {
echo ",\n";
}
echo "
\"";
echo $data[$i];
echo "\"";
}
?>
);
</script>
<h1>This is what the data contains:</h1>

<ul>
<script>
for (i = 0; (i < data.length); i++) {
document.write("<li>" + data[i] + "</li>\n");
}
</script>
</ul>

2. Using JavaScript Only: Data in the URL


When server-side scripting is not available, it is still possible to pass data
between web pages, either via the "query string" (the portion of the URL after
the ?) or the window.name property. First we'll look at how to do it via the query
string.
The main problem with the query string approach is that the amount of data
you can pass is limited.The maximum total safe length of a URL is 2,083
characters, and "escaping" of data like whitespace and punctuation will
consume quite a bit of this space. So this technique should be used only for
small amounts of information. For larger amounts, use the PHP technique
demonstrated above a similar technique based on ASP or Perl, or
the window.name technique at the end of this article. Just keep in mind that
server-side scripting is always preferable for passing large amounts of data.
Implementing the Query String Solution
When web servers see a URL that specifies an ordinary HTML web page,
followed by a ? character, followed by additional data, like this:
http://www.example.com/page.html?this%20is%20some%20data

They deliver the file /page.html to the browser and ignore the ? and the data
beyond it. However, this data is available to JavaScript code in page.html, in
the variable window.location.search.
Even though this technique uses only JavaScript, you cannot test this using
two HTML pages on your own hard drive in Internet Explorer unless you
have a web server on your own computer -- a simple and useful thing to have,

and I recommend setting one up for testing purposes. Test this technique with
your pages on a web server, not just your hard drive. Or test it in Firefox,
which allows URLs with a ? to work correctly for JavaScript pages on the local
hard drive.
Again, let's assume you have a JavaScript array of strings you'd like to pass to
a new web page:
<script>
var data = new Array();
data[0] = "one, a datum";
data[1] = "two, a deer";
data[2] = "three, a slash: \\";
data[3] = "four has quotes: \"I forget what four was for\"";
</script>

We can pass this data to a second page by packing the array into a single
string, "escaping" each of the array elements with
JavaScript's escape() function and then separating them with commas. We
then send the browser to a new page by
setting window.location to passdata2b.html (the name of the new page), followed
by a ? character, followed by our packed string. In the second page, we'll find
the data in window.location.search and break it back into separate array
elements with the split()function, and then use unescape() to restore each of
these elements to their normal appearance.
The two listings that follow
are passdata2a.html and passdata2b.html. passdata2a.html passes an array of
JavaScript data to passdata2b.html when a link is clicked.
passdata2a.html
<script>
var data = new Array();
data[0] = "one, a datum";
data[1] = "two, a deer";
data[2] = "three, a slash: \\";
data[3] = "four has quotes: \"I forget what four was for\"";
</script>
<script>
function sendData()
{
// Initialize packed or we get the word 'undefined'

var packed = "";


for (i = 0; (i < data.length); i++) {
if (i > 0) {
packed += ",";
}
packed += escape(data[i]);
}
window.location = "passdata2b.html?" + packed;
}
</script>
<h1>This is what the array contains:</h1>
<ul>
<script>
for (i = 0; (i < data.length); i++) {
document.write("<li>" + data[i] + "</li>\n");
}
</script>
</ul>
<a href="javascript:sendData();">Go to Page Two</a>
passdata2b.html
<script>
var query = window.location.search;
// Skip the leading ?, which should always be there,
// but be careful anyway
if (query.substring(0, 1) == '?') {
query = query.substring(1);
}
var data = query.split(',');
for (i = 0; (i < data.length); i++) {
data[i] = unescape(data[i]);
}
</script>
<h1>This is what the array contains:</h1>
<ul>
<script>
for (i = 0; (i < data.length); i++) {
document.write("<li>" + data[i] + "</li>\n");
}
</script>
</ul>

3. Using JavaScript Only: window.name


The query string solution is the traditional way to pass data without server side
scripting, but it supports a limited amount of data. Recently another alternative
has gained popularity: thewindow.name property.
The original purpose of window.name is not to pass data between pages. The
idea is that a browser window (or tab) can be given a name that can then be

used to refer to that window later. For instance, the window.open function can be
used to open a new page in an existing popup window by specifying its name.
However, clever programmers have noticed that the window.name property can
be changed by JavaScript code and has no apparent fixed length limit. So why
not use it to pass data between pages?
There are three downsides to this approach. The first two have simple
workarounds, but the third is afatal security flaw:
A. Internet Explorer rejects special characters in window.name. So you can't trust
line breaks (carriage returns) or binary data to stick around in window.name. We
handle this issue the same way we handle it for the query string: by "escaping"
our data.
B. If you are using window.name to pass data around, then you no longer have
the option of using it to refer to the window in window.open calls and so on. You
could work around this by removing the data from window.name after you parse
it, but then the data is no longer available if the user reloads the page.
Depending on your needs, this may or may not be a serious issue for your
purposes.
C. Once the data is in window.name, it stays there even if the user follows a link
to a completely different website. This is extremely dangerous - especially if
there is personal information included in the data! Please do not use this
method.
A few developers may feel that window.name is safe for use in their application
because there will never be any personal information passed. This is almost
always a mistake - you don't know how users will choose to use your web
application, and what they will hold you responsible for if things go badly
wrong.
If you do choose to use window.name to pass data, note that
the window.name property is not available to JavaScript code that executes while

the page is still loading. You will need to access it from a function called by
the onLoad handler of the body element.