Helpful Information
 
 
Category: Coding tips & tutorials threads
Implementation to send variables through the url (with javascript) like PHP $_GET.

I remember several times this question has been asked in this forum and I never found an appropriate answer. So today as I was reading a book I thought of sending variables through javascript from one page to the other. This is just an experiment which I thought I should share it with you so that I know what I did wrong and what I need to implement.:) Here's the script:



<html>
<head>
<title>Javascript Implementation to PHP type GET variables.</title>
<script type="text/javascript">
var url = String(window.location);
var index = url.indexOf("?");
var data = url.substr(index+1);
var splitted = data.split("=");
event = splitted[0];
act = splitted[1];
</script>
</head>
</body>
<script type="text/javascript">
if(index == -1){
document.write("Please Click One of these links: <a href='"+url+"?user=false'>Login as a Guest</a><br /><a href='"+url+"?user=true'>Login as a user</a>");
} else if(event == "user" && act == "true"){
document.write("Welcome User.");
} else {
document.write("You are a stranger!!!");
}
</script>
</body>
</html>


So what do you think guys??

EDIT: Forgot to mention it still can't catch all the url variables(for e.g this=that&multiple=variables).

Here a more user friendly version:



<html>
<head>
<title>Javascript Implementation to PHP type GET variables.</title>
<script type="text/javascript">
var url = String(window.location);
var index = url.indexOf("?");
var data = url.substr(index+1);

var splitted = data.split("=");
event = splitted[0];
act = splitted[1];
</script>
</head>
</body>
<script type="text/javascript">
if(index == -1){
document.write(noindex());
} else if(event == "user" && act == "true"){
document.write(isuser());
} else {
document.write(notuser());
}
function noindex(){
content = ''
content += "Please Click One of these links: <br><a href='"+url+"?user=false'>Guests Click Here</a><br /><a href='"+url+"?user=true'>Users Click Here</a>";
return content;
}
function notuser(){
content = ''
content += 'You are a stranger!!!';
return content;
}
function isuser(){
content = ''
content += 'Welcome User';
return content;
}
</script>
</body>
</html>

Is anyone interested?? Hello??

I don't really get the point....I mean get variables are useful for form processing, but you don't need to reload the page for that. I can't think of anything that this could be used for.

It can be useful if you want to implement dynamic/flexible pages with javascript like

for displaying a form :
http://somehost.somedomain/somefile.somextension?show=form
to show something else in the same page :
http://somehost.somedomain/somefile.somextension?show=somethingelse

So that's all I made this for. It proved to be useful for me and thought may be someone else could also find this useful.

Yes but the problem is what if the user has disabled javascript. Your site becomes inaccessible.

In that case either the author has to use PHP or go in the traditional way or let his users that js must be enabled before accessing the page.:)

Here a more user friendly version:



<html>
<head>
<title>Javascript Implementation to PHP type GET variables.</title>
<script type="text/javascript">
var url = String(window.location);
var index = url.indexOf("?");
var data = url.substr(index+1);

var splitted = data.split("=");
event = splitted[0];
act = splitted[1];
</script>
</head>
</body>
<script type="text/javascript">
if(index == -1){
document.write(noindex());
} else if(event == "user" && act == "true"){
document.write(isuser());
} else {
document.write(notuser());
}
function noindex(){
content = ''
content += "Please Click One of these links: <br><a href='"+url+"?user=false'>Guests Click Here</a><br /><a href='"+url+"?user=true'>Users Click Here</a>";
return content;
}
function notuser(){
content = ''
content += 'You are a stranger!!!';
return content;
}
function isuser(){
content = ''
content += 'Welcome User';
return content;
}
</script>
</body>
</html>



I'm sorry, i'm kind of a novice, so could someone please give me a play-by-play of just what this script does? I can use all the help I can get.

This is vastly over-complicated.
<script type="text/javascript">
var _GET = window.location.href.substr(window.location.href.indexOf('?') + 1).split(/&|;/);
for(var i in _GET)
if(_GET[i].indexOf('=') === -1)
_GET[unescape(_GET[i])] = '';
else _GET[unescape(_GET[i].substr(0, _GET[i].indexOf('=')))] = unescape(_GET[i].substr(_GET[i].indexOf('=') + 1));
</script>Ta-da.

