i everyone,
I'm a complete novice to javascript and have been looking around for a few days now trying to figure this one out. If you have any advice or ideas, I'd GREATLY appreciate it!

Here is what I'm trying to do. I run a review site with multiple cities.
For each city page, I want to display different banners. When someone comes to my site, they select the city they are from and a cookie is set.
The cookie is called "transfer_page" and the values are "LA" "NY" "London" etc.

I have different banner campaigns for each city.
So, once a visitor has selected their page (and the cookie has been set), I want them to only see the banners that apply to their city.

Here is the cody I'm using right now. I'm using smarty templates as well, if that helps at all. (so I'm using the {literal} tag as well)

Here is what I'm come up with so far:

{literal}
<script type="text/javascript">		
function checkCookie()
{
var city=getCookie('transfer_page');
if (city!=null && city!="LA")
  {
 	document.write('{$ads->getAdCode(1)');
  }
if (city!=null && city!="London")
  {
 	document.write('{$ads->getAdCode(2)');
  }
else
  {
 	document.write('{$ads->getAdCode(3)');  
  }
}
</script>
{/literal}

Thank you again for any insight you may be able to provide. Please go easy on me, I'm sure the above code is completely wrong! ;-)

Thanks again,
John

Recommended Answers

All 10 Replies

Johnathan,

Cookie handling is a bunch of rather tedious string handling, so it's best to let some ready-made cookie class handle all that, freeing you to invoke some simple methods.

Here's a demo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Airshow :: Untitled</title>
<style type="text/css">
{}
</style>

<script>
//General purpose Cookie class (typically saved in separate file, cookie.js).
var Cookie = function(name, hours, path, domain, secure) {
	this.$name = name;
	this.$expiration = (hours) ? new Date((new Date()).getTime() + hours*3600000) : null;
	this.$path = (path) ? path : null;
	this.$domain = (domain) ? domain : null;
	this.$secure = (secure) ? true : false;
	this.store = function() {
		var prop;
		var cookievalArray = [];
		for(prop in this){
			if((prop.charAt(0)!=='$') && (typeof this[prop]!=='function')) {
				cookievalArray.push( prop + ':' + escape(this[prop]) );
			}
		}
		var cookie = [ this.$name + '=' + cookievalArray.join('&') ];
		cookie.push( (this.$expiration) ? 'expires=' + this.$expiration.toGMTString() : '' );
		cookie.push( (this.$path)       ? 'path='    + this.$path                     : '' );
		cookie.push( (this.$domain)     ? 'domain='  + this.$domain                   : '' );
		cookie.push( (this.$secure)     ? 'secure'                                    : '' );
		document.cookie = cookie.join('; ');
	};
	this.load = function() {
		var i;
		var allcookies = document.cookie;
		if(allcookies==='') { return false; }
		var start = allcookies.indexOf(this.$name + '=');
		if(start===-1) { return false; }
		start += this.$name.length + 1;
		var end = (allcookies.indexOf(';',start)===-1)? allcookies.length : allcookies.indexOf(';',start);
		var cookieval = allcookies.substring(start,end);
		var a = cookieval.split('&');
		for(i=0; i<a.length; i++){
			a[i] = a[i].split(':');
			this[a[i][0]] = unescape(a[i][1]);
		}
		return true;
	};
	this.remove = function() {
		var cookie = [this.$name + '='];
		if(this.$path)   { cookie.push( 'path=' + this.$path ); }
		if(this.$domain) { cookie.push( 'domain=' + this.$domain ); }
		cookie.push( 'expires=Fri, 02-Jan-1970 00:00:00 GMT' );
		document.cookie = cookie.join('; ');
	};
	this.clear = function() {
		var prop;
		for(prop in this){
			if((prop.charAt(0)!=='$') && (typeof this[prop]!=='function')) {
				delete this[prop];
			}
		}
	};
};
</script>
<script>
onload = function() {
	var cookie = new Cookie('transfer_page', 200000);
	cookie.load();

	var cityHTML = {
		LA: '<h3>Los Angeles</h3>',//replace with smarty tag {$ads->getAdCode(1)}
		NY: '<h3>New York</h3>',//replace with smarty tag {$ads->getAdCode(2)}
		LONDON: '<h3>London</h3>'//replace with smarty tag {$ads->getAdCode(3)}
	};

	function saveCity(cityName) {//call this function (from wherever) to store cityName in the cookie
		//This will probably be part of a larger "saveProfile" function.
		cookie.city = cityName;
		//cookie.xxx = 'xxx';//sample other profile details
		//cookie.yyy = 'yyy';//sample other profile details
		cookie.store();
	}
	
	function setBanner() {//call this function (from wherever) to retreive cityName from the cookie and write the banner into the document.
		var city = cookie.city;
		var banner = document.getElementById('banner');
		if(banner) {
			banner.innerHTML = (city) ?  cityHTML[city.toUpperCase()] : "<p>Please set City in your profile</p>";
		}
	}
	setBanner();
	
	// ********** surrogate code to set city *********
	var button1 = document.getElementById("setCity_LA");
	var button2 = document.getElementById("setCity_NY");
	var button3 = document.getElementById("setCity_LONDON");
	button1.onclick = button2.onclick = button3.onclick = function(){
		saveCity(this.value);
	}
	// ********** ************************** *********
};
</script>
</head>

<body>

<div id="banner"></div>

<!-- ********** surrogate HTML to set city ********* -->
<button id="setCity_LA" value="LA">LA</button>&nbsp;
<button id="setCity_NY" value="NY">NY</button>&nbsp;
<button id="setCity_LONDON" value="London">London</button>&nbsp;
<!-- ********** ************************** ********* -->

</body>
</html>

Airshow

Thank you Airshow!
This is a huge help. Looks like I wasn't even remotely close! Still much more learning to do.

I've implemented it as you suggested and it works just as you said.
The only difference is that the cookie is already set as "London" or "LA" or "NY" and I noticed that this script writes a new cookie as "city:London" with the "city:" in front.

Since the cookie is already set in the user's browser before they get to this page, is there anyway this script can look for the "London" value in the existing cookie? Without having to set it again using the buttons you used?

So if I have the "London" cookie already set, when I get to this page, it will recognize it and then show the London content?

Thank you again, I really appreciate you taking the time to help me with this.

Johnathan

Johnathan,

Sure, whatever was saved can be retreived but I will need to see the code which set the existing cookie and the cooke text itself.

It's probably incompatible with my cookie class but we may be able to create some code to handle that legacy and have my cookie class for easier cookie management in the future.

Airshow

Hi Airshow,
Here is the code I currently use to set a cookie when the user selects the city they are in:

function setCookie(cookieName,cookieValue,nDays) {
 var today = new Date();
 var expire = new Date();
 if (nDays==null || nDays==0) nDays=1;
 expire.setTime(today.getTime() + 3600000*24*nDays);
 document.cookie = cookieName+"="+escape(cookieValue)
                 + ";expires="+expire.toGMTString();
	//alert(expire.toGMTString()+'---');
}

function getCookie(c_name)
{
if (document.cookie.length>0)
  {
  c_start=document.cookie.indexOf(c_name + "=");
  if (c_start!=-1)
    {
    c_start=c_start + c_name.length+1;
    c_end=document.cookie.indexOf(";",c_start);
    if (c_end==-1) c_end=document.cookie.length;
	//alert(unescape(document.cookie.substring(c_start,c_end)));

    return unescape(document.cookie.substring(c_start,c_end));
    }
  }
return "";
}
function checkCookie()//dest
{
	transferpage=getCookie('transfer_page');
	return transferpage;
}
function redirectindexpage(dest)
 {
 setCookie('transfer_page',dest,365)
 $(document).ready(function(){
  
 setCookie('transfer_page',dest,365);
  transferpage = checkCookie();
 });
 checkCookie('transfer_page'); 
   if(dest =="LA")
   {
		 $(window.location).attr('href', 'http://www.actorrated.com/indexLA.php');
   }
   if(dest =="NY")
   {
	 	$(window.location).attr('href', 'http://www.actorrated.com/indexNY.php');	 
   }
    if(dest =="Other")
   {
	 	$(window.location).attr('href', 'http://www.actorrated.com/index.php');	 
   }
       if(dest =="Chicago")
   {
	 	$(window.location).attr('href', 'http://www.actorrated.com/indexCH.php');	 
   }
   		if(dest =="London")
   {
	 	$(window.location).attr('href', 'http://www.actorrated.com/indexLON.php');	 
   }

} 
 $(document).ready(function(){
 	transferpage = checkCookie();
	//alert(transferpage+'66666');
	var pagename =  '{/literal} {$page_name}{literal}';
	if(pagename!='' && pagename!=null  && pagename!=undefined)
	 	pagename = jQuery.trim(pagename);

	var defpagename = "index.php";
	 //alert(transferpage);
	if(transferpage==null || transferpage=="")
		 { 
						
		 if((pagename)==defpagename)
		 {
			window.scroll(1,1);
			//document.getElementsByTagName('html')[0].style.overflow = 'hidden';
			document.getElementById('selpage').style.display='block';
			document.getElementById('fade_f').style.display='block';
			getPageSize();
		}		
	 }
	else{
	if(transferpage!=null && transferpage!="")
     {
	  if(pagename==defpagename)
		 {
			if(transferpage=="LA")
				$(window.location).attr('href', 'http://www.actorrated.com/indexLA.php');
			
			if(transferpage=="NY")
				$(window.location).attr('href', 'http://www.actorrated.com/indexNY.php');
				
			if(transferpage=="Chicago")
				$(window.location).attr('href', 'http://www.actorrated.com/indexCH.php');	
			
			if(transferpage=="London")
				$(window.location).attr('href', 'http://www.actorrated.com/indexLON.php');	
		}
	 
	 }
	}
 }); 
 ///////////////////
$(window).load(function() {	
	$('#slider').nivoSlider({
		effect:'random', //Specify sets like: 'fold,fade,sliceDown'
		slices:15,
		animSpeed:500,
		pauseTime:6000,
		startSlide:0, //Set starting Slide (0 index)
		directionNav:true, //Next & Prev
		directionNavHide:true, //Only show on hover
		controlNav:true, //1,2,3...
		controlNavThumbs:false, //Use thumbnails for Control Nav
      controlNavThumbsFromRel:false, //Use image rel for thumbs
		controlNavThumbsSearch: '.jpg', //Replace this with...
		controlNavThumbsReplace: '_thumb.jpg', //...this in thumb Image src
		keyboardNav:true, //Use left & right arrows
		pauseOnHover:true, //Stop animation while hovering
		manualAdvance:false, //Force manual transitions
		captionOpacity:0.8, //Universal caption opacity
		beforeChange: function(){},
		afterChange: function(){},
		slideshowEnd: function(){} //Triggers after all slides have been shown
	});

});
</script>

Thanks again,
John

Oh woops, you can ignore the nivoSlider code... ;-)

