In this post, I would like to share a little jQuery code snippet that makes getting URL parameters and their values more convenient.
Recently, while working on one of my projects, I needed to read and get parameter values from URL string of the current page that was constructed and sent by PHP script. I came across this short and sweet JavaScript code snippet by Roshambo that does just that.
// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
The function returns an array/object with your URL parameters and their values. For example, consider we have the following URL:
http://www.example.com/?me=myValue&name2=SomeOtherValue
Calling getUrlVars()
function would return you the following array:
{
"me" : "myValue",
"name2" : "SomeOtherValue"
}
To get a value of first parameter you would do this:
var first = getUrlVars()["me"];
// To get the second parameter
var second = getUrlVars()["name2"];
To make the script syntax to look more jQuery like syntax I rewrote it as an extension for jQuery:
$.extend({
getUrlVars: function(){
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
},
getUrlVar: function(name){
return $.getUrlVars()[name];
}
});
Now, if you include the above code in your javascript file, you can get URL parameter values in the following way:
// Get object of URL parameters
var allVars = $.getUrlVars();
// Getting URL var by its nam
var byName = $.getUrlVar('name');
That’s it! You might also find the following jQuery related articles on this blogs interesting:
Shouldn't you cache the decoded vars?
ReplyDeleteI don't really see the point of making this a jquery plugin in this case, since it doesn't take jQuery or DOM elements and doesnt return them either.
ReplyDeleteNonetheless, This is by far the cleanest implementation of this utility I have seen.
Also, jQuery will let you go back the other way too:
$.param({
me: "myValue",
name2: "someOtherValue"
});
returns "me=myValue&name2=someOtherValue"
This is really nice for caching the results of jQuery plugins that take objects as parameters. Usually, if you try to say cache[obj] = foo obj.toString will be called and you will be left with "[object Object]", which is not too helpful, but $.param() handles everything cleanly and quickly. So, now cache[$.param(obj)] = foo works out perfectly.
Thanks !!
ReplyDeleteJust one line is enough inside getUrlVars():
ReplyDeletereturn window.location.href.slice(window.location.href.indexOf('?')).split(/[&?]{1}[\w\d]+=/);
Take care
That's pretty sweet. I'm in the need for just this bit of code. Thanks! :)
ReplyDeleteShane
I was going to reply to this post with a regex solution, which I think is much more elegant. However, someone has obviously beat me to it:
ReplyDeletehttp://ejohn.org/blog/search-and-dont-replace/
Er, I posted too soon. The page I linked to wasn't solving this exact problem. Here's the solution that solves this problem:
ReplyDeletefunction getUrlParameters() {
var map = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
map[key] = value;
});
return map;
}
you are confusing location.search and location.hash
ReplyDeletehere is an example i built for a framework that extracts both search and hash
var Params = {
/*
Get
-------------------------------
walk through window.location.search and window.location.hash
generate object (result) from iteration
*/
Get:function()
{
result = {};
request = {
search:window.location.search.slice(1, window.location.search.length),
hash:window.location.hash.slice(1, window.location.hash.length)
}
// check
for(type in request)
{
if(request[type] != "")
{
var x = request[type].split("&");
for(i in x)
{
var y = x[i].split("=");
var prop = y[0];
var value = y[1];
result[prop] = value;
}
}
}
return result;
}
}
where result will be an object as such
result = {
search:{
prop:value,...
},
hash:{
prop:value,...
},
}
ps: love your articles
addons.32teeth@gmail.com
I know this is completely unrelated but based on your understanding of jquery, please indulge me an see if you can help me...
ReplyDeleteI have this code
jQuery(document).ready(function() {
$('a').click(function() {
...
I have a lot of a (=link) tags generated dynamically after an Ajax call that I tug inside a div tag but for the life of me they do not get selected based on the event above...can you help me out? thanks!
Looks great!! But how to call an extension in jquery ?
ReplyDeleteThanks Alex
This is a great bit of code, thanks a lot. I added the code in a separate js file and works well.
ReplyDeleteWould be nice to add decodeURI before slice url
ReplyDeleteExcellent article.
ReplyDeleteBut after reading the following
http://asimilia.wordpress.com/2008/12/17/jquery-extend-confusion/
I have little bit confusion... which one is correct in our example?
Hi, Thanks for the post.
ReplyDeleteWhat if the query parameter is an object. When I try to access that object it's giving me an error. please help, thanks.
var first = getUrlVars()["query"];
alert("property ==="+first.name);
What jquery version library does this work with?
ReplyDeletethanks all
Getting some "unexpected token in attribute selector" error message.
I basically created a blank html and linked to the latest jQuery library and added the above code to a "script" block
thanks =D
ReplyDeleteyou could simply use this:
ReplyDeletevar rUrl = $(document).getUrlParam("ReturnUrl");
OR
var rUrl = $().getUrlParam("ReturnUrl");
http://somesite.com?ReturnUrl=%2fStore%2fProducts%2fAdd
Original posting:
http://www.techiegyan.com/2009/04/01/read-url-parameter-in-javascript-jquery-plugin/
thanks for saving my brain from extraction.. NICE POST
ReplyDeleteWhat about the hash? Currently, the above code will add the hash onto the last query parameter.
ReplyDeleteWhoops... I think I lied, sorry...
ReplyDeleteexcellent code...
ReplyDeleteafter a long search i found this solution good
but what if the URL has a hash at the moment?
ReplyDeleteif there is a location hash, this script doesnt work right...
Thanks. Probably want to modify the hashing part to something like:
ReplyDeletevar url = decordeURI(window.location.href.replace(/&/g, "&"));
var hashes = url.indexOf("?") + 1).split("&");
There's probably an even better regex way.
This is incredibly useful to my team. We are using it to simulate pages in prototyping without the benefit of a database, so being able to manipulate pages and content within based on this is wonderful. Thanks so much!
ReplyDeleteNote that the URL can also have anchors- e.g.:
ReplyDeletehttp://jquery-howto.blogspot.com/2009/09/get-url-parameters-values-with-jquery.html#comments
Perhaps use something like:
vars[hash[0]] = hash[1].replace(/#/g, '');
Would someone be nice enough to tell me step by step how to pull the URL parameter and place it as a string inside of a form text box? Sorry if this is a newbie question, but I think it would help a lot of people implement this idea.
ReplyDeleteHey dude. Thank you so much, you rocks!
ReplyDeleteWhen there are multiple url parameters i am seeing getUrlVars()["me"]; is returning 'myValue,' instead of 'myValue'
ReplyDeleteAnybody is seeing this kind of issue?
Dunno if it will help anyone out, but I've extended it a little bit to handle arrays passed through the URL (eg: http://website.com/?myarray[]=test1&myarray[]=test2&myarray[]=test3 )
ReplyDelete$.extend({
getURLVariables : function() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
var key = hash[0].split('[]')[0];
if(!vars[key]) {
vars.push(key);
vars[key] = [];
}
vars[key].push(hash[1]);
}
return vars;
},
getURLVariable : function(name) {
var val;
var query = $.getURLVariables()[name];
if(query){
if(query.length == 1) {
val = query[0];
} else {
val = query;
}
}
return val;
}
});
if you have page anker in your page, and parse your url including an anker, the anker will become part of last element
ReplyDeleteex http://mypage/somepage.html?a=2345#kurt
So before parsing the url you should remove everying after and including the #
it will be great if you write a article about jQuery security while getting parameters from the url... i have some work in jquery, but i don't feel they are highly secure...
ReplyDeleteYears too late, but you should do a check to see if the var exists before returning a value (to avoid a javascript error):
ReplyDeletegetUrlVar: function(name){
if($.getUrlVars()[name]){
return $.getUrlVars()[name];
}else{return null;}
}
yoink!
ReplyDeletejust added it to my plugin (added decodeURIComponent to returned value), thanks :-)
Thanx a lot for your help. Saves me a lot of time! :)
ReplyDeleteHere's a variation of the function to extract a single value: https://gist.github.com/1771618
ReplyDeleteOops, that last version had issues when there were no params. Here's a better version:
ReplyDeletefunction getUrlVars() {
var params = {}, d = function (s) { return s ? decodeURIComponent(s.replace(/\+/, " ")) : null; }
if(window.location.search) $.each(window.location.search.substring(1).split('&'), function(i, v) {
var pair = v.split('=');
params[d(pair[0])] = d(pair[1]);
});
return params;
}
can this code be used on a commercial website
ReplyDeleteI like! Cheers mate!
ReplyDeleteAwesome post. Works like a charm. Thanks!
ReplyDeleteWhy not make it more useful and PASS it the url, so you can parse hrefs from links too?
ReplyDeletefunction getUrlVars(url)
{
var vars = [], hash;
var hashes = url.slice(url.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
If you want it for page then call it with
var myGetArray = getUrlVars(window.location.href);
this will not work for arrays returned through get, which have the following syntax:
ReplyDelete?a[action]=5&a[method]=b
The obvious object that should be returned is:
{
"a": {
"action": 5,
"method": "b"
}
}
and not:
{
"a[action]": 5,
"a[method]": "b"
}
Works well. Thanks
ReplyDeleteRegarding the regex solution, here's a simple variant that expands the function to include keys that don't have values defined. For example in "page.html?mobile&page=1", the "mobile" key has no value. Just add a question mark (?) after the second equals (=) sign in the regex string. It will yield the object {mobile:"",page:1}, whereas without the ? mark the mobile key won't even make it into the object. This is useful if you just need to detect the existence of a key in the URI, and not necessarily the value.
ReplyDeleteHere's a copy of the full function with the ? mark added after the second equal sign in the regular expression.
function getUrlParameters() {
var map={};
var parts=window.location.href.replace(/[?&]+([^=&]+)=?([^&]*)/gi,function(m,key,value){
map[key]=value;
});
return map;
}
I have made some modifications to fix encoding problem :
ReplyDeletevars[v[0]] = decodeURI(v[1]);
Result is :
(function ($) {
/**
* returns object with url variables
* hash parameters take precedence over search
* parameters
* @return {Object}
*/
$.getUrlVars = function () {
var loc = document.location,
search = loc.search.replace('?', '').split('&'),
hash = loc.hash.replace('#', '').split('&'),
i, l, v, vars = {};
for (i = 0, l = search.length; i < l; i++) {
v = search[i].split('=');
vars[v[0]] = decodeURI(v[1]);
}
for (i = 0, l = hash.length; i < l; i++) {
v = hash[i].split('=');
vars[v[0]] = decodeURI(v[1]);
}
return vars;
}
/**
* returns a single value from the getUrlVars hash
* @param {String} i The hash index
* @return {String}
*/
$.getUrlVar = function (i) {
return $.getUrlVars()[i];
}
}(jQuery));
Thanks, works great.
ReplyDeletethis doesn't work for a single variable. i.e. there is no & to split on..
ReplyDeleteBest example I have seen - thumbs up!
ReplyDeleteThis doesn't work for URL's with a hash section. For example:
ReplyDeletehttp://www.whatever.com/?id=38389#Registration
In the id field, the value would be 38389#Registration which is incorrect.
You should use window.location.search instead of window.location.href.slice(window.location.href.indexOf('?') + 1)
I have two variables "coachid" & "screenname"
ReplyDelete?coachid=186123&screenname=Hank247Fitness
Not sure exactly how to implement this into the following code:
function cleanse( txt ) {
txt = txt.replace( /\s/g, '' );
txt = txt.replace( /[^A-Za-z0-9.]/g, '' );
return txt;
}
function update_links() {
var sn = cleanse( $('#screenname').val() );
var ci = cleanse( $('#coachid').val() );
$('.linkformat').each( function( lfind, lf ) {
var lf_id = lf.id.match( /lf_(.*)$/ );
lf_id = lf_id[1];
var fmt = $(lf).text();
fmt = fmt.replace(/\{\{screenname\}\}/gi, sn );
fmt = fmt.replace(/\{\{coachid\}\}/gi, ci );
var linkresult = $('#lr_'+lf_id);
if ( linkresult.get(0).nodeName == 'A' ) {
$('#lr_'+lf_id).attr( 'href', fmt );
$('#lr_'+lf_id).text( fmt );
} else {
$('#lr_'+lf_id).text( fmt );
}
} );
}
$(function() {
$('.coach-image').click( function( e ) {
e.preventDefault();
$('#coachid').val( $(this).attr('coachid') );
$('#screenname').val( $(this).attr('screenname') );
update_links();
} );
$('.watchable').keyup( function() { update_links(); } );
$('.watchable').blur( function() { update_links(); } );
$('#getname').click(function() {
$.ajax({
type: "POST",
url: "getname.php",
data: "id=" + escape($('#coachid').val()),
success: function(data) {
if ( data.name != null ) {
$('#screenname').val(data.name);
} else if ( data.error != null ) {
alert("There was an error accessing the server: " + data.error);
}
},
error: function() {
alert("The getname backend function is not present or could not be invoked properly.");
}
});
});
update_links();
});
Hi,
ReplyDeleteWhat if i have a "=" in my value?
let's say http://www.example.com?var1=val1&var2=val2=val3
note that, var2 should be "val2=val3"
but in this case, i only got "val2"
Thank you.