﻿/*
 INCLUDES
 **********************************************/
// specify which javascripts to include on the webpage
//js('/files/javascript/SCRIPTNAME.js');
js('/files/javascript/jquery.colorbox-min.js');
js('/files/javascript/jquery.autocomplete.min.js');
js('/files/javascript/jquery.cycle.all.min.js');
js('/files/javascript/jquery.ba-bbq.min.js');



// groupsmenu ajax funktionality
// version: 1.0 - 2010-05-12
(function($){

	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.groupsmenuAjax = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.groupsmenuAjax.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
		
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $(this).metadata()) : opts;
			
			// add the correct classes based on which submenus are open and closed when the plugin is called
			$(this).find('ul.' + o.closedClass).prev().addClass(o.closedClass);
			$(this).find('ul.' + o.openClass).prev().addClass(o.openClass);
			
			// dynamisk aktivering af klik på elementerne
			$(this).find('.' + o.hasSubmenuClass + ' > a').live('click', function(e){
			
				var $this = $(this);
				
				if ($this.next().size() > 0) {
					// there is already a submenu, so lets just work with that
					
					if ($this.hasClass('closed')) {
						// when the item is closed, open it and close all the other open menus
						$this.removeClass(o.closedClass).addClass(o.openClass).next().slideDown('fast').parent().siblings().find('ul').slideUp().prev().removeClass(o.openClass).addClass(o.closedClass);
					}
					else {
						// when the item is open, close it
						$this.removeClass(o.openClass).addClass(o.closedClass).next().slideUp('fast');
					}
				}
				else {
					// there is not a submenu yet, so fetch the correct submenu with Ajax
					
					// give feedback to the user, that we are working on getting the submenu
					$('<img class="preloader" src="' + o.preloaderImage + '" alt=""/>').insertAfter($this).fadeIn('fast');
					
					// fetch the submenu
					$.ajax({
						url: '/dynamic.aspx?data=groups&template=groupsmenu_ajax&ajaxmode=1',
						data: {
							key: $this.metadata().menuid
						},
						success: function(data){
							// add a "open" class to the link, remove the preloader image and insert the new list of menuitems after the link
							
							$this.addClass(o.openClass).next('img').fadeOut('fast', function(){
								$(this).remove();
							}).end().after(data).next().slideDown('fast');
						}
					});
				}
				
				// remove focus from the clicked link and cancel the normal click event
				$this.blur();
				e.preventDefault();
				//return false;
				
			});
		});
	}
	
	// default values for the options
	$.fn.groupsmenuAjax.defaults = {
		hasSubmenuClass: 'hasSubmenu',
		openClass: 'open',
		closedClass: 'closed',
		preloaderImage: '/images/preload_16x16.gif'
	};
	
})(jQuery);



// horizontal main menu - suckerfish style drop down
// version: 1.0 - 2010-05-14
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.menuFades = function(options){
	
		// activate the script for each instans found in the selector
		return this.each(function(){
		
			$(this).find('li').hoverIntent(function(){
				// on mouseover
				$('ul:first', this).fadeIn('fast');
			}, function(){
				// on mouseout
				$('ul:first', this).fadeOut('fast');
			});
			
		});
	}
	
})(jQuery);



// add and subtract quantity fields.
// version: 1.1 - 2010-07-22
(function($){

	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.quantityAddSubtract = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.quantityAddSubtract.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			if ($this.hasClass('quantityButtonsAttached') == false){
				
				$this.addClass('quantityButtonsAttached');
				
				// insert a - (subtract) button
				$('<img/>', {
					'class': o.subtractClass,
					'src': o.subtractImage,
					'alt': '',
					click: function(){
						var floatValue = round_float($this.val(), 2);
						var floatNewVal = floatValue - o.step;
						var floatMinVal = round_float($this.closest('form').find('input[name="min_quantity"]').val(), 2);
						
						if (floatNewVal < floatMinVal) {
							$this.val(floatMinVal);
						}
						else if (floatNewVal < o.step) {
							$this.val(o.step);
						}
						else {
							$this.val(floatNewVal);
						}
					}
				}).insertBefore($this);
				
				// insert a + (add) button
				$('<img/>', {
					'class': o.addClass,
					'src': o.addImage,
					'alt': '',
					click: function(){
						var floatValue = round_float($this.val(), 2);
						var floatNewVal = floatValue + o.step;
						$this.val(floatNewVal);
					}
				}).insertAfter($this);
				
				// when the user removes the focus from the field, check the content
				$this.blur(function(){
					var qtycolli = parseFloat(o.step);
					var quantity = parseFloat($this.val().toString().replace(',', '.'));
					
					// check if colliMessage is defined. If it is, give the user this message, else give the standard danish message 
					var messageText = (typeof colliMessage != 'undefined') ? colliMessage : 'Antallet passer ikke med en hel pakning og er blevet justeret.';
					
					if (isNaN(quantity)) {
						$this.val('');
					}
					else {
						$this.val(quantity);
					}
					
					// show a message to the user
					if (qtycolli > 1 && quantity > 0 && round_float(quantity % qtycolli, 2) > 0) {
						$this.val(round_float(Math.ceil(quantity / qtycolli) * qtycolli, 2));
						$this.after('<div class="' + o.messageClass + '"><div>' + messageText + '</div></div>');
						$this.parent().find('.' + o.messageClass).fadeIn('slow', function(){
							window.setTimeout("$('." + o.messageClass + "').fadeOut('slow',function(){ $(this).remove(); })", 5000);
						});
					}
				});
			
			}
		});
	}
	
	// default values for the options
	$.fn.quantityAddSubtract.defaults = {
		addClass: 'jsQuantityAdd',
		addImage: '/images/btn_plus.gif',
		subtractClass: 'jsQuantitySubtract',
		subtractImage: '/images/btn_minus.gif',
		step: 1,
		messageClass: 'jsMessage'
	};
	
})(jQuery);



// jQuery plugin to replace the text in input fields on focus/blur or replace entire password field
// version: 1.0 - 2010-05-14 
(function($){
	$.fn.toggleInputText = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.toggleInputText.defaults, options);
		
		return ($(this).each(function(){
			var $this = $(this);
			title = $this.attr('title');
			
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			if ($this.attr('type') == 'password') {
				// password field specific replacement
				
				var fakePassword = $('<input/>', {
					'class': $this.attr('class') + ' fakePassword',
					'value': $this.attr('title'),
					'type': 'text',
					css: {
						display: 'none'
					},
					focus: function(){
						$(this).hide();
						$this.show().focus();
					}
				});
				
				$this.after(fakePassword).blur(function(){
					if ($this.val() == "") {
						$this.hide().next('.fakePassword').show();
					};
									});
				
				if ($this.val() == "") {
					$this.hide().next('.fakePassword').show();
				};
							}
			else {
				// toggle values
				if ($this.val() == "") {
					$this.val(title);
				};
				$this.focus(function(){
					if ($this.val() == $this.attr('title')) {
						$this.val("");
					};
									}).blur(function(){
					if ($this.val() == "") {
						$this.val($this.attr('title'));
					};
									});
			}
			
			// hide the labels if the option is set to true
			if (o.hideLabels && $this.attr('id') != '') {
				$this.closest('form').find('label[for="' + $this.attr('id') + '"]').hide();
			}
			
		}));
	};
	
	// default values for the options
	$.fn.toggleInputText.defaults = {
		hideLabels: true
	};
	
})(jQuery);



// show the item specified in the href and hide what is specified in the options 
// version: 1.0 - 2010-05-12
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.setActiveBox = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.setActiveBox.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			$this.click(function(){
				// show the specified element
				$($this.attr('href')).show();
				
				// if hideSelector is set, hide the elements in the selector
				if (o.hideSelector != null) {
					$(o.hideSelector).hide();
				}

				// stop the click on the link
				return false;
			})
		});
	}
	
	// default values for the options
	$.fn.setActiveBox.defaults = {
		hideSelector: null
	};
	
})(jQuery);



// beskrivelse
// version: 1.0 - 2010-05-12
(function($){
// TODO:
//		Lav dokumentation til hvordan plugin'et bliver brugt

	$.fn.sendAjaxPost = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.sendAjaxPost.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			$this.click(function(){
				$.ajax({
					url: '/post.aspx?ajaxmode=1',
					type: 'post',
					data: o.data
				});
				
				if (o.after){
					o.after($this);
				}

				
				return false;
				
			});
		});
	}

	// default values for the options
	$.fn.sendAjaxPost.defaults = {
		data: null,
		after: null
	};

})(jQuery);



// use history.back if the history is present, else fallback to the link.
// version: 1.0 - 2010-05-27
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.historyBack = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.historyBack.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			$this.click(function(){
				if (history.length > 1){
					// there is a history in the browser
					history.back();
					return false;
				}
				else {
					// there is not a history in the browser
					// let the link work as a normal link
				}
			});
				
		});
	}
	
	// default values for the options
	$.fn.historyBack.defaults = {
		option: 'value'
	};

})(jQuery);