You can see the code in action at ActorRated.com/index.php (this will make the city selector popup appear).

On the London (indexLON.php) page you can see my attempt at inserting your code.

Thank you again,
John

Here's a new version of Cookie. Note the added method legacyLoad().

//General purpose Cookie class (typically saved in separate cookie.js file).
var Cookie = function(name, hours, path, domain, secure) {
	this.$name = name;
	this.$expiration = (hours) ? new Date((new Date()).getTime() + hours*3600000) : null;
	this.$path = (path) ? path : null;
	this.$domain = (domain) ? domain : null;
	this.$secure = (secure) ? true : false;
	this.store = function() {
		var prop;
		var cookievalArray = [];
		for(prop in this){
			if((prop.charAt(0)!=='$') && (typeof this[prop]!=='function')) {
				cookievalArray.push( prop + ':' + escape(this[prop]) );
			}
		}
		var cookie = [ this.$name + '=' + cookievalArray.join('&') ];
		cookie.push( (this.$expiration) ? 'expires=' + this.$expiration.toGMTString() : '' );
		cookie.push( (this.$path)       ? 'path='    + this.$path                     : '' );
		cookie.push( (this.$domain)     ? 'domain='  + this.$domain                   : '' );
		cookie.push( (this.$secure)     ? 'secure'                                    : '' );
		document.cookie = cookie.join('; ');
	};
	this.load = function() {
		var i;
		var allcookies = document.cookie;
		if(allcookies==='') { return false; }
		var start = allcookies.indexOf(this.$name + '=');
		if(start===-1) { return false; }
		start += this.$name.length + 1;
		var end = (allcookies.indexOf(';',start)===-1)? allcookies.length : allcookies.indexOf(';',start);
		var cookieval = allcookies.substring(start,end);
		var a = cookieval.split('&');
		for(i=0; i<a.length; i++){
			a[i] = a[i].split(':');
			this[a[i][0]] = unescape(a[i][1]);
		}
		return true;
	};
	this.legacyLoad = function(c_name) {
		if (document.cookie.length>0) {
			c_start=document.cookie.indexOf(c_name + "=");
			if (c_start!=-1) {
				c_start=c_start + c_name.length+1;
				c_end=document.cookie.indexOf(";",c_start);
				if (c_end==-1) c_end=document.cookie.length;
				var val = unescape(document.cookie.substring(c_start,c_end));
				if(val) { this[c_name] = val; }
			}
		}
		return "";
	};
	this.remove = function() {
		var cookie = [this.$name + '='];
		if(this.$path)   { cookie.push( 'path=' + this.$path ); }
		if(this.$domain) { cookie.push( 'domain=' + this.$domain ); }
		cookie.push( 'expires=Fri, 02-Jan-1970 00:00:00 GMT' );
		document.cookie = cookie.join('; ');
	};
	this.clear = function() {
		var prop;
		for(prop in this){
			if((prop.charAt(0)!=='$') && (typeof this[prop]!=='function')) {
				delete this[prop];
			}
		}
	};
	
};

