Click to See Complete Forum and Search --> : passing -values


rbeckmon
06-14-2003, 12:04 PM
Can anyone help me?

I'm having a problem with the passing-values script I downloaded from this site. It works fine on this site but when I try to use it, I just get undifined on the next page. It should work offline, should'nt it? Below is the script.


<!-- THREE STEPS TO INSTALL PASSING VALUES:

1. Copy the form code into the first page with the form
2. Paste the HEAD code into the second HTML page
3. Add the final code into the BODY of your second page -->

<!-- STEP ONE: Paste this code into the HEAD of your HTML document -->

<BODY>

<center>
<form type=get action="passing-values-source.html">
<table border=1>
<tr>
<td>First Name:</td>
<td><input type=text name=firstname size=10></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input type=text name=lastname size=10></td>
</tr>
<tr>
<td>Age:</td>
<td><input type=text name=age size=3></td>
</tr>
<tr>
<td colspan=2><input type=submit value="Submit!">
</td>
</tr>
</table>
</form>
</center>

<!-- STEP TWO: Paste this code into the HEAD of your second document -->

<HEAD>

<SCRIPT LANGUAGE="JavaScript">

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Begin
function getParams() {
var idx = document.URL.indexOf('?');
var params = new Array();
if (idx != -1) {
var pairs = document.URL.substring(idx+1, document.URL.length).split('&');
for (var i=0; i<pairs.length; i++) {
nameVal = pairs[i].split('=');
params[nameVal[0]] = nameVal[1];
}
}
return params;
}
params = getParams();
// End -->
</script>
</HEAD>

<!-- STEP THREE: Put this on the page that should read the values -->

<BODY>

<SCRIPT LANGUAGE="JavaScript">

<!-- Begin
firstname = unescape(params["firstname"]);
lastname = unescape(params["lastname"]);
age = unescape(params["age"]);

document.write("firstname = " + firstname + "<br>");
document.write("lastname = " + lastname + "<br>");
document.write("age = " + age + "<br>");
// End -->
</script>

<p><center>
<font face="arial, helvetica" size="-2">Free JavaScripts provided<br>
by <a href="http://javascriptsource.com">The JavaScript Source</a></font>
</center><p>

<!-- Script Size: 1.23 KB -->

rbeckmon
06-14-2003, 12:21 PM
Thanks Dave. I'll see if that woks better. Back at ya later.

rbeckmon
06-14-2003, 12:52 PM
I think you may be right, but I still have a problem. I'm getting a blank return. You think that might be do to the fact that I don't have the SearchString.js file? Hmmmm?

jeffmott
06-14-2003, 01:53 PM
rbeckmon, the script from javascript source should return undefined only you have not yet submitted the form. no values were sent, hence the values were never defined.

dave's script is a better choice, but it does have a couple problems itself. the semi-colon is a valid delimiter between name/value pairs (just as ampersand), but is not supported. multiple values are also thrown away (which are a very common thing to have, particularly with checkboxes).

another alternative is attached.

jeffmott
06-14-2003, 04:12 PM
I have never heard of semicolons being valid delimiters in the query/search stringIndeed. There is much more focus on form processing in Perl/CGI than in JavaScript, so it isn't something you might normally come across.I can guarantee that the browser will not generate them for the FORM METHOD=GET submission. Do you have some link that says the semicolon is valid in the standards?the browser? You should say which browser you're referring to, unless you can give this assurance for all versions of all browsers.

But I don't know of any browsers that use a semi-colon from form submission either. ;)