// check if the specified logininfo actually returns a user
// version: 1.0 - 2010-05-28
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.checkLogin = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.checkLogin.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// check if a user exists with the specified login. If not, throw an error 
			$this.bind('submit.checklogin',function(){
				var strEmail = $('input[name="Email"]',this).val(),
						strPass = $('input[name="Password"]',this).val();
			  
				// create the data object and fill it with data
				var objData = new Object();
				
				if (o.ajaxData){
					// ajaxData contains data, so we fill it into the objData object
					objData = o.ajaxData;
				}
				else {
					// ajaxData is null, so we fill objData with as good data as possible from the visible text/password fields in the form
					$this.find(':text:visible[name],:password:visible[name]').each(function(){
						objData[$(this).attr('name')] = $(this).val();
					});
				}
				
				$.ajax({
					url: '/dynamic.aspx?data=checklogin&ajaxmode=1',
					data: objData,
					success: function(data){
						if (data == '||') {
							// there's no login with those info, so we alert the user and stops the login form
							$this.find('.error').show();
							return false
						}
						else {
							// hide the error, if it's shown and remove the checklogin check (this one) and submit the form normally
							$this.find('.error').hide().end().unbind('submit.checklogin').submit();
						}
					}
				});
				
				// cancel the regular submit function
				return false;
			});
		});
	}
	
	// default values for the options
	$.fn.checkLogin.defaults = {
		ajaxData: null
	};

})(jQuery);



// activate paging on productlistpaging via ajax 
// version: 1.1 - 2010-07-22
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	// global variables for all functions
	var $container;
	
	$.fn.ajaxProductlistpaging = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.ajaxProductlistpaging.defaults, options);
		
		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// find out which page we are on
			var strActivePage = '1';
			if (location.href.match(o.curpageRegExMatch)) {
				strActivePage = location.href.match(o.curpageRegExMatch)[1];
			} 
			
			// wrap the "current page" productlist and actions in a container, a track and a page container
			$this.find(o.productlistGroupSelector)
				.wrapAll('<div class="' + o.containerId + '"/>')
				.wrapAll('<div class="' + o.trackId + '"/>')
				.wrapAll('<div class="' + o.pageIdPrefix + strActivePage + ' ' + o.pageClass + '"/>');
			
			$container = $('.' + o.containerId,$this);
			
			// give the container some styles, so the pages can move inside this as on a "track"
			$container.css({
				position: 'relative',
				width: $container.width() + 'px',
				height: $container.height() + 'px',
				overflow: 'hidden'
			});
			
			$('.' + o.pageIdPrefix + strActivePage,$this).css({
				position: 'absolute',
				top: 0,
				left: $container.width() * (parseInt(strActivePage) - 1) + 'px',
				width: $container.width() + 'px',
				height: $container.height() + 'px'
			});
			
			$('.' + o.trackId,$this).css({
				position: 'absolute',
				top: 0,
				left: '-' + $container.width() * (parseInt(strActivePage) - 1) + 'px'
			});
			
			
			// find out if the user requests a page via the location.hash
			if (location.hash.indexOf(o.hashPrefix) > -1) {
				var strHashPage = parseInt(location.hash.replace('#' + o.hashPrefix,''));
				
				if (strHashPage != strActivePage ){
					
					// decide which key/value to use (searchtext or key) and whether or not jQuery BBQ have been used
					var strKeyset;
					if (typeof $.bbq.getState() != 'undefined' && location.href.match(o.searchtextRegExMatch)){
						// find the search parameter in the jQuery BBQ plugin
						strKeyset = 'searchtext=' + $.bbq.getState().site.match(o.searchtextRegExMatch)[1];
					}
					else if (typeof $.bbq.getState() != 'undefined'){
						// find the second key parameter in the jQuery BBQ plugin
						strKeyset = 'key=' + $.bbq.getState().site.match(o.keyRegExMatch)[1];
					}
					else if (location.href.match(o.searchtextRegExMatch)) {
						// find the search parameter in the HREF eg. "test" in /productlistpaging/?searchtext=test&paging=1&curpage=2
						strKeyset = 'searchtext=' + location.href.match(o.searchtextRegExMatch)[1];
					} else {
						// find the second parameter in the HREF eg. "test group" in /productlistpaging/test group/?paging=1&curpage=2
						strKeyset = 'key=' + location.pathname.match(o.keyRegExMatch)[1];
					}
					
					var strHashPageUrl = '/dynamic.aspx?data=products&' + strKeyset + '&paging=1&curpage=' + strHashPage;
					getPage(strHashPageUrl, strHashPage, o, $this);
				}
			}

			
			$this.find(o.pagingLinkSelector).live('click',function(){
				// make a new url
				var strUrl = $(this).attr('href');
				var objCurPage = strUrl.match(o.curpageRegExMatch); // find the current page in the HREF
				
				var strCurpage = '1';
				if (objCurPage){
					strCurpage = objCurPage[1];
				}
				
				// set the hash in the URL for when links are sent by mail or in other ways
				location.hash = o.hashPrefix + strCurpage;
				
				if ($('.' + o.pageIdPrefix + strCurpage,$this).size() > 0){
					// the page already exists
					
					
					$('.'+ o.trackId,$this).animate({
						left: ($('.' + o.pageIdPrefix + strCurpage,$this).position().left * -1) + 'px'
					},'slow');
					
				} else {
					// the page did not exist 
				
					//var objKey = strUrl.match(o.keyRegExMatch); // find the second parameter in the HREF eg. "test group" in /productlistpaging/test group/?paging=1&curpage=2
					
					
					// decide which key/value to use (searchtext or key)
					var strKeyset2;
					if (strUrl.match(o.searchtextRegExMatch)) {
						// find the search parameter in the HREF eg. "test" in /productlistpaging/?searchtext=test&paging=1&curpage=2
						strKeyset2 = 'searchtext=' + strUrl.match(o.searchtextRegExMatch)[1];
					} else {
						// find the second parameter in the HREF eg. "test group" in /productlistpaging/test group/?paging=1&curpage=2
						strKeyset2 = 'key=' + strUrl.match(o.keyRegExMatch)[1];
					}
					
					var strDynamicurl = '/dynamic.aspx?data=products&' + strKeyset2 + '&paging=1&curpage=' + strCurpage;
					
					activatePagePreloader();
					getPage(strDynamicurl, strCurpage, o, $this);
				}
				
				// cancel the normal click event
				return false;
			});
			
		});
	}
	
	function getPage(strUrl,strPageId,o,pageContainer){
		/*
		console.log(strUrl);
		console.log(strPageId);
		console.log(o);
		console.log(pageContainer);
		*/
		
		$.get(strUrl,function(data){
			// find the body element  
			var startCut = data.indexOf('<body');
			var endCut = data.indexOf('</body>') + 7;
			
			// if the new page has content, insert it and scroll to it
			if ($(data.substring(startCut, endCut)).find(o.productlistGroupSelector).size() > 1) {
				$('.'+ o.trackId, pageContainer).append('<div class="' + o.pageIdPrefix + strPageId + ' ' + o.pageClass + '"/>');
				
				$('.' + o.pageIdPrefix + strPageId, pageContainer).css({
					position: 'absolute',
					left: ($container.width() * (strPageId - 1)) + 'px',
					top: 0,
					width: $container.width() + 'px',
					height: $container.height() + 'px',
					overflow: 'hidden'
				}).html($(data.substring(startCut, endCut)).find(o.productlistGroupSelector));
				
				if (o.beforeAjaxAnimation) {
					o.beforeAjaxAnimation();
				}
				
				// hide the page preloader
				deActivatePagePreloader();
				
				$('.'+ o.trackId, pageContainer).animate({
					left: ($('.' + o.pageIdPrefix + strPageId, pageContainer).position().left * -1) + 'px'
				}, 'slow');
				
				if (o.afterAjaxAnimation) {
					o.afterAjaxAnimation();
				}

			}
		});
	}
	
	// default values for the options
	$.fn.ajaxProductlistpaging.defaults = {
		containerId: 'productlistpaging-ajax-container',
		trackId: 'productlistpaging-ajax-track',
		pageIdPrefix: 'productlistpaging-ajax-page',
		pageClass: 'productlistpaging-ajax-page',
		hashPrefix: 'page',
		productlistGroupSelector: '.productlistActions,.productlist',
		pagingLinkSelector: '.productlistPaging a',
		curpageRegExMatch: /curpage=(\d+)/i,
		keyRegExMatch: /\/[^\/]+\/(.+)\//i,
		searchtextRegExMatch: /searchtext=([^&]+)/i,
		beforeAjaxAnimation: null,
		afterAjaxAnimation: null
	};
})(jQuery);



 // GLS lookup
 // version: 1.0 - 2010-06-09
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt
	
	$.fn.glsLookup = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.glsLookup.defaults, options);
		
		// activate the script for each instance found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// when selecting a GLS shop, update the input values
			$(o.glsContainer + ' :radio').live('click',function(){
				$(o.glsShopName).val($(this).metadata().name);
				$(o.glsShopAddress).val($(this).metadata().address);
			});
			
			// when selecting a shippingtype, toggle the glsData depending on whether useGLS is set or not
			$(o.shippingtypesContainer + ' :radio').click(function(){
				
				if ($(this).metadata().useGLS == true){
					$(o.glsContainer).fadeIn();
				} else {
					$(o.glsContainer).fadeOut();
				}
			});
			
			// set basic values for street postalcode and country
			var strStreet = $(o.street).val();
			var strPostalcode = $(o.postalcode).val();
			var strCountry = $(o.country).val();
			
			// if an alternate delivery address is chosen, replace the previous values with these 
			if ($(o.postalcode2).size() > 0 && $(o.postalcode2).val() != '') {
				strStreet = $(o.street2).val();
				strPostalcode = $(o.postalcode2).val();
				strCountry = $(o.country2).val();
			}
			
			// do an ajax request to the server
			if (strPostalcode != '') {
				$.ajax({
					url: "/dynamic.aspx?data=glsdelivery&ajaxmode=1",
					data: {
						street: strStreet,
						postalcode: strPostalcode,
						country: strCountry
					},
					success: function(data){
						if (data != '') {
							// replace the old GLS data with new
							$(o.glsContainer).html(data);
						}
						else {
							$(o.glsContainer).empty('');
						}
						
						// click the checked radiobutton so it saves data
						$(o.glsContainer).find(':radio:checked').click();
					}
				});
			}
		});
	}

	
	// default values for the options
	$.fn.glsLookup.defaults = {
		glsContainer: '#jsGlsdata',
		postalcode: '#addrPostalcode',
		street: '#addrStreet',
		country: '#addrCountry',
		postalcode2: '#addrPostalcode2',
		street2: '#addrStreet2',
		country2: '#addrCountry2',
		glsShopName: '#glsShopName',
		glsShopAddress: '#glsShopAddress',
		shippingtypesContainer: '#shippingtypes'
	};

})(jQuery);


