Attaching custom IDs to links based on the query string

Sometimes you need to attach custom ID like reference ID or a campaign ID to links inside a page content e.g. to track clicks deeper than only on current page.

You can use cookie but if you want to pass a value to different domain or basically you don’t want to use cookies that’s the solution you may be interested in. There are other reasons, everything depends on the implementation and the general need.

Few times I was involved in cross-domain projects with custom tracking for different campaigns. The value was set in a query string e.g. www.mydomain.com/page.html?myID=some_value. The “myID” value will be passed to all links with domain www.otherdomain.com.

In the process of writing this article I wasn’t really thinking about extending query string options, but why not? If you want to attach “myid1″ to some links and “myid2″ to different links you should be able to do it with this script. Basically we’ll use a loop that will go through our associative array.

Now lets set the list of rules we want to implement:

- for better maintanance associative array will be created with list of query arguments and jQuery selector to specify the target where myid will be attached,

- myid will be taken from the query string,

- myid won’t be attached if the query string will be empty e.g.: ?myid1=

- links with manually attached myids will be ignored,

- links with empty myids will be replaced with the proper value e.g.: <a href=”http://www.mydomain.com/?myid1=”>anchor</a>.

Ok, it’s time for some fun :)

As always first we need to include the jQuery library inside the head section of our page:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

Lets create our associative array with options:

var config={
'myid1':[
"#topnav a[href^='http://www.mydomain.com']",
"#topnav a[href^='http://www.randomdomain.com']"
],
'myid2':[
"#topnav a[href^='http://www.otherdomain.com']"
]
}

In above code:

‘myid1′ stands for the name of the ID we’ll get from the query string and attach to links

#topnav a[href^='http://www.mydomain.com'] and #topnav a[href^='http://www.randomdomain.com'] – jQuery selectors, search in div with id topnav for ‘a’ where href starts (^) with http://www.mydomain.com and http://www.randomdomain.com

For the ‘myid2′ we’re doing the same thing, read from query string and attach to links with where domain starts with www.otherdomain.com.

We can add the config variable outside of any functions but to exclude any conflicts with the name it’s for the best to keep it inside :)

We need to read the value from two places, one – from the query string and two – from the href attribute. I think that the best way of doing it is to use one generic function:

//key = query argument to read from the url
//url = full url (our page url or href value)
function getHrefValue(key,url){
//search for the value between 'key=' and & or and of the line
var query=new RegExp("[?&]"+(key.replace(/[[]/,"[").replace(/[]]/,"]"))+"=([^&#]*)").exec(url);
//query=null -> 'no key found' else return the value: empty or value
return (query==null)?null:query[1];
}

It’s time for the best part, the proper function that’ll match/add/replace the anchors href :D

//loop through config array, current = key
for(var current in config){
//get the current key value from location.search (everything after '?')
var myvalue=getHrefValue(current,location.search);
//if above exists and it's not empty
if(myvalue!=null&&myvalue!=""){
//joins the jQuery selectors into one line and search for matches
$(config[current].join(',')).each(function(){
//store the current href attr in href variable
var href=$(this).attr('href');
//search for current key value in href
var hrefvalue=getHrefValue(current,href);
//if current key isn't present in hrefvalue
if(hrefvalue==null){
//split the href into an array, use # as a separator
var href_split=href.split('#');
//this line is a bit optimised, I'll explain below
$(this).attr('href',href_split[0]+(href_split[0].indexOf('?')>-1?'&':'?')+current+'='+myvalue+(typeof(href_split[1])!="undefined"?'#'+href_split[1]:''));
//attach class selected and selected-[key],
//we can add it to above line but just to make it more clear...
$(this).addClass('selected selected-'+current);
}
//if href contains empty key e.g. myid1=
if(hrefvalue==""){
//replace the current key with current key with value e.g. myid1= -> myid1=value
$(this).attr('href',href.replace(current+'=',current+'='+myvalue))
//attach class selected and selected-[key]
$(this).addClass('selected selected-'+current);
}
});
}
}

Now lets put all in one, I’ll add proper comments in the code to explain the matchHrefs function:

function getHrefValue(key,url){
var query=new RegExp("[?&]"+(key.replace(/[[]/,"[").replace(/[]]/,"]"))+"=([^&#]*)").exec(url);
return (query==null)?null:query[1];
}
function matchHrefs(){
var config={
'myid1':["#topnav a[href^='http://www.mydomain.com']","#topnav a[href^='http://www.randomdomain.com']"],
'myid2':["#topnav a[href^='http://www.otherdomain.com']"]
}
for(var current in config){
var myvalue=getHrefValue(current,location.search);
if(myvalue!=null&&myvalue!=""){
$(config[current].join(',')).each(function(){
var href=$(this).attr('href');
var hrefvalue=getHrefValue(current,href);
if(hrefvalue==null){
var href_split=href.split('#');
$(this).attr('href',href_split[0]+(href_split[0].indexOf('?')>-1?'&':'?')+current+'='+myvalue+(typeof(href_split[1])!="undefined"?'#'+href_split[1]:''));
$(this).addClass('selected selected-'+current);
}
if(hrefvalue==""){
$(this).attr('href',href.replace(current+'=',current+'='+myvalue));
$(this).addClass('selected selected-'+current);
}
});
}
}
}
$(function(){matchHrefs();});

Just remember to wrap above code in <script type=”text/javascript”>/*code here*/</script> and that should be it.

If you want to check how it’s working just download the zip file here.

Thanks for reading and see you soon!:)

G.

You may also like...

6 Responses

  1. Korin-K says:

    nice, I was looking for something similar some time ago, Thanks!

  2. Shyam Sundar says:

    This post is an absolute life saver! I was googling for about 2 hrs before I finally found your blog. I don’t know how to thank you Gregory.

    I have a doubt, and I would be really great full if you could help me please. What I am trying to achieve is:
    I know that if i go to http://www.mydomain.com/page.html?myID1=some_value, then “myID1” value will be passed to all links with domain http://www.otherdomain.com.

    But if simply I go to http://www.mydomain.com, i require a default value to be added to the link, example: http://www.otherdomain.com?myID1=default_value

    I guess it something must be edited after the if(hrefvalue==null){ line, but I can’t figure out how to do it. Please help me. Thanks again.

  1. 27th December 2010

    [...] Attaching custom IDs to links based on the query string … [...]

  2. 28th December 2010

    [...] Attaching custom IDs to links based on the query string – ArtisNavi.com [...]

  3. 24th October 2011

    [...] guess this is possible with javascript, but I’m not sure how to do it. I found this during my research, but its not exactly what I’m looking for. I want the change to happen [...]

  4. 25th October 2011

    [...] this case. I guess this is possible with javascript, but I’m not sure how to do it. I found this during my research, but its not exactly what I’m looking for. I want the change to happen [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>