Now I know that you are using jQuery, we can frame things inside $(document).ready instead of onload...:

$(document).ready(function(){
	var cookie = new Cookie('profile', 24*365);
	cookie.legacyLoad('transfer_page');
	if(cookie.transfer_page) { cookie.store(); }
	cookie.load();

	var urls = {
		LA: 'indexLA.php',
		NY: 'indexNY.php',
		CHICAGO: 'indexCH.php',
		LONDON: 'indexLON.php'
	};
	var defpagename = "index.php";
	
	function redirectindexpage(dest) {
		cookie.transfer_page = dest;
		redirect(dest);
	}
	function redirect(transferpage) {
		window.location.href = urls[transferpage.toUpperCase()];
	}

	var transferpage = cookie.transfer_page;
	var pagename =  '{/literal} {$page_name}{literal}';
	if(pagename) { pagename = $.trim(pagename); }
	if(pagename === defpagename) {
		if(transferpage) {
			redirect(transferpage);
		}
		else {
			window.scroll(1,1);
			//document.getElementsByTagName('html')[0].style.overflow = 'hidden';
			document.getElementById('selpage').style.display='block';
			document.getElementById('fade_f').style.display='block';
			getPageSize();
		}
	}
	
	//Because redirect is framed within $(document).ready, we must attach the onclick handlers here rather than in HTML.
	$('.class="subbtn"').click(function(){
		var cityCode = $(this).val();
		cookie.transfer_page = cityCode;
		cookie.store();
		redirect(cityCode);
	});
	// The city buttons must now be as follows:
	// <button value="LA" class="subbtn">Los Angeles</button>
	// Note: It's now a <button>, onclick="..." is removed and value is now "LA"|"NY"|"CHICAGO"|"LONDON"
});