This function is good enough to get the GET variables:


function get(key_str) {
if(window.location.search) {
var query = window.location.search.substr(1);
var pairs = query.split("&");
for(var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split("=");
if(unescape(pair[0]) == key_str)
return unescape(pair[1]);
}
}
}

@Mobulus: This function takes the query string (?this=this&that=that...) from the url and handels it so that you can access evry variable separately.
-------------------------------
Aaaawwwww, Twey... :p

Still bigger than it has to be.

There's no point in calling a function every time you want to get a variable. The query string isn't going to change, so you might as well just store everything in an object at the start and avoid the overhead. Also, that script fails to take into consideration the non-existance of window.location.search, the use of semicolons to separate variables, and the use of URL-encoded characters.

Also, that script fails to take into consideration the non-existance of window.location.search
Actually, if there is no query string the function returns undefined. So I don't have to deal with that.

Semicolons? I've never seen any site where the get variables are seperated with semicolons.

http://www.simplemachines.org/community/

Oh thank twey and DimX for improving my code. I was using it because of my non-serverside-language-enabled site in tripod and my code was limited but yours rocks. Thanks all you guyz. I think that it can even handle ajax requests. But I must try.Thanks again.:D

http://www.simplemachines.org/community/
Oh well, fine :p here's the "perfect" function:


function $_GET(key_str) {
if(window.location.search) {
var query = window.location.search.substr(1);
var pairs = query.split(/&|;/);
for(var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split("=");
if(unescape(pair[0]) == key_str)
return unescape(pair[1]);
}
}
}

alert( $_GET("p") );


Btw. yes, it could be done only once when the page loads:


var $_GET = new Array();
if(window.location.search) {
var query = window.location.search.substr(1);
var pairs = query.split(/&|;/);
for(var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split("=");
$_GET[unescape(pair[0])] = unescape(pair[1]);
}
}

alert( $_GET["p"] );

That's perfect DimX,Twey!!!

Oh it does not work with ajax calls probably because it cannot find window.location in ajax requests.

var $_GET = new Array();
if(window.location.search) {
var query = window.location.search.substr(1);
var pairs = query.split(/&|;/);
for(var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split("=");
$_GET[unescape(pair[0])] = unescape(pair[1]);
}
}

alert( $_GET["p"] );$ should be reserved for system identifiers in Javascript, and I still don't see what's wrong with my original:
<script type="text/javascript">
var _GET = location.href.substr(window.location.href.indexOf('?') + 1).split(/&|;/);
for(var i in _GET)
if(_GET[i].indexOf('=') === -1)
_GET[decodeURIComponent(_GET[i])] = '';
else _GET[decodeURIComponent(_GET[i].substr(0, _GET[i].indexOf('=')))] = decodeURIComponent(_GET[i].substr(_GET[i].indexOf('=') + 1));
</script>
Oh it does not work with ajax calls probably because it cannot find window.location in ajax requests.It won't work with AJAX calls, because scripts on a page loaded via AJAX aren't even called unless you do so manually, and then they refer to the loading page's window.location, not the loaded page.

and then they refer to the loading page's window.location, not the loaded page.

That's what I meant by


probably because it cannot find window.location in ajax requests


$ should be reserved for system identifiers in Javascript,

It means that the prototype $ function isn't valid too?? And is it a should or a must??

... and I still don't see what's wrong with my original
Nothing, it's perfect, I was just using another technique ;)

It means that the prototype $ function isn't valid too?? And is it a should or a must??"Should," not "must." :) It's just bad form.

Thanks for clearing the point Twey.

There's no point in calling a function every time you want to get a variable. The query string isn't going to change, so you might as well just store everything in an object at the start and avoid the overhead.

You're not wrong. There would be overhead, of course, but then a counter argument is that the function would be called so infrequently that the relatively small amount of overhead that would occur would be insignificant. There's no harm in caching the results (though calling code could do that, too), but I don't think it's a big deal.



Also, that script fails to take into consideration the non-existance of window.location.search,

An alternative is the URL property of the document object, which should also be well supported.




Semicolons? I've never seen any site where the get variables are seperated with semicolons.

That's not quite the point though, is it? The HTML Specification recommends in appendix B.2.2 that both HTTP and CGI (or other server-side language) implementors accept semicolons to allow markup authors to forego the hassle of encoding ampersands as entity references in URLs in attributes.