/*
function singleLookup(){
		var objForm = $(this).closest('form').get(0);
*/	
		/*
		var strStreet = o.street ? o.street.val() : objForm.street.value;
		var strPostalcode = o.postalcode ? o.postalcode.val() : objForm.postalcode.value;
		var strCountry = o.country ? o.country.val() : objForm.country.value;
		*/
		
		/*
		var strStreet = o.street.val();
		var strPostalcode = o.postalcode.val();
		var strCountry = o.country.val();
		*/
		
		/*
		var strStreet = objForm.street.value;
		var strPostalcode = objForm.postalcode.value;
		*/
		
		/*
		if (objForm.postalcode2 || o.postalcode2) {
			if (objForm.postalcode2.value != '' || o.postalcode2) {
				strStreet = o.street2 ? o.street2.val() : objForm.street2.value;
				strPostalcode = o.postalcode2 ? o.postalcode2.val() : objForm.postalcode2.value;
				strCountry = o.country2 ? o.country2.val() : objForm.country2.value;
				
			}
		}
		*/
/*		
		if (strPostalcode != '') {
		
			$.get("dynamic.aspx?data=glsdelivery&ajaxmode=1", {
				street: strStreet,
				postalcode: strPostalcode,
				country: strCountry
			}, function(data){
			
				if (data != '') {
					// replace the old GLS data with new
					$(o.glsContainer).replaceWith(data);
				}
				else {
					$(o.glsContainer).empty('');
				}
				
				$(o.glsContainer).find(':radio:checked').click();
				
			}, 'html');
			
		}
	}
*/


// read out RSS and Atom feeds
// dependent on the jQuery plugin getFeed
// version: 1.0 - 2010-07-28
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt

	$.fn.readFeed = function(options){

		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.readFeed.defaults, options);

		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this)
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			if (o.feed){
				
				if (o.feed.match('http://') == null){
					o.feed = 'http://' + o.feed;
				}
				o.feed = '/proxy.aspx?datatype=xml&url=' + o.feed;
				
				$.getFeed({
					url: o.feed,
					success: function(feed){
						if (feed.image){
							$this.append('<a href="' + feed.image.link + '"><img src="' + feed.image.url + '" alt="' + feed.image.title + '"/></a>');
						}
						$this.append('<h2><a href="' + feed.link + '">' + feed.title + '</a></h2><h3>' + feed.description + '</h3>');
						var html = '';
						for(var i = 0; i < feed.items.length && i < 5; i++) {
							var item = feed.items[i];
							html += '<h3><a href="' + item.link + '">' + item.title + '</a></h3>';
							html += '<div class="updated">' + item.updated + '</div>';
							html += '<div class="description">' + item.description + '</div>';
						}
						$this.append(html);
					}
				});
				
			}
			
		});
	}

	// default values for the options
	$.fn.readFeed.defaults = {
		feed: false
	};

})(jQuery);


/*
 // Standard jQuery plugin opbygning
 // --------------------------------
 // beskrivelse
 // version: 1.0 - 2010-06-09
 (function($){
 // TODO:
 //		Lav dokumentation til hvordan plugin'et bliver brugt
 
 $.fn.FUNKTIONSNAVN = function(options){
 
 // create the options object with data from the default options and the user specified options
 var opts = $.extend({}, $.fn.FUNKTIONSNAVN.defaults, options);
 
 // activate the script for each instans found in the selector
 return this.each(function(){
 var $this = $(this);
 // build element specific options
 var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
 
 
 });
 }
 
 // default values for the options
 $.fn.FUNKTIONSNAVN.defaults = {
 option: 'value'
 };
 
 })(jQuery);
*/


// round floats up / down
function round_float(x, n){
	if (!parseInt(n)) var n = 0;
	if (!parseFloat(x)) 		
		return false;
	return Math.round(x * Math.pow(10, n)) / Math.pow(10, n);
}


// NY activate ajax shopping - skal kopieres over i korrekt javascript fil, når den er færdig og gennemtestet.
function activateAjaxShopping_NEW(objArg){

	/* 
	 * ajaxMode (default = false)             : defines whether or not ajaxMode is being used in the querystring
	 * target (default = '.basketpreview')    : selector string to the element which should be replaced with the content
	 * find (default = '.basketpreview')      : selector string to find a specific element inside the collected data
	 *
	 * if no arguments are passed, default values are set
	 */
	objArg = (typeof objArg == 'undefined') ? new Object : objArg;
	objArg.ajaxMode = (typeof objArg.ajaxMode == 'undefined') ? false : objArg.ajaxMode;
	objArg.target = (typeof objArg.target == 'undefined') ? '.basketpreview' : objArg.target;
	objArg.find = (typeof objArg.find == 'undefined') ? '.basketpreview' : objArg.find;
	
	var strAjaxMode = '';
	if (objArg.ajaxMode) {
		strAjaxMode = '&ajaxmode=1'; // call the page with ajaxmode = 1 
	}

	// remove products from basket and update basket preview
	$('.basketpreview input').live('click', function(){
		$(this).closest('form').submit(function(){
			$.post('/post.aspx', {
				_Function: this._Function.value,
				_ReturnTo: '/dynamic.aspx?data=basket&template=basketpreview' + strAjaxMode,
				productid: this.productid.value,
				quantity: this.quantity.value,
				pkid: this.pkid.value
			}, function(data){
			
				var $content = '';
				
				if (objArg.ajaxMode) {
				
					$content = $(data).filter(objArg.find);
					
				}
				else {
				
					// find the body element  
					var startCut = data.indexOf('<body');
					var endCut = data.indexOf('</body>') + 7;
					
					var $content = $(data.substring(startCut, endCut));
					
				}
				
				// replace the target with the new content
				$(objArg.target).replaceWith($content);
				
			}, 'html');
			
			// cancel the normal form submit
			return false;
		});
	});
	

	// add products to basket and update basketpreview
	$('form.jsUpdateBasket').live('submit',function(){
		var strAlert;
		
		// cancel the Ajax call, if some values are missing
		if (this.productid.value == '' || this.quantity.value == '') {
		
			strAlert = (typeof strErrorFieldRequired == 'undefined') ? 'Udfyld alle n\u00F8dvendige felter' : strErrorFieldRequired;
			
			modalAlert(strAlert);
			return false;
		}
		
		// cancel the Ajax call, if the quantity is less than minimum quantity
		if (parseInt(this.min_quantity.value) > parseInt(this.quantity.value)) {
		
			strAlert = (typeof strErrorOrderMinimum == 'undefined') ? 'Du skal bestille minimum' : strErrorOrderMinimum;
			var strAlertPcs = (typeof strErrorOrderMinimumPcs == 'undefined') ? 'stk.' : strErrorOrderMinimumPcs;
			
			modalAlert(strAlert + ' ' + this.min_quantity.value + ' ' + strAlertPcs);
			return false;
		}
		
		
		$.post("/post.aspx", {
			_Function: this._Function.value,
			_ReturnTo: '/dynamic.aspx?data=basket&template=basketpreview' + strAjaxMode,
			productid: this.productid.value,
			quantity: this.quantity.value
		}, function(data){
		
			var $content = '';
			
			if (objArg.ajaxMode) {
				$content = $(data).filter(objArg.find);
			}
			else {
			
				// find the body element  
				var startCut = data.indexOf('<body');
				var endCut = data.indexOf('</body>') + 7;
				
				var $content = $(data.substring(startCut, endCut));
				
			}
			
			// replace the target with the new content
			$(objArg.target).replaceWith($content);
			
		}, 'html');
		
		
		// this is used to show that the form have been sent to the server and the basket have been updated  
		$('.added', this).fadeIn(100, function(a){
			setTimeout(function(){
				$('.added').fadeOut('slow');
			}, 2000)
		});
		
		// cancel the normal form submit
		return false;
	});

	// hack to make Internet Explorer respect the live event on the forms (it could otherwise just use the browser default action)
	$('form.jsUpdateBasket :submit, form.jsUpdateBasket :image').live('click',function(){
		$(this).closest('form').submit();
		return false;
	});
}