It is for when writing a query string as part of a link in an HTML document.
HTML 4.01 Specification: http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2.2for radio buttons (but, only the checked radio button is submitted by the browserThat's why I said checkbox, not radio button. Same situation also arises with select menus with the multiple attribute set.

jeffmott
06-14-2003, 06:02 PM
I was of the understanding that a comma-delimited list is submitted for the SELECT element with the multiple attributeA simple test (I tested in IE6, NS7, and Opera7) show that all will submit a select[multiple] as separate values.Perhaps this is a misunderstanding because that is what ASP converts it to in the Request object.I'm a little curious just what ASP does when a comma appears in one of the values. It either has to be encoded (requiring you to decode it) or it is left alone (leaving the programer with no way of knowing the difference between a plain "," character and what is supposed to be a delimiter). This method for returning multiple values also appears in Perl/CGI on occasion, but given the problems with it, it is not considered a good solution.

jeffmott
06-14-2003, 06:27 PM
Note, the above may *look* like array processing, but it definitely is not.Are you speaking here about what is returned, or how it is stored internally?If you reference one of multiple form parameters without specifying a value for index, the data is returned as a comma-delimited string.Yes, this makes me believe that this is only the return value of this particular call method and is not representative of how it is stored internally. However, for the reasons I already mentioned, the comma delimited list is error prone and not very practical. Which means to retrieve the set of values (reliably), you'd have to manually loop from 1 to Request.Form("multiple-select-name").Count and populate your own array. This is something the JavaScript version I posted does for the programmer. params('multiple-select-name') returns an array of the values.

EDIT: Unless you can find more documentation on the Request object (or if the code behind it is open source) you might want to try a test with multiple values that include a comma in the value to see just how it is processed. I would test for myself, but I don't have access to an ASP server.

jeffmott
06-14-2003, 07:34 PM
I don't mean to be a pest here but...SearchString.js
if (inpt.indexOf(";")>(-1)) delim = ";";
else delim = "&";Both & and ; may appear as delimiters in the same query string. Searching for just one or the other doesn't quite do it. Granted it is rare that this would happen, but I think everyone would agree that software should be written to handle all cases, not just the usual ones. In your original code, supporting the semi-colon in addition to the ampersand would have been as simple as changing split("&") to split(/[&;]/).SearchString.js
if (this[name]) {
if (typeof(this[name]) != "object") {
this[name] = new Array(this[name]);
}
this[name][this[name].length] = unescape(ary[x][1]);
} else {
this[name] = unescape(ary[x][1]);
}There is nothing actually wrong with this, just a problem I forsee users of the script encountering. It is now unkown to the user if they will be returned a string or an array (one of the pitfalls of a typeless language, a strictly typed language wouldn't let you do this). So the only way for the user to avoid treating a string as an array or vice versa is to check the type for every value wherever it is used. You can probably see how that would become a great hassle.

jeffmott
06-15-2003, 12:22 AM
I doubt PHP or ASP will support having both ampersands and semicolons used as delimiters in the same querystring (though I haven't checked to see).Why do you doubt it? I cannot speak for PHP or ASP either, but the CGI module that is part of the standard distribution of Perl does. The specification says only "support the use of ';' in place of '&'". Never does it say each much be used exclusively. To say they cannot each appear as delimiters in a query string is an assumption.Obviously, no browser is going to create them that way and there is no sane reason for a coder to do so eitherTrue. But if we are designing for all cases and not just the commonly seen then we must consider the insane coder. :p And the code to support both is shorter and cleaner.

So...
* support both characters as delimiters interchangably -> supports *all* cases; shorter and cleaner code
* support both characters as delimiters exclusively -> supports *most* cases; more conditionals and statements, more variables to track

no brainer?you'd be throwing a monkey-wrench into the works if either the semi-colon or the ampersand is used as data and the other was intended as the delimiterIf the program/coder correctly URL encoded the data then there is no problem. Both "&" and ";" characters should be escaped ( %HH ) if they appear in the actual data.In my opinion, that is pure overkillIn my opinion (with nothing to the contrary) it is the correct way to do it.As for the dynamic switch from a primitive value to an array... Hey, we're not talking about data that is unknown to the original coder of the page. Such a coder is going to know if there is the possibility for duplicate names in their querystrings. It is ridiculous to speculate that such a coder would be "forced" to test every name to determine which type of value they need to handle.You can't just take my word for it that it's a problem? Or at the very least test it yourself? Well, fine. I guess I'll have to spoon feed it to you then. Test the following page.<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html lang="en-us">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<script type="text/javascript">
function SearchStringExtract(locObj) {
var x, ary, delim, name, inpt = locObj.search.substr(1);
if (inpt.length > 0) {
if (arguments.length>1) delim = arguments[1];
else {
if (inpt.indexOf(";")>(-1)) delim = ";";
else delim = "&";
}
ary = inpt.replace(/\+/g, " ").split(delim);
for (x in ary) {
ary[x] = ary[x].split("=");
name = unescape(ary[x][0]);
if (this[name]) {
if (typeof(this[name]) != "object") {
this[name] = new Array(this[name]);
}
this[name][this[name].length] = unescape(ary[x][1]);
} else {
this[name] = unescape(ary[x][1]);
}
}
}
}
</script>
</head>

<body>

<form action="page.html" method="get">
<input type="checkbox" name="n" value="Hello">
<input type="checkbox" name="n" value="World">
<input type="checkbox" name="n" value="Foo">
<input type="checkbox" name="n" value="Bar"><br>
<input type="submit">
</form>

<script type="text/javascript">

var QueryString = new SearchStringExtract(top.location);

/*
n potentially has multiple values, so assume we're getting
an array, loop through it, and alert() each value
*/

var n = QueryString["n"];
for (var i = 0; i < n.length; ++i)
alert(n[i]);

</script>

</body>

</html>Try submitting the form with only one checkbox checked. Would you consider this the expected behaviour? I certainly don't.Do you like to make everything you do more complex than it needs to be?I like making things work the way they're supposed to.

rbeckmon
06-15-2003, 10:26 AM
Boy! I didn't mean to get such a long discussion going. I do realy appreciate it though. I'm new at this so am learning a lot. I don't think the code I'm trying is the one I need though. I may need to use perl. What I want is for the information to stay posted to the second page so when you close it and then reopen it, it will still be there.

jeffmott
06-15-2003, 12:16 PM
Doing it your way, how are you going to allow for the possibility that *nothing* is "properly" encoded?Doing it your way, how are you going to either? This is the one thing that decode functions are generally allowed to assume, that they are being given data that is properly encoded. If we were writing a Base64 decode function, we can assume that the data we were given is properly Base64 encoded. And if we are writting a query string decode function then we can assume that the data we are being given is indeed a properly encoded query string.Neither the ampersand nor the semicolon *have* to be encoded -- as the specification clearly states that these are to be allowed (unencoded) as part of the URLSorry, I don't see where the specification "clearly states" they may appear unencoded _as a part of the data to be sent_. Why don't you provide a link?but most coders don't even know that at least the "value", of a name/value pair, *should* be encodedI assume everything you did when you were learning worked the very first time? A coder that doesn't URL encode their query string may not get the expected results (just like anything else in software when you give it malformed input). They'll ask a couple questions on a couple forums, realize their error, and fix it. The fault here does not lie with the parser for being given bad input.

But if you feel your script should try to work with completely unencoded data, be my guest. What if there's more then one "?"? What if there's more than one "=" in between each delimiter? If the data appears unencoded should %HH and "+" still be decoded? Since you seem so passioniate about making your script work for all these situations, I'm sure you'll start working at it right away. :rolleyes:

**And a little curious why you say my script is poor for not doing things that yours does not do either (and is not expected for any script to do). You're not trying to be manipulative again, are you?The coder just *has* to take some responsibility of their ownAgreed. But if you did run the example I gave you, then you'd see that they in fact would have to test if they got a string or an array back before they do anything with it. This is far more responsibility (and work) than is necessary. Unless, of course, if you havn't even looked at the example yet and you're just ignoring the problem.

jeffmott
06-15-2003, 01:09 PM
jeffmott
But if you did run the example I gave you, then you'd see that they in fact would have to test if they got a string or an array back before they do anything with it. This is far more responsibility (and work) than is necessary. Unless, of course, if you havn't even looked at the example yet and you're just ignoring the problem.So I guess you've chosen to ignore the problem then? This was one of the points trying to be made before it spun out in so many different directions.

rbeckmon
06-15-2003, 02:30 PM
You don't happen to have a simple perl script for this, do you? Or do I need to go to the cgi forum?

Thanks Dave.

jeffmott
06-15-2003, 02:40 PM
You don't happen to have a simple perl script for this, do you? Or do I need to go to the cgi forum?The CGI forum is where this question would belong, but I'll answer it here anyway. Perl comes with a standard library file called CGI.pm that you can use for your parameter parsing. It supports both OO and functional styles for calling its subroutines.use CGI;
my $cgi = CGI->new();
my $var = $cgi->param('variable-name');See http://www.perldoc.com/perl5.8.0/lib/CGI.html for more details.