var $_GET = new Array();

Why an array? You aren't using any array features, but rather a feature of objects in general; an Object object is all that's necessary.




$ should be reserved for system identifiers in Javascript ...

Machine-generated identifiers.



and I still don't see what's wrong with my original:

You use a for..in loop to iterate over an array. That's not particularly sensible, particularly as for..in iterative statements are prone to enumerating user-defined properties inherited through the prototype chain, and even host properties that aren't assigned the DontEnum attribute. You should use a for statement, instead, particularly due to the fact that the only properties you are interested in are array indices.




It means that the prototype $ function isn't valid too??

The Prototype library is poor full-stop. The fact that it flouts an established convention is just one reason why.



And is it a should or a must??

It is defined as such in the language specification, and there is no reason to disregard that reservation: there are other, less obtuse means of naming or prefixing identifiers.

Mike

There would be overhead, of course, but then a counter argument is that the function would be called so infrequently that the relatively small amount of overhead that would occur would be insignificant.Yes, but the point was that one might as well save that overhead anyway, particularly when it takes more code to do it the slightly-less-efficient way.
You use a for..in loop to iterate over an array.I do? Whoops...
<script type="text/javascript">
var _GET = window.location.href.substr(window.location.href.indexOf('?') + 1).split(/&|;/);
for(var i = 0; i < _GET.length; ++i)
if(_GET[i].indexOf('=') === -1)
_GET[unescape(_GET[i])] = '';
else _GET[unescape(_GET[i].substr(0, _GET[i].indexOf('=')))] = unescape(_GET[i].substr(_GET[i].indexOf('=') + 1));
</script>

Yes, but the point was that one might as well save that overhead anyway, particularly when it takes more code to do it the slightly-less-efficient way.

Umm:



function getQueryValue(name) {
var match = (new RegExp('[?&;]' + name + '=([^&;#]*)')).exec(document.URL);

return match ? unescape(match[1]) : null;
}

More code, you say? :p That (only lightly tested, by the way) also copes with fragment identifiers, which seem to have been forgotten in other solutions.

Mike

Bah. Foiled. :p Well, that pretty much obsoletes the rest.
I'm not as up on regex as I should be, so I have to ask: Could one use a .match() operation or two to fill an object with the values as I did with mine?

I'm not as up on regex as I should be, so I have to ask: Could one use a .match() operation or two to fill an object with the values as I did with mine?

You could, though it wouldn't be a simple one-step process.

When a string or non-global regular expression object is passed to the String.prototype.match method, it's exactly the same as calling the RegExp.prototype.exec method:



pattern.exec(string)

If pattern was a string, it's passed to the RegExp constructor function, first.

On the other hand, if the argument is a regular expression object with the global flag set, the return value is array of matches. Unfortunately, each element is the matched substring, rather than the actual result from the exec method. For example, if you were to use the regular expression:



/[?&;]([^=]+)=([^&;#]*)/

you'd get results like "?foo=bar" and "&flag="; the capturing parentheses are ignored and might as well not exist. As such, you'd still need to strip the first character and split on the equals symbol.

By the way, the latter result is how flags have to represented in the query string to be matched by the getQueryValue function. Furthermore, to differentiate a flag (which would be returned as an empty string) and a non-existent value, compare the return value with null.

Mike

Can you please explain why in this function:

function getQueryValue(name) {
var match = (new RegExp('[?&;]' + name + '=([^&;#]*)')).exec(document.URL);

return match ? unescape(match[1]) : null;
}

you used this line:

return match ? unescape(match[1]) : null;

while


return match[1];
works fine?

What exactly does the syntax mean?

It means:


if (match)
return unescape(match[1]);
else
return null;

Because if no matches are found it's better to return null.

ok, so why the unescape() if it works without it?

Because the URL may contain characters such as %2e, which should be unescape()ed back into their original unencoded forms (. in this case).

Can you please explain why ... you used this line:

return match ? unescape(match[1]) : null;

while


return match[1];
works fine?

For what definition of "works"?

Yes, if the regular expression is always matched (if the sought parameter is always present), then the exec method will always return an object reference. However, if a parameter is absent the return value will be null, and attempting to access a property of a null value will cause a run-time error.

Mike










privacy (GDPR)