// GiftWrapping
function GiftWrapping()
{
	$('.inpWrapping').live('click', function() {
			var that = $(this);
			var pkid = $(this).attr('name').substring(8);
			activatePagePreloader();
			
			if ($(this).is(':checked'))
			{
				var params = {};
				params[encodeURI('pkid')] = pkid;
				params[encodeURI('productid')] = $('#update' + pkid).find('input[name=productid]').val();
				params[encodeURI('quantity')] = $('input[name=quantity' + pkid + ']').val();
				params[encodeURI('@wrapping')] = 1;
				params[encodeURI('_Function')] = 'UpdateBasket';
				params[encodeURI('_ReturnTo')] = '/dynamic.aspx?data=basket';
				
				$.post("/post.aspx", params,
				function(data){
					//alert('CHECKED: ' + pkid);
					$('#siteMain').html(data);
				}, 'html');
			}
			else
			{
				var params = {};
				params[encodeURI('pkid')] = pkid;
				params[encodeURI('productid')] = $('#update' + pkid).find('input[name=productid]').val();
				params[encodeURI('quantity')] = $('input[name=quantity' + pkid + ']').val();
				params[encodeURI('@wrapping')] = 0;
				params[encodeURI('_Function')] = 'UpdateBasket';
				params[encodeURI('_ReturnTo')] = '/dynamic.aspx?data=basket';
				
				$.post("/post.aspx", params,
				function(data){
					//alert('UNCHECKED: ' + pkid);
					$('#siteMain').html(data);
				}, 'html');
			}
			
			deActivatePagePreloader();
		});
	//});
}

/*
 ON LOAD
 *********************************************/
// jQuery 'onReady' script - runs when the document have been loaded, but before images
$(function(){
	//validateForms();
	
	activateAjaxShopping_NEW({
		ajaxMode: true
	});
	
	$('form').formvalidation();
	
	autocompletePostalCode3('#tDelivery #addrPostalcode', '#tDelivery #addrCity', '#tDelivery #addrCountry');
	autocompletePostalCode3('#tDelivery #addrPostalcode2', '#tDelivery #addrCity2', '#tDelivery #addrCountry2');
	autocompletePostalCode3('#tCreatecustomer #customerPostalcode', '#tCreatecustomer #customerCity', '#tCreatecustomer #customerCountry');
	
	productlistImage();
	postPolls();
	quizWizzard();
	tracktrace();
	changeProductImage();
	flashLoad();
	openPopups();
	GiftWrapping();
	//showInlineHelp();
	//variantSelection();
	
	// when changing sort method on productlistpaging, submit the sorting form
	$('#siteMain').delegate('.productlistSorting select', 'change', function(){
		$(this).closest('form').submit();
	});
	
	$('.tProducts').ajaxProductlistpaging({
		beforeAjaxAnimation: function(){
			$('.jsQuantity').quantityAddSubtract();
		}
	});
	
	
	$('#mainMenu').menuFades();
	$('#areaMenu').groupsmenuAjax();
	$('.jsQuantity').quantityAddSubtract();
	$('.jsInput').toggleInputText();
	$('.jsShowForgotPwd, .jsShowLogin').setActiveBox();
	$('.jsGoBack').historyBack();
	$('#menuLoginForm form, #siteLoginForm form').checkLogin();
	$('#tPayment').glsLookup();
	$('.rssFeed').readFeed();
	
	
	// toggle optional delivery address
	$('#addrOptionalDelivery').click(function(){
		if (this.checked){
			$('#tDelivery').find('.secondaryAddress .secondaryAddresinput').removeAttr('disabled');
			$('#tDelivery').find('.secondaryAddress').show();
		} else {
			$('#tDelivery').find('.secondaryAddress .secondaryAddresinput').attr('disabled','disabled');
			$('#tDelivery').find('.secondaryAddress').hide();
		}
	});
	$('#tDelivery').find('.secondaryAddress:hidden .secondaryAddresinput').attr('disabled','disabled');

	
	// tests if the terms are accepted on the orderstatus page before going on
	$('#tOrderstatus').find('form').submit(function(){
		if ($('#TermsAccepted').is(':checked') == false){
			var strAlert = typeof strAcceptTermsError == 'undefined' ? 'Du skal acceptere handelsbetingelserne' : strAcceptTermsError;
			alert(strAlert);
			return false;
		}
	});
	
	// when user wants to unsubscribe the newsletter, fill out the correct form and submit it
	$('#tNewssignup').find('.cancelSubscription').click(function(){
		var objForm = $('#newsletterCancelSubscription');
		objForm.get(0).email.value = $('#newslettersubscribeEmail').val();
		objForm.submit();
	});
	
	// show/hide the menuLogin container, based on the class
	$('#menuLogin>a').click(function(){
		$(this).blur().parent().toggleClass('itemLoginActive');
		return false;
	});
	
	// add/remove product to/from wishlist
	$('.productLinkwishlist').not('.productLinkwishlistRemove').sendAjaxPost({
		after: function(){ $('.productLinkwishlist').toggle(); }
	});
	$('.productLinkwishlistRemove').sendAjaxPost({
		after: function(){ $('.productLinkwishlist').toggle(); }
	});
	
	// add/remove product to/from favorites
	$('.productLinkfavorites').not('.productLinkfavoritesRemove').sendAjaxPost({
		after: function(){ $('.productLinkfavorites').toggle(); }
	});
	$('.productLinkfavoritesRemove').sendAjaxPost({
		after: function(){ $('.productLinkfavorites').toggle(); }
	});
	
	// add lightbox/colorbox functionality to shoppinglist links
	$('.productLinkshoppinglist').colorbox({
		onComplete: function(){
			$('#tUpdateshoppinglist .jsQuantity').quantityAddSubtract();
			$('#tUpdateshoppinglist .jsInput').toggleInputText();
			$('#tUpdateshoppinglist').find('form').ajaxForm({
				success: function(data){
					$(document).one('cbox_closed',function(){
						$.fn.colorbox({
							html: data
						});
					});
					$.fn.colorbox.close();
				}
			})
		}
	});
	
	// add lightbox/colorbox functionality to tip a friend links
	$('.productLinktipafriend').colorbox({
		onComplete: function(){
			$('#tTipafriend .jsInput').toggleInputText();
			$.fn.colorbox.resize();
			$('#tTipafriend').find('form').formvalidation().ajaxForm({
				beforeSubmit: function(formData, jqForm, options){
					if (jqForm.data('allOk') == 0){
						return false;
					}
				},
				success: function(data){
					$(document).one('cbox_closed',function(){
						$.fn.colorbox({
							html: data
						});
					});
					$.fn.colorbox.close();
				}
			})
		}
	});
	
	// add lightbox/colorbox functionality to print links
	$('.productLinkprint').colorbox({
		iframe: true,
		width:700,
		height:'80%'
	});
	
	
	
	
	// standard lightbox feature for productinfo page - building the container
	updateProductImagesLightbox();
	
	// standard lightbox feature for productinfo page - activating the overlay
	$('#productImages a').colorbox({
		inline: true,
		href: '#productImagesLightbox',
		onOpen: function(){
			$('#productImagesLightbox').find('.imageContainer img[src$="' + escape($(this).attr('href')) + '"]:first').show().siblings('img').hide();
			$('#productImagesLightbox').find('.productImageActions').html($('#productAdditions').children().clone(true));
		},
		onComplete: function(){
			$('#productImagesLightbox').find('.imageContainer').css({
				height: $('#productImagesLightbox').find('.imageContainer').height()
			});
			
			if ($('#productImagesLightbox').find('.imageContainer img').size() > 1) {
				updateLightboxButtons();
				
				$('#productImagesLightbox').find('.imageContainer .lightboxNavigation').click(function(){
					$this = $(this);
					$img = $this.siblings('img:visible');
					
					if ($img.siblings('img').size() > 0) {
						if ($img.next('img').size() > 0 && $this.hasClass('next')) {
							$img.fadeOut('fast', function(){
								$img.next('img').fadeIn('slow');
								updateLightboxButtons();
							});
						}
						else if ($img.prev('img').size() > 0 && $this.hasClass('prev')) {
							$img.fadeOut('fast', function(){
								$img.prev('img').fadeIn('slow');
								updateLightboxButtons();
							});
						}
					}
				});
			}
			else {
				$('#productImagesLightbox').find('.imageContainer .lightboxNavigation').hide();
			}			
		}
	});
	
	
	
	// delete from basket
	$('#tBasket').find('.jsDelete').live('click',function(){
		$($(this).attr('href')).ajaxSubmit({
			beforeSubmit: activatePagePreloader,
			success: function(data){
				// find the body element  
				var startCut = data.indexOf('<body');
				var endCut = data.indexOf('</body>') + 7;
				
				var $content = $(data.substring(startCut, endCut));
				$('#tBasket').replaceWith($content);
				
			}
		});
		return false;
	});
	
	// update quantity in basket
	$('#tBasket').find('.quantity input').live('change',function(){
		var strPkid = $(this).attr('name').replace('quantity',''),
				intValue = $(this).val();
		
		$('#update' + strPkid).get(0).quantity.value = intValue;
		
		$('#update' + strPkid).ajaxSubmit({
			beforeSubmit: activatePagePreloader,
			success: function(data){
				// find the body element  
				var startCut = data.indexOf('<body');
				var endCut = data.indexOf('</body>') + 7;
				
				var $content = $(data.substring(startCut, endCut));
				$('#tBasket').replaceWith($content);
				
			}
		});
		return false;
	});
	
	$('#tBasket').find('#basketWrapping').live('click',function(){
		$(this).closest('form').ajaxSubmit();
	});
	
	// toggle the visibility of the optional delivery form
	$('.jsOptionalDelivery').click(function(){
		var $this = $(this);
		
		if ($this.attr('checked')){
			$('.secondaryAddress').show();
		} else {
			$('.secondaryAddress').hide();
		}
	});
	
	
	// empty city and postalcode input fields, when changing country 
	$('#tDelivery').find(':input[name=country]').change(function(){
		$('#tDelivery').find(':input[name=city], :input[name=postalcode]').val('');
		$('#addrPostalcode').flushCache();
	})
	.end().find(':input[name=country],:input[name=country2]').change(function(){
		$('#tDelivery').find(':input[name=city2], :input[name=postalcode2]').val('');
		$('#addrPostalcode2').flushCache();
	});
	
	
	
	// ajax submitting the subscribe newsletter form
	$('#newsletterSubscription').ajaxForm({
		beforeSubmit: function(formData, jqForm, options){
			if (jqForm.data('allOk') == 0){
				return false;
			}
			$('#newsletterSubscription').find('.preloader').fadeIn('fast');
		},
		success: function(){
			$('#newsletterSubscription').find('.preloader').hide();
			$('#newsletterSignupSuccess').fadeIn('fast', function(){
				setTimeout("$('#newsletterSignupSuccess').fadeOut('fast')",5000);
			});
			
		}
	});
	
	// ajax submitting the unsubscribe newsletter form
	$('#newsletterCancelSubscription').ajaxForm({
		beforeSubmit: function(formData, jqForm, options){
			if (jqForm.data('allOk') == 0){
				return false;
			}
			$('#newsletterSubscription').find('.preloader').fadeIn('fast');
		},
		success: function(){
			$('#newsletterSubscription').find('.preloader').hide();
			$('#newsletterUnsubscribeSuccess').fadeIn('fast', function(){
				setTimeout("$('#newsletterUnsubscribeSuccess').fadeOut('fast')", 5000);
			});
		}
	});
	
	
	
	// promotion articles rotation
	if ($('#promotion .promotionImages img').size() > 1){
		$('#promotion .promotionImages').cycle({ 
			speed:  'fast',
			timeout: 4000,
			pager: '#promotion .promotionNav',
			pagerAnchorBuilder: function(idx, slide){
				// return selector string for existing anchor 
				return '#promotion .promotionNav li:eq(' + idx + ') a';
			},
			pagerEvent: 'mouseover',
			pauseOnPagerHover: true
		});
		
		// force a click event on the carousel navigation links, to counteract the cycle plugin event unbinder.
		$('#promotion .promotionNav a').click(function(){
			location.href = this;
		});
	}
	
	// toggle visibility of input fields on the customerinfo page, when clicking on the edit profile button
	$('#tCustomerinfo').find('.inpEditProfile').click(function(){
		$('#tCustomerinfo .updatecustomerForm').find('span.value,:text, select, textarea,:submit,:button').toggle();
		return false;
	});
	
	// on submitting forms on the shoppinglist page, ask if the user wants to save the list for later. 
	$('#tShoppinglist').find('.jsTransferShoppinglistToBasket').submit(function(){
		var preserveText = (typeof preserveListText != 'undefined')? preserveListText : 'Vil du bevare listen?'; 
		var agree = confirm(preserveText);
		if (agree){
			this.preserve.value = '1';
		}
	});
	
	
	// galleries on pages should have lightbox/colorbox functionality and an icon at mouseover
	$('#pageGallery').find('a[rel="imageGallery"]').append('<img class="zoom" src="/images/icon_zoom.png" alt="">').colorbox({
		current: ''
	});
	
	// images on normal pages should have lightbox/colorbox functionality
	$('a[rel="pageImages"]').colorbox({
		current: ''
	});
	
	// activate search suggests - type-ahead search
	$('.searchform input[name="searchtext"]').searchSuggest({
		afterAjax: function(){
			$('.jsQuantity').quantityAddSubtract();
		}
	});

	$('.getEmailLink').click(function(){
		var $this = $(this);
		$.ajax({
			url: '/dynamic.aspx?ajaxmode=1&data=article&template=getemail',
			data: {
				key: $this.attr('href').substring(1)
			},
			success: function(data){
				$this.replaceWith(data);
			}
		});
		return false;
	});




	initializeBBQ();

}); // jQuery ready end


