View Full Version : Parse search string into get variables
beetle
08-21-2002, 07:10 PM
I feel like I have been repeating this code lately, so I cleaned it up and am gonna show it here. This function returns an array (with hash names) containing all the get variables.function parseGetVars() {
var getVars = new Array();
var qString = unescape(top.location.search.substring(1));
var pairs = qString.split(/\&/);
for (var i in pairs) {
var nameVal = pairs[i].split(/\=/);
getVars[nameVal[0]] = nameVal[1];
}
return getVars;
}A simple page to test this looks like<html>
<head>
<title>Test</title>
<script>
function parseGetVars() {
var getVars = new Array();
var qString = unescape(top.location.search.substring(1));
var pairs = qString.split(/\&/);
for (var i in pairs) {
var nameVal = pairs[i].split(/\=/);
getVars[nameVal[0]] = nameVal[1];
}
return getVars;
}
</script>
</head>
<body>
<script>
var g = parseGetVars();
for (var i in g)
document.writeln(i+'='+g[i]+'<br>');
</script>
</body>
</html>Hope this helps anyone...optimizations/comments are welcome!
mordred
08-23-2002, 03:16 PM
Great minds think alike:
http://www.codingforums.com/showthread.php?s=&threadid=2217
:D
beetle
08-23-2002, 03:33 PM
Heh, so they do indeed :D
Did you know when you create variables they become part of the window object? I used this fact to make your (very usefull) parseGetVars create real variables that can be used directly in a script.
function parseGetVars()
{
var qString = unescape(top.location.search.substring(1));
var pairs = qString.split(/\&/);
for (var i in pairs)
{
var nameVal = pairs[i].split(/\=/);
window[nameVal[0]] = nameVal[1];
}
}
parseGetVars();
If you place that code as the first code in the HEAD of your document then all the variables will be available to your scripts.
-------------------------------------------------------------------------------
Hers is a test (I created a putVars() to send the vars to the next page).
Save this as index.html - it initially creates the vars 'aa' and 'bb'
<html>
<head>
<title>index.html - initialy creates the vars</title>
<script>
/********** Created here ***********/
aa=1;
bb=1;
/***********************************/
function putVars(url)
{
var str = "?";
var i;
for(i=1 ; i<arguments.length-1 ; i++)
str+=(arguments[i] + "=" + window[arguments[i]] + "&");
str+=(arguments[i] + "=" + window[arguments[i]]);
url.href += str;
}
</script>
</head>
<body>
<A HREF="#" onClick="alert(aa);return false" >Value of aa</A><br>
<A HREF="#" onClick="alert(bb);return false" >Value of bb</A><br>
<A HREF="#" onClick="aa++;return false" >aa = aa + 1 </A><br>
<A HREF="#" onClick="bb++;return false" >bb = bb + 1 </A><br>
<A HREF="#" onClick="bb = (parseInt(bb) + 2);return false" >aa = aa+2</A><br>
<A HREF="#" onClick="bb = (parseInt(bb) + 2);return false" >bb = bb+2</A><br>
<A HREF="index2.html" onClick="putVars(this, 'aa', 'bb');return true" >Put aa,bb</A><br>
</body>
</html>
Save this next file as "index2.html" - it reads the vars and recreates them
<html>
<head>
<title>index2.html - reads the query string and re-creates the vars</title>
<script>
function parseGetVars()
{
var qString = unescape(top.location.search.substring(1));
var pairs = qString.split(/\&/);
for (var i in pairs)
{
var nameVal = pairs[i].split(/\=/);
window[nameVal[0]] = nameVal[1];
}
}
parseGetVars();
/*** You can now use the vars 'aa' and 'bb'***/
status = "aa=" + aa + ":bb=" + bb;
/********************************/
function putVars(url)
{
var str = "?";
var i;
for(i=1 ; i<arguments.length-1 ; i++)
str+=(arguments[i] + "=" + window[arguments[i]] + "&");
str+=(arguments[i] + "=" + window[arguments[i]]);
url.href += str;
}
</script>
</head>
<body>
<A HREF="#" onClick="alert(aa);return false" >Value of aa</A><br>
<A HREF="#" onClick="alert(bb);return false" >Value of bb</A><br>
<A HREF="#" onClick="aa++;return false" >aa = aa + 1 </A><br>
<A HREF="#" onClick="bb++;return false" >bb = bb + 1 </A><br>
<A HREF="#" onClick="bb = (parseInt(bb) + 2);return false" >aa = aa+2</A><br>
<A HREF="#" onClick="bb = (parseInt(bb) + 2);return false" >bb = bb+2</A><br>
<A HREF="index2.html" onClick="putVars(this, 'aa', 'bb');return true" >Put aa,bb</A><br>
</body>
</html>
beetle
08-23-2002, 07:56 PM
Yes! I did. A good modification nonetheless. (oh, and the proper term for 'real' variables is 'global' :D)
I kept the getVars array for my purposes as to not cause any variable conflicts.
Here's an idea to extend it more...function parseGetVars(prefix)
{
if (typeof prefix == 'undefined') prefix = '';
var qString = unescape(top.location.search.substring(1));
var pairs = qString.split(/\&/);
for (var i in pairs)
{
var nameVal = pairs[i].split(/\=/);
window[prefix + nameVal[0]] = nameVal[1];
}
}
parseGetVars('get_');Now all my get variables are global, but prefixed by 'get_'. Of course, it's optional, so you can just leave it out.
beetle
09-06-2002, 09:53 PM
I noticed that there is a tiny error in the logic of this script, that will only affect it when there is an equal sign as part of a value of one of the get variables. Here's the solution.function parseGetVars() {
var getVars = new Array();
var qString = top.location.search.substring(1);
var pairs = qString.split(/\&/);
for (var i in pairs) {
var nameVal = pairs[i].split(/\=/);
getVars[unescape(nameVal[0])] = unescape(nameVal[1]);
}
return getVars;
}
Cheers :D
whammy
12-12-2002, 01:52 AM
I kept the getVars array for my purposes as to not cause any variable conflicts.
That's the only flaw I see in the improvement... I'm going to see how I can improve my code further to do the same thing while trying to avoid conflicts.... looks like we're all aiming for the perfect "querystring parsing script", eh? :)
I think we're all spoiled by server-side scripting and want to force javascript to do the same for us client-side. Which is a good thing. :D
Also, in which case (as beetle said), I would avoid making them global variables using "window" on principle... there may be cases where that would cause a conflict, but perhaps glenngv had the easiest solution to that in a recent post, which was adding something like Macromedia does with Dreamweaver to the beginning of the variable... i.e. he used GV_varname, whereas Macromedia uses MM_varname (I'm sure anyone who has looked at any dreamweaver-generated javascript is quite familiar with that!).
I think it's better to request something and define it as a 'local variable' where requested to err on the safe side, otherwise.
So I guess "GV_blah" (in this case meaning "Global Variable" instead of "Glenn Vergara"), although that may have been his original meaning (I have no idea) might be a near-perfect solution. :D
glenngv
12-12-2002, 09:27 AM
oh whammy I didn't realize that! What I meant with GV is my name. But having a double-meaning with Global Variable is indeed very cool :cool:
Thanks for that :thumbsup:
beetle
12-12-2002, 02:01 PM
Didn't my post a couple up show how to make the global variables prefixed?
Beetle did provide a version that did prefix all the variables. If you look you can see where the getvars is called with a prefix. I think it is the best solution as I would like to be able to get my vars un prefixed (by the getvars routine that is) so I could use the putvars. (I am thinking of a page that keeps updating but passing the vars between each reload).
Beetle, you then posted an update that fixed an error but you kept the getVars array.
Combining what you posted I personally prefer this as the best solution
function parseGetVars(prefix)
{
if (typeof prefix == 'undefined') prefix = '';
var qString = top.location.search.substring(1);
var pairs = qString.split(/\&/);
for (var i in pairs)
{
var nameVal = pairs[i].split(/\=/);
window[prefix + unescape(nameVal[0])] = unescape(nameVal[1]);
}
}
parseGetVars('get_');
//parseGetVars('GV_'); // use this to prefix with GV_
//parseGetVars(); //use this for no prefix
I think this is the best because it allows a user to use this piece of code cut'n' paste and if there is a variable conflict you can just go back and add/change the prefix. (But this is just my personal opinion).
Anyway, I think this is a great piece of code and is the easiest way I have seen of passing vars between pages.
whammy
12-13-2002, 02:15 AM
Oops, my bad - you did indeed! Definitely a very nice piece of work. :)
Wish I had known how all this worked a couple of years ago... :D
Vladdy
12-13-2002, 04:06 AM
Originally posted by whammy
I think we're all spoiled by server-side scripting and want to force javascript to do the same for us client-side. Which is a good thing. :D
LOL Whammy, that is why I implemented the same functionality as follows:
function obj_queryString()
{
qs=document.URL.substring(document.URL.indexOf('?')+1,document.URL.length);
queries=qs.split(/\&/);
for(i=0;i<queries.length;i++)
{ query=queries[i].split(/\=/);
this[query[0]]=unescape(query[1]);
}
}
queryString=new obj_queryString();
whammy
12-13-2002, 04:52 AM
My, that looks even shorter... :D
Roelf
12-13-2002, 10:11 AM
i have created a version that produces a 2D array with all the querystring parameters in it, the name in the [0] and the content in the [1] part. A search function to get the desired vaiable out is also available. I realize it is a bit more code, but the risc of variable conflicts is absolutely minimized. works fine for me
glenngv
12-13-2002, 10:26 AM
I think the best code is Vladdy's. No need for the global variables (nothing to worry about variable conflicts)
...although he could have used location.search instead of document.URL :D
beetle
12-13-2002, 04:40 PM
Indeed, Vladdy's code rocks...it never crossed my mind to make a constructor :rolleyes:
However, as with my own version, I've found a problem with all of these. If the value of the variable is empty, some nasty errors popup. Here's the fix (using Vladdy's code as a base ;))function GetVars() {
var query, qs = top.location.search.substring(1);
var queries = qs.split(/\&/);
for (var i=0; i<queries.length; i++) {
query = queries[i].split(/\=/);
this[query[0]] = (typeof query[1] == 'undefined') ? null : unescape(query[1]);
}
}
var _GET = new GetVars();
Hi Guys,
May I humbly contribute my personal preference for global vars:eval(unescape(location.search.replace(/\+/g,' ').replace(/[?&]([^=]+)=([^&]*)/g, "var $1='$2';")))Please notice it deals with a bug none of the other scripts dealt with.
It's the + sign that substitutes spaces in values and cannot be unescaped.
Other flavors:
Prefixed (discrete):eval(unescape(location.search.replace(/\+/g,' ').replace(/[?&]([^=]+)=([^&]*)/g, "var GV_$1='$2';")))Prefixed (generic):prefix="GV_"
eval(unescape(location.search.replace(/\+/g,' ').replace(/[?&]([^=]+)=([^&]*)/g, "var "+prefix+"$1='$2';")))Associative array:getVars=[]
eval(unescape(location.search.replace(/\+/g,' ').replace(/[?&]([^=]+)=([^&]*)/g, "getVars['$1']='$2';")))Indexed array (Roelf suggestion):indexArray=[]
eval(unescape(location.search.replace(/\+/g,' ').replace(/[?&]([^=]+)=([^&]*)/g, "indexArray[indexArray.length]=['$1','$2'];")))As the difference between flavors is mainly the replacement string,
it should not be too difficult to combine all into one neat object.
A short history:
Way back in the 20th century :) Danny Goodman (JS Bible) wrote an article on the subject (Listing 1):
http://developer.netscape.com/viewsource/goodman_url_pass/goodman_url_pass.html
Early in this century VoiceBox dealt with it here:
http://www.webxpertz.net/forums/showthread.php3?threadid=2814#post14531
( •) (• )
>>V
whammy
12-15-2002, 06:16 AM
Good catch ...
beetle
12-15-2002, 08:42 AM
Indeed, easy enough to add...function GetVars() {
var query, qs = top.location.search.substring(1);
var queries = qs.split(/\&/);
for (var i=0; i<queries.length; i++) {
query = queries[i].split(/\=/);
this[query[0]] = (typeof query[1] == 'undefined') ? null : unescape(query[1]).replace(/\+/g," ");
}
}
var _GET = new GetVars();Personally, I think the eval statments, although compact, are pretty heinous. :D
lMarks
01-15-2007, 11:58 PM
There's a way to do a function to get just the search terms ( the terms that are before the '=') ... like:
location.search = "?q=Query+Id&qtype=Query+Type+Id+A01&homeTitle=my+Home";
function getTerm(n) {
var query = location.search.substring(1).split("&");
var term = query[n].substring(0, query[n].indexOf("="));
return term;
}
var term = new Array();
term[0] = getTerm(0);
Or.. just remove all the content and give back the Terms.. like a array
["q", "qtype", "homeTitle"] orrrr.. array.toString() ~ ["q,qtype,homeTitle"].
Thanks! =]
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.