You may like to take the opportunity to (significantly) tidy up your pages.

As far as I can tell, the redirect code only needs to appear on the index page.

You will declutter the index page (and make it load faster) by putting the Cookie class in a separate .js file then include it on the page with another <script src="..."> tag.

Some of your original javascript (getCookie, checkCookie, redirectindexpage, and my onload function) is now redundant and can be deleted (after first backing up the page).

You should be able to move the $('#slider')... out of $(window).load(), into $(document).ready. That will further simplify things.

Make sure you test test test the cookie code before you deploy it. Having said that, the worst eventuality is that users' original city selection gets deleted and they have to select again - not disasterous like wiping out a whole user_profile.

Airshow

Hi Airshow,
Thank you so much for your help with all this.
This looks great. I've taken your advice and will link to an external cookie.js instead of including it in my header file. I totally agree that my code is a messy. I'll work on cleaning it up. I have noticed the pages taking a while to load.

Since this is for my banner ads, is there a way to make it so I can include my ad code $ads->getAdCode(1) without the visitor having to click?

The idea is to make it so just the banner ads that apply to that city appear automatically after referencing the cookie that was already set.
I apologize if I didn't make that clear before.

Also, the way you have this written now, is it supposed to replace my current cookie code for my city selector popup?

Thank you again for your time and advice.

Johnathan

Johnathan,

Since this is for my banner ads, is there a way to make it so I can include my ad code $ads->getAdCode(1) without the visitor having to click?

The idea is to make it so just the banner ads that apply to that city appear automatically after referencing the cookie that was already set.
I apologize if I didn't make that clear before.

It works the same way your original code was suposed to work. If user visits index page and no cookie is set, then it invites user to select a city then forwards to the appropriate city page with approapriate banner. If cookie is set, then it reads the cookie and forwards automatically.

It would be faster to load/run and maybe not significantly more difficult, to have a single index page (no forwarding) and to choose the appropriate banner dynamically. Further differences between the city pages could also be accommodated in a single page.

Typically, differences like this are handled in a single page server-side by eg. php, not client-side by javascript.

Also, the way you have this written now, is it supposed to replace my current cookie code for my city selector popup?

Yes. The code $('.class="subbtn"').click(function(){...}); at the bottom of the script gives the appropriate onclick functionality to the Los Angeles, New York etc. buttons. This includes storing the selected button's value in the cookie and forwarding to the appropriate page. You need to recompose the buttons as indicated in my code comment.

Airshow

Thank you again Airshow. I'll try implementing this code and see how it works. I really appreciate all your time and advice.

I'll let you know how it goes!
Thanks again,
Johnathan

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.