// if popups are used on the page, show it
// have to be in the load event, since "ready state" is to early
$(window).load(function(){
	// set default id on the popup
	var strCurrentPKID = '0';
	
	// if the strPagePKID variable is set, replace the old id 
	if (typeof strPagePKID != 'undefined'){ strCurrentPKID = strPagePKID; }
	
	// if a popup should be shown and the cookie is not set to 1
	if ($('#pagePopup').size() > 0 && readCookie('pagePopup'+ strCurrentPKID) != '1'){
		$.colorbox({
			href: $('#pagePopup').attr('href'),
			iframe: true,
			width: '700',
			height: '80%',
			title: '<a href="#" onclick="closeAndHidePopup('+ strCurrentPKID +'); return false;">Luk og vis ikke igen</a>',
			onOpen: function(){
				$('#colorbox').addClass('pagePopup');
			},
			onClosed: function(){
				$('#colorbox').removeClass('pagePopup');
			}
		});
	}
});

// close and hide the pagePopup
function closeAndHidePopup(strPKID){
	createCookie('pagePopup' + strPKID,'1',1);
	$.colorbox.close();
}

// standard lightbox feature for productinfo page - building the container
function updateProductImagesLightbox(){
	
	$('#productImagesLightbox .imageContainer').find('img').remove()
		.end().prepend($('#productImages img').clone().removeAttr('id')).find('.zoom').remove()
		.end().find('img').each(function(){
	
			var strSrc = $(this).attr('src').replace('/thumbnail/','/productzoom/').replace('/productmain/','/productzoom/');
			$(this).attr('src',strSrc);
		
		}).hide();
	
} // updateProductImagesLightbox end


function autocompletePostalCode3(pcodeField, cityField, countryField) {
	if ($.isFunction($(this).autocomplete)) {//kontroller om autocomplete-funktionen er importeret
		$(pcodeField)
			.autocomplete('/dynamic.aspx?data=citynames&ajaxmode=1', {
				formatItem: function(row, i, max) {
					return row[0].replace('_',' ');
				},
				max: 9,
				extraParams: {
					countryid: function() { return $(countryField).val(); }
				},
				width: '200px'
			})
			.result(function(event, data, formatted){
				
				if (data) {
					var result = data[0].split('_');
					$(pcodeField).val(result[0]);
					if ($(pcodeField).val() != '') {
						$(cityField).val(result[1]);
					}
					else {
						$(cityField).val('');
					}
				}
				
				/*
				else {
					$(cityField).val('');
				}
				*/
				
			})
			.blur(function(){
				$this = $(this);
				if ($this.val() != ""){
					$.ajax({
						url: "/dynamic.aspx?data=citynames&ajaxmode=1",
						data: {
							q: $this.val(),
							countryid: $(countryField).val()
						},
						success: function(data){

							if(data != ""){
								var strFirstResult = data.match(/(.+)\n/i)[1].split('_');
								$(pcodeField).val(strFirstResult[0]);
								$(cityField).val(strFirstResult[1]);	
							}
							
						}
					});
				}
			});
		
		$(cityField).attr('readonly', true).addClass('disabled');
	}
}


function activatePagePreloader(){
	$('#pagePreloader').fadeTo('fast',0.5);
}
function deActivatePagePreloader(){
	$('#pagePreloader').fadeOut('fast');
}

// productImagesLightbox buttons update
function updateLightboxButtons(){
	
	var $imageContainer = $('#productImagesLightbox').find('.imageContainer');
	var $prev = $imageContainer.find('.prev'),
			$next = $imageContainer.find('.next'),
			$img = $imageContainer.find('img:visible');
	
	// enable/disable the next-button as needed
	if ($img.nextAll('img').size() < 1){ $next.addClass('disabled'); }
	else { $next.removeClass('disabled'); }
	
	// enable/disable the prev-button as needed
	if ($img.prevAll('img').size() < 1){ $prev.addClass('disabled'); }
	else { $prev.removeClass('disabled'); }

} // updateLightboxButtons end


// OLD FORM VALIDATION!!!! NOT USED ANYMORE
// validate forms on submit and on input typing and blur
function formValidation(){

	// single field validation
	function validateField(evt){
		var $this = $(this), objForm = $this.closest('form'), strActivateKeyup = 'jsTextfieldactivatekeyup', bitOk = true, re;
		
		if (evt.type != "keyup" || $this.hasClass(strActivateKeyup)) {
			// if the input doesn't allow keyup events, activate it (this happens at first blur event)
			if (!$this.hasClass(strActivateKeyup)) {
				$this.addClass(strActivateKeyup);
			}
			
			// validate field
			
			/*
			 * Valideringen skal understoette foelgende data, krav og afgraensninger:
			 *
			 * Fornavn og efternavn skal indeholde tekst.
			 * Gade skal indeholde minimum et ord efterfulgt af et mellemum og et tal.
			 * postnummer skal vaere 4 tegn i Danmark.
			 * By bliver automatisk indsat efter postnummer.
			 * Telefon skal indeholde 8 tegn for dansk tlf.nummer.
			 * E-mail skal indeholde min. 1 tegn efterfulgt af et @ (snabel a) efterfulgt af min. 1 tegn efterfulgt af et . (punktum) efterfulgt af 2-4 karakterer.
			 *
			 *
			 * For at identificere de forskellige felttyper, skal hvert felt have en css klasse der fort�ller hvordan feltet skal valideres.
			 * Forslag til css klasser, der kan benyttes til validering samt beskrivelse af hvad de skal validere:
			 *
			 * jsValidate: bruges kun til at identificere hvilke felter der skal valideres.
			 * jsValidatetext: validerer om feltet ikke er tomt - dette skal vaere basis form for validering, alle andre valideringstyper goer automatisk dette
			 * jsValidatefullname: kontrollerer om der er minimum 2 ord i feltet
			 * jsValidatepostalcode: tester om postnummeret er korrekt i forhold til det enkelte lands krav
			 * jsValidatephone: Ser om telefonnummeret er indtastet korrekt i forhold til landets krav
			 * jsValidatemail: E-mail skal indeholde de paakraevede dele specificeret ovenfor
			 * jsValidateaddress: Korrekt indtastet adresse - efter ovenstaaende specifikation
			 * jsValidaterepeat: Tester om teksten i feltet er det samme som i feltet med det tilknyttede ID (i css klassen "jsValidaterepeatfromIDPAAFELT"
			 *
			 *
			 */
			// test if there is a required field for this input field
			var strCurrentName = $this.attr('name');
			var objRequiredField = $('input[name=_' + strCurrentName + '_required],input[name=' + strCurrentName + '_Required]', objForm);
			var bitRequired = (objRequiredField.size() > 0);
			
			if ($this.hasClass('jsValidatetext')) {
				re = /.+/;
			}
			else 
				if ($this.hasClass('jsValidatefullname')) {
					re = /\w+\s\w+/;
				}
				else 
					if ($this.hasClass('jsValidatepostalcode')) {
						// her boer man have forskellige landevalg, saa valideringen ved hvordan den skal validere? ligenu gaar den kun efter 4 cifre
						//re = /^\d{4}$/;
						re = /^\d+$/;
					}
					else 
						if ($this.hasClass('jsValidatephone')) {
							// her boer man have forskellige landevalg, saa valideringen ved hvordan den skal validere? ligenu gaar den kun efter 8 cifre
							re = /^\d{8}$/;
						}
						else 
							if ($this.hasClass('jsValidatemail')) {
								re = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+$/i;
							}
							else 
								if ($this.hasClass('jsValidateaddress')) {
									re = /^(.)+\s[1-9]/;
								}
								else {
									// hvis der ikke er nogen specifik validering, skal der alligevel valideres paa om der er indhold i feltet.
									re = /.+/;
								}
			
			bitOk = re.test($this.val());
			
			// hvis feltet er et repeat felt, f.eks. gentag password eller e-mail,
			// skal valideringen i stedet gaa paa om feltets indhold er det samme som det tilknyttede
			if ($this.hasClass('jsValidaterepeat')) {
				var strAllclasses = $this.attr('class').split(' '), strOriginalInputId;
				
				$.each(strAllclasses, function(i, val){
					if (val.indexOf('jsValidaterepeatfrom') > -1) {
						strOriginalInputId = val.replace('jsValidaterepeatfrom', '');
						
						return false;
					}
				});
				
				bitOk = ($this.val() == $('#' + strOriginalInputId).val() && $this.val != '');
			}
			
			// hvis et postalcode felt ikke indeholder tal mellem 1000 og 9999, skal der vises en fejl
			/*
			if ($this.hasClass('jsValidatepostalcode') && bitOk) {
				var intPostal = parseInt($this.val());
				if (intPostal < 1000 || intPostal > 9999){
					bitOk = false;
				}
			}
			*/
			
			if ((bitRequired && bitOk) || (!bitRequired && $this.val() != '' && bitOk)) {
				// hvis feltet er korrekt udfyldt
				$this.removeClass('textfield_error').siblings('.validationMessage').removeClass('validationMessageError');
				$this.addClass('textfield_valid').siblings('.validationMessage').addClass('validationMessageValid');
				
				$this.data('validatedOk', true);
			}
			else 
				if ((bitRequired && !bitOk) || (!bitRequired && $this.val() != '' && !bitOk) || (bitRequired && $this.val() == '')) {
					// hvis feltet ikke er udfyldt korrekt.
					$this.removeClass('textfield_valid').siblings('.validationMessage').removeClass('validationMessageValid');
					$this.addClass('textfield_error').siblings('.validationMessage').addClass('validationMessageError');
					
					$this.data('validatedOk', false);
				}
				else
					if ($this.val() == '' && !bitRequired) {
						// hvis feltet ikke er udfyldt og det ikke er paakraevet
						$this.removeClass('textfield_error').siblings('.validationMessage').removeClass('validationMessageError');
						$this.removeClass('textfield_valid').siblings('.validationMessage').removeClass('validationMessageValid');
						
						$this.data('validatedOk', true);
					}
					else {
					}
		}
	} // validateField end
	
	
	$('form').each(function(){
		var objForm = this;
		
		// if the 'allOk' is already set as a string on the form, validation is already active and does not need to bet set again.
		if (typeof ($(objForm).data('allOk')) == 'string'){
			return false;
		}
		
		$(objForm).data('allOk', '1');
		
		// select all fields that require a certain mask validation
		$('.jsValidate', objForm).bind('keyup blur', validateField);
		
		$(objForm).submit(function(){
			var bitSendform = true;
			
			// Run a validation on all required fields
			$(':input[name*=_Required], :input[name*=_required]', this).each(function(){
				var relatedInput = $(':input[name=' + $(this).attr('name').replace(/_Required$/i, '').replace(/^_/, '') + ']', objForm);
				relatedInput.each(validateField)
			});
			
			// test if any active fields are not valid
			$(':input', this).not('[disabled]').each(function(){
				var $input = $(this);
				
				if ($input.data('validatedOk') == false) {
					bitSendform = false;
				}
			});
			
			if (!bitSendform) {
				$(objForm).data('allOk', '0');
				
				var strAlert = 'Du skal udfylde alle felter med * med korrekt data';
				alert(strAlert);
				return false;
			}
		});
		
	});

} // formValidation end










// beskrivelse
// version: 1.0 - 2010-06-08
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt

	$.fn.formvalidation = function(options){
	
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.formvalidation.defaults, options);
	
		// activate the script for each instans found in the selector
		return this.each(function(){
			var objForm = this;
			var $this = $(objForm);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			
			// if the 'allOk' is already set as a string on the form, validation is already active and does not need to bet set again.
			if (typeof ($this.data('allOk')) == 'string'){
				return false;
			}
			
			$this.data('allOk', '1');
			
			// select all fields that require a certain mask validation
			$this.find('.jsValidate').bind('keyup blur', validateField);
			
			$this.submit($.fn.formvalidation.validate);
		});
	}
	
	$.fn.formvalidation.validate = function(){
		var $this = $(this), bitSendform = true;
		
		// Run a validation on all required fields
		$this.find(':input[name*=_Required], :input[name*=_required]').each(function(){
			var relatedInput = $this.find(':input[name=' + $(this).attr('name').replace(/_Required$/i, '').replace(/^_/, '') + ']');
			relatedInput.each(validateField);
		});
		
		// test if any active fields are not valid
		$this.find(':input').not('[disabled]').each(function(){
			var $input = $(this);
			
			if ($input.data('validatedOk') == false) {
				bitSendform = false;
			}
		});
		
		if (!bitSendform) {
			$this.data('allOk', '0');
			
			var strAlert = 'Du skal udfylde alle felter med * med korrekt data';
			alert(strAlert);
			return false;
		} else {
			$this.data('allOk', '1');
		}
	}
	
	// single field validation
	function validateField(evt){
		var $this = $(this), objForm = $this.closest('form'), strActivateKeyup = 'jsTextfieldactivatekeyup', bitOk = true, re;
		
		if (evt.type != "keyup" || $this.hasClass(strActivateKeyup)) {
			// if the input doesn't allow keyup events, activate it (this happens at first blur event)
			if (!$this.hasClass(strActivateKeyup)) {
				$this.addClass(strActivateKeyup);
			}
			
			// validate field
			
			/*
			 * Valideringen skal understoette foelgende data, krav og afgraensninger:
			 *
			 * Fornavn og efternavn skal indeholde tekst.
			 * Gade skal indeholde minimum et ord efterfulgt af et mellemum og et tal.
			 * postnummer skal vaere 4 tegn i Danmark.
			 * By bliver automatisk indsat efter postnummer.
			 * Telefon skal indeholde 8 tegn for dansk tlf.nummer.
			 * E-mail skal indeholde min. 1 tegn efterfulgt af et @ (snabel a) efterfulgt af min. 1 tegn efterfulgt af et . (punktum) efterfulgt af 2-4 karakterer.
			 *
			 *
			 * For at identificere de forskellige felttyper, skal hvert felt have en css klasse der fort�ller hvordan feltet skal valideres.
			 * Forslag til css klasser, der kan benyttes til validering samt beskrivelse af hvad de skal validere:
			 *
			 * jsValidate: bruges kun til at identificere hvilke felter der skal valideres.
			 * jsValidatetext: validerer om feltet ikke er tomt - dette skal vaere basis form for validering, alle andre valideringstyper goer automatisk dette
			 * jsValidatefullname: kontrollerer om der er minimum 2 ord i feltet
			 * jsValidatepostalcode: tester om postnummeret er korrekt i forhold til det enkelte lands krav
			 * jsValidatephone: Ser om telefonnummeret er indtastet korrekt i forhold til landets krav
			 * jsValidatemail: E-mail skal indeholde de paakraevede dele specificeret ovenfor
			 * jsValidateaddress: Korrekt indtastet adresse - efter ovenstaaende specifikation
			 * jsValidaterepeat: Tester om teksten i feltet er det samme som i feltet med det tilknyttede ID (i css klassen "jsValidaterepeatfromIDPAAFELT"
			 *
			 *
			 */
			// test if there is a required field for this input field
			var strCurrentName = $this.attr('name');
			var objRequiredField = $('input[name=_' + strCurrentName + '_required],input[name=' + strCurrentName + '_Required]', objForm);
			var bitRequired = (objRequiredField.size() > 0);
			
			if ($this.hasClass('jsValidatetext')) {
				re = /.+/;
			}
			else 
				if ($this.hasClass('jsValidatefullname')) {
					re = /[^ ]+ [^ ]+/;
				}
				else 
					if ($this.hasClass('jsValidatepostalcode')) {
						// her boer man have forskellige landevalg, saa valideringen ved hvordan den skal validere? ligenu gaar den kun efter 4 cifre
						//re = /^\d{4}$/;
						re = /^\d+$/;
					}
					else 
						if ($this.hasClass('jsValidatephone')) {
							// her boer man have forskellige landevalg, saa valideringen ved hvordan den skal validere? ligenu gaar den kun efter 8 cifre
							re = /^\d{8}$/;
						}
						else 
							if ($this.hasClass('jsValidatemail')) {
								re = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+$/i;
							}
							else 
								if ($this.hasClass('jsValidateaddress')) {
									re = /^(.)+\s[1-9]/;
								}
								else {
									// hvis der ikke er nogen specifik validering, skal der alligevel valideres paa om der er indhold i feltet.
									re = /.+/;
								}
			
			bitOk = re.test($this.val());
			
			// hvis feltet er et repeat felt, f.eks. gentag password eller e-mail,
			// skal valideringen i stedet gaa paa om feltets indhold er det samme som det tilknyttede
			if ($this.hasClass('jsValidaterepeat')) {
				var strAllclasses = $this.attr('class').split(' '), strOriginalInputId;
				
				$.each(strAllclasses, function(i, val){
					if (val.indexOf('jsValidaterepeatfrom') > -1) {
						strOriginalInputId = val.replace('jsValidaterepeatfrom', '');
						
						return false;
					}
				});
				
				bitOk = ($this.val() == $('#' + strOriginalInputId).val() && $this.val != '');
			}
			
			// hvis et postalcode felt ikke indeholder tal mellem 1000 og 9999, skal der vises en fejl
			/*
			if ($this.hasClass('jsValidatepostalcode') && bitOk) {
				var intPostal = parseInt($this.val());
				if (intPostal < 1000 || intPostal > 9999){
					bitOk = false;
				}
			}
			*/
			
			if ((bitRequired && bitOk) || (!bitRequired && $this.val() != '' && bitOk)) {
				// hvis feltet er korrekt udfyldt
				$this.removeClass('textfield_error').siblings('.validationMessage').removeClass('validationMessageError');
				$this.addClass('textfield_valid').siblings('.validationMessage').addClass('validationMessageValid');
				
				$this.data('validatedOk', true);
			}
			else 
				if ((bitRequired && !bitOk) || (!bitRequired && $this.val() != '' && !bitOk) || (bitRequired && $this.val() == '')) {
					// hvis feltet ikke er udfyldt korrekt.
					$this.removeClass('textfield_valid').siblings('.validationMessage').removeClass('validationMessageValid');
					$this.addClass('textfield_error').siblings('.validationMessage').addClass('validationMessageError');
					
					$this.data('validatedOk', false);
				}
				else
					if ($this.val() == '' && !bitRequired) {
						// hvis feltet ikke er udfyldt og det ikke er paakraevet
						$this.removeClass('textfield_error').siblings('.validationMessage').removeClass('validationMessageError');
						$this.removeClass('textfield_valid').siblings('.validationMessage').removeClass('validationMessageValid');
						
						$this.data('validatedOk', true);
					}
					else {
					}
		}
	} // validateField end
	
	
	
	// default values for the options
	$.fn.formvalidation.defaults = {
		option: 'value'
	};

})(jQuery);


// searchSuggest - type ahead
// version: 1.0 - 2010-07-23
(function($){
	// TODO:
	//		Lav dokumentation til hvordan plugin'et bliver brugt.
	//		Udvid funktionalitet, så man kan kalde/aktivere søgningen direkte fra javascript ved at kalde det på ca. denne måde: $(selector).searchSuggest.search().
	//		Lav callback funktioner.
	//		Burde man kunne navigere ned igennem listen af resultater med keyboardet? Hvis man skal, skal det være en option og hvordan skulle det gøres med et fleksibelt system - der skal være en form for selector-option tilknyttet så?
	
	
	$.fn.searchSuggest = function(options){
		
		// create the options object with data from the default options and the user specified options
		var opts = $.extend({}, $.fn.searchSuggest.defaults, options);

		// activate the script for each instans found in the selector
		return this.each(function(){
			var $this = $(this);
			// build element specific options
			var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
			
			// remove the autocomplete from the input
			$this.attr('autocomplete','off').keyup(function(e){
				var intKey = e.keyCode;
				// only allow certain keystrokes
				if ((intKey > 47 && intKey < 58) || (intKey > 36 && intKey < 41) || (intKey > 64 && intKey < 91) ||
						(intKey > 96 && intKey < 112) || (intKey > 185 && intKey < 223) ||
						intKey == 32 || intKey == 226 ||
						intKey == 46 || intKey == 8){
			
					// if the timeout is still counting down, cancel it to stop the client from hammering the server with search requests
					if (typeof($.fn.searchSuggest.searchSuggestTimeout) != 'undefined') {
						clearTimeout($.fn.searchSuggest.searchSuggestTimeout);
					}
					
					// set the timeout to when the search should be made after last keystroke
					$.fn.searchSuggest.searchSuggestTimeout = window.setTimeout(function(){
						searchSuggestAjax($this,o);
					}, o.timeout);
				}
			});
		});
	}
	
	
	// timeout container for the searchsuggestion container
	$.fn.searchSuggest.searchSuggestTimeout;
	
	
	// search suggest ajax request
	// strSort: optional method of sorting
	function searchSuggestAjax($this,o,strSort){
		
		// if no sorting method has been chosen, use the default
		if (!strSort){
			strSort = o.defaultSort
		};
		
		if ($this.val().length >= o.minLength) {
			var strQuery = '/dynamic.aspx?ajaxmode=1&data=' + o.ajaxDataFormat + '&template=' + o.ajaxTemplate + '&sort=' + strSort + '&searchtext=' + $this.val();
			
			$.ajax({
				url: strQuery,
				type: 'get',
				success: function(data){
					
					// collect the position and dimensions of the searchfield
					var inputX = $this.offset().left,
							inputY = $this.offset().top,
							inputHeight = $this.outerHeight(),
							inputWidth = $this.outerWidth();
					
					// position the search container below the searchfield aligned to the left.
					var containerX = inputX + o.offsetX,
							containerY = inputY + inputHeight + o.offsetY;
					
					// If horisontalAlign is set to right, position the search container to be aligned to the right
					if (o.horisontalAlign == 'right'){
						containerX = inputX - (o.containerCss.width - inputWidth);
					}
					
					// set the default container CSS and let the user extend it as needed
					var containerCssObject = $.extend({
						position: 'absolute',
						top: containerY,
						left: containerX,
						zIndex: o.zIndex
					}, o.containerCss);
					
					//if the container do not already exist, create it and append it to the body
					if ($('#' + o.containerId).size() == 0){
						var ajaxSearchBox = $('<div/>',{
							'id': o.containerId,
							css: containerCssObject,
							html: data
						}).css('opacity',0).appendTo('body').fadeTo(200,1);
					} else {
						// if the container already exists, just replace the content with new data
						$('#' + o.containerId).html(data);
					}
					
					// unbind previous events and append new ones.
					// if the user press Esc on the keyboard or click outside the search container, close the search container and unbind the events
					$(document).unbind('.searchSuggest').bind('keyup.searchSuggest click.searchSuggest',function(e){
						if (e.which == 27 || (e.type == 'click' && !$(e.target).closest('#'+o.containerId).size() > 0)) {
							$('#'+o.containerId).remove();
							$(document).unbind('.searchSuggest');
						}
					});
					
					if (o.afterAjax) {
						o.afterAjax();
					}
				}
			});
		} else {
			$('#'+o.containerId).remove();
		}
	}
	
	
	// default values for the options
	$.fn.searchSuggest.defaults = {
		ajaxDataFormat: 'products',
		ajaxTemplate: 'ajaxsearch',
		containerCss: {
			background: '#fff', // IE6-7 bugfix, so elements can't be clicked through the searchcontainer. It can be replaced with a (transparent) background-image instead.
			width: 300
		},
		containerId: 'ajaxSearchSuggestContainer',
		defaultSort: 'pop',
		horisontalAlign: 'right',
		minLength: 2,
		offsetX: 0,
		offsetY: 5,
		timeout: 200,
		zIndex: 1000,
		afterAjax: null
	};

})(jQuery);


function initializeBBQ(){
	
	// to prevent any empty page reloads, test if $ exists
	if (typeof $ == 'undefined') {
		return false;
	}
	
	// cancel the BBQ integration if the confirmation page is loaded
	if ($('#tConfirmation').size() > 0 || $('.shopflowForm, .shopflow').size() > 0) {
  	return false;
  }
	
	// insert the needed classes and default content
	$('#site').addClass('jsBbq');
	$('#siteMain').addClass('jsBbq-content').wrapInner('<div class="jsBbq-default"/>');
	
	// For each .bbq widget, keep a data object containing a mapping of
	// url-to-container for caching purposes.
	$('.jsBbq').each(function(){
		$(this).data('bbq', {
			cache: {
				// If url is '' (no fragment), display this div's content.
				'': $(this).find('.jsBbq-default'),
				'/': $(this).find('.jsBbq-default')
			}
		});
	});
	
	// For all links inside a .jsBbq widget, push the appropriate state onto the
	// history when clicked.
	$('#areaMenu a[href^="/groups/"], #siteBreadcrumb a[href^="/groups/"]').live('click', function(e){
		var state = {},  // Get the id of this .jsBbq widget.
		id = $(this).closest('.jsBbq').attr('id'),  // Get the url from the link's href attribute, stripping any leading #.
		url = $(this).attr('href');
		
		// Set the state!
		state[id] = url;
		$.bbq.pushState(state);
		
		// save the request for the latest clicked url, so the callback knows which to show, even if the return order is not the same as the requested order
		$(this).closest('.jsBbq').data('currentLinkUrl',url);

		// And finally, prevent the default link click behavior by returning false.
		e.preventDefault();
		//return false;

	});
	
	// Bind an event to window.onhashchange that, when the history state changes,
	// iterates over all .bbq widgets, getting their appropriate url from the
	// current state. If that .bbq widget's url has changed, display either our
	// cached content or fetch new content to be displayed.
	$(window).bind('hashchange', function(e){
	
		// Iterate over all .bbq widgets.
		$('.jsBbq').each(function(){
			var that = $(this),   // Get the stored data for this .bbq widget.
			data = that.data('bbq'),   // Get the url for this .bbq widget from the hash, based on the
			// appropriate id property. In jQuery 1.4, you should use e.getState()
			// instead of $.bbq.getState().
			url = $.bbq.getState(that.attr('id')) || '';
			
			// If the url hasn't changed, do nothing and skip to the next .bbq widget.
			if (data.url === url || url == '') {
				return;
			}
			
			// Store the url for the next time around.
			data.url = url;
			
			// Remove .bbq-current class from any previously "current" link(s).
			that.find('a.selected').removeClass('selected');
			
			// Hide any visible ajax content.
			that.find('.jsBbq-content').children(':visible').hide();
			
			// Add .bbq-current class to "current" nav link(s), only if url isn't empty.
			url && that.find('#areaMenu a[href="' + url + '"]').addClass('selected');
			
			// create a url to the dynamic page, to get a faster and smaller page
			// the url could be built up of a dataformat, key and template
			var arrLinkUrl = url.substr(1).split('/');
			var strLinkUrl = '/dynamic.aspx?ajaxmode=1';
			var strBreadcrumbUrl = '/dynamic.aspx?ajaxmode=1&data=breadcrumb';
			
			if (arrLinkUrl[0] && arrLinkUrl[0] != '') {
				strLinkUrl = strLinkUrl + '&data=' + arrLinkUrl[0];
				strBreadcrumbUrl = strBreadcrumbUrl + '&maindata=' + arrLinkUrl[0];
			}
			if (arrLinkUrl[1] && arrLinkUrl[1] != '') {
				strLinkUrl = strLinkUrl + '&key=' + arrLinkUrl[1];
				strBreadcrumbUrl = strBreadcrumbUrl + '&mainkey=' + arrLinkUrl[1];
			}
			if (arrLinkUrl[2] && arrLinkUrl[2] != '') {
				strLinkUrl = strLinkUrl + '&template=' + arrLinkUrl[2];
				strBreadcrumbUrl = strBreadcrumbUrl + '&maintemplate=' + arrLinkUrl[2];
			}
			
			// update the breadcrumb if the URL contains something
			if (url) {
				$('#siteBreadcrumb').load(strBreadcrumbUrl + ' >div');
			}
			
			if (data.cache[url]) {
				// Since the widget is already in the cache, it doesn't need to be
				// created, so instead of creating it again, let's just show it!
				data.cache[url].show();
				
			}
			else {
				// Show "loading" content while AJAX content loads.
				that.find('.jsBbq-loading').show();
				
				// Create container for this url's content and store a reference to it in
				// the cache.
				
				
				//data.cache[url] = $('<div class="jsBbq-item"/>')				// Append the content container to the parent container.
				//.appendTo(that.find('.jsBbq-content'));
				
				$.ajax({
					url: strLinkUrl,
					success: function(strData){
						
						// find the body element  
						var startCut = strData.indexOf('<body');
						var endCut = strData.indexOf('</body>') + 7;
						
						// Create container for this url's content and store a reference to it in
						// the cache.
					
						var strStyle = '';
						if( that.data('currentLinkUrl') != url && typeof that.data('currentLinkUrl') != 'undefined') {
							strStyle = ' style="display: none;"';
						}
					
						// if the new page has content, insert it and scroll to it
						data.cache[url] = $('<div class="jsBbq-item"' + strStyle + '/>')				// Append the content container to the parent container.
						.appendTo(that.find('.jsBbq-content'))
						.html($(strData.substring(startCut, endCut)));
						
						// reactivate the add and subtract features on productlists 
						$('.jsQuantity').quantityAddSubtract();
						
						$('.tProducts').ajaxProductlistpaging({
							beforeAjaxAnimation: function(){
								$('.jsQuantity').quantityAddSubtract();
							}
						});
						
						// Content loaded, hide "loading" content.
						that.find('.jsBbq-loading').hide();
					}
				});
				
			/*
			 // Load external content via AJAX.
			 .load( strLinkUrl + ' >div', function(){
			 // reactivate the add and subtract features on productlists
			 $('.jsQuantity').quantityAddSubtract();
			 
			 $('.tProducts').ajaxProductlistpaging({
			 beforeAjaxAnimation: function(){
			 $('.jsQuantity').quantityAddSubtract();
			 }
			 });
			 
			 // Content loaded, hide "loading" content.
			 that.find( '.jsBbq-loading' ).hide();
			 });
			 */
			}
		});
	});
	
	// Since the event is only triggered when the hash changes, we need to trigger
	// the event now, to handle the hash the page may have loaded with.
	$(window).trigger('hashchange');
}

