Documentation You are here: start » v » 0.7.0 » advanced » javascript

This is an old revision of the document!


FoxyCart's Javascript, JSON, and JSONP

FoxyCart's foxycart.js file is full of goodies that you probably won't ever need to think twice about. If default configurations are an anathema to you, if you need to get advanced for a custom integration, or if you're just curious about what's under the hood please explore this page and the “raw” version of the foxycart.js, and let us know if you have any questions.

What It Does

The foxycart.js file:

  • Handles all cross-domain sessions, ensuring sessions don't get lost regardless of browser privacy settings (so long as some cookies are enabled).
  • Automatically (mostly) handles determining at what level to set your store's FoxyCart cookie. (ie. Determines to set it at .example.com or .example.co.uk or .custom.example.com.)
  • Makes it easy for custom events or validation to be run before products are added to the cart.
  • Makes it easy for custom events on an attempted add-to-cart (ie. the default Colorbox modal window, custom JSONP functionality, etc.).
  • Makes it easy for custom events or validation to be run after products are added to the cart.
  • Automatically attaches onclick and onsubmit handling to all links and forms (even dynamically created elements) pointing to your store's FoxyCart cart URL.
  • Keeps the FoxyCart JSON object (FC.json) current before and after cart requests.
  • Alerts if jQuery isn't loaded.

Available Files

What's Different from Previous Versions

Almost everything but some of the ways that sessions are set has been rewritten, but here are the main changes from the foxycart_includes.js in v0.6.0:

  • No more .foxycart class necessary for add-to-cart links and forms. Instead it relies on the href or action of the link or form pointing to your FoxyCart's domain.
  • The fc_json object is now accessible as FC.json.
  • fc_PreProcess() has been changed to a preprocess() method that's more flexible, called differently, expecting different arguments.
  • fc_BuildFoxyCart() has similarly been changed to a postprocess() method described below.
  • Setting the FoxyCart Session ID (fcsid) at a subdomain, third-level domain, or specific path is now possible without rewriting core functions.

How It Works & Configuration

While most of this should happen automatically, especially if you're using the foxycart.js or foxycart.complete.js versions (as opposed to the foxycart.raw.js), there are a few things that are three configurations that do need to be configured correctly.

The first configuration that the FC object in foxycart.js takes is the path to your store's FoxyCart cart, like yourstorename.foxycart.com. This setting is critical (and usually set automatically unless you're using the “raw” version of foxycart.raw.js), as this is how the script determines which links to attach the click or submit events to, as well as when and how to add the session ID to any and all requests to your store's FoxyCart requests.

Without this setting configured correctly it is highly likely that your customers will lose their cart contents when they attempt a checkout.

''sitedomain'': The Domain on Which Your Visitor's FoxyCart Cookies Are Set

The sitedomain is the second argument required, but unlike the storedomain, the sitedomain is only used to determine where to set the cookie for the visitor's FoxyCart session. If your sitedomain is passed in as example.com or www.example.com, the fcsid (FoxyCart Session ID) cookie is set at the second-level domain, which is .example.com. If your sitedomain is a third-level domain like example.co.uk or subdomain.example.com, the cookie would be set at .example.co.uk or .subdomain.example.com.

This setting is only important if your site isn't at the second-level domain, or if you want to restrict your FoxyCart sessions by subdomain. For example, if your site is example.co.uk, you don't want the cookie set at .co.uk. Or if you want to have different FoxyCart sites at donations.example.com and products.example.com, you'd need the cookies not to be set at .example.com or the sessions would overlap with unexpected results. (Another example would be if your site is at a 3rd party provider like example.squarespace.com, you don't want all *.squarespace.com sites sharing your FoxyCart sessions.)

The only thing to keep in mind is that the www subdomain is effectively ignored, so if you do want to lock your sessions down to .www.example.com you'll need to set the sitedomain value to something like www1.example.com. The actual value doesn't matter; it's only counting the dots in the value after it strips the www.

''cookiepath'': The Path on Which Your Visitor's FoxyCart Cookies Are Set

The cookiepath determines the fcsid cookie's path. This is almost always going to be empty, so the cookies would be set at .example.com, but if you do need to have multiple FoxyCart sessions on the same domain you could use this setting to restrict cookies to something like .example.com/en/ and .example.com/es/ (to split English and Spanish FoxyCart stores, for example).

"Mini-Cart" Display and Helper Functionality

When the FC class is initialized (via the .init() method) and on the .cart_update() method, elements with the following classes or IDs are modified:

  • #fc_minicart, .fc_minicart: If the FC.json.product_count is greater than 0, these elements will be shown. Otherwise they'll be hidden
  • #fc_quantity, .fc_quantity: The inner HTML will be replaced by the value in FC.json.product_count.
  • #fc_total_price, .fc_total_price: The inner HTML will be replaced by the value in FC.json.total_price, formatted using the _currency_format function (which adds decimals but doesn't add currency symbols).

Adding Your Own Events

''preprocess'': Before an Add-To-Cart

What It Is

Attaching a custom event to be run before an item is added to the cart can be useful if you need to do client-side validation of a form or value before allowing the cart-add to happen. For example, you may have a “Custom Note” field on an add-to-cart form that's required. Or a “Gift Recipient Email Address” field that must be completed for the item to be added to the cart. Using the preprocess event allows all of this and more.

How It Works: Overview

When a link or form pointing to your FoxyCart's cart URL (ie. https://example.foxycart.tld/cart) is clicked or submitted, foxycart.js first checks to see if any functions have been added to your preprocess array. If any functions exist, they are run in order of entry (first-in-first out) passing in two arguments:

  1. The submitted element itself.
  2. An array of name/value pairs to be submitted to the cart-add request. This array is built using an “unserialize” function inside the FC object.

If any function in the preprocess array returns false, the cart-add is aborted. (The actual onclick or onsubmit event of the add-to-cart link or form returns false, so the default behavior of the element is bypassed as well.) No other indication is given, so if you have a preprocess function that returns false it should also alert the user.

If no preprocess functions are added, this step is effectively skipped.

How It Works: Details

Assuming the default fcc object, the first step is to create a function and add it to the preprocess array:

foxycart_ga = function(e, arr) {
	var href = '';
	if (e.tagName == 'A') {
		href = e.href;
	} else if (e.tagName == 'FORM') {
		href = 'https://'+storedomain+'/cart?'+jQuery(e).serialize();
	}
	if (!href.match("cart=(checkout|updateinfo)") && !href.match("redirect=")) {
		pageTracker._trackPageview('/cart');
		console.info('foo1');
		return true;
	}
}
fcc.events.cart.preprocess.add(foxycart_ga);

Or just create an anonymous function straight in the array, like this:

fcc.events.cart.preprocess.add(function(e, arr) {
	var href = '';
	if (e.tagName == 'A') {
		href = e.href;
	} else if (e.tagName == 'FORM') {
		href = 'https://'+storedomain+'/cart?'+jQuery(e).serialize();
	}
	if (!href.match("cart=(checkout|updateinfo)") && !href.match("redirect=")) {
		pageTracker._trackPageview('/cart');
		console.info('foo1');
		return true;
	}
});

That function fires off a request to Google Analytics's _trackPageview() function before the cart is added, and returns true. Because it returns true the .execute() method of the preprocess object will continue on to the next function in its array. If the execute() method runs all the functions in the preprocess array without hitting a return of false, the cart-add request moves on to the process event.

''process'': The Actual Add-To-Cart Event

What It Is

The process event is where you can define what happens when a visitor to your site clicks an “add to cart” link or form. You may want to display an unobtrusive indication that the item has been added to their cart; you may wish to display a modal window (like the default Colorbox script); you may want to send the visitor directly to checkout if certain products are in the cart; or you may want to do a combination of all that and more. All of this functionality can be defined in the process event.

Skipping It Entirely

If you don't want anything fancy and just want your links and forms to load the cart up straight, just don't add any functions to process. It's that easy. If no functions are present then your add-to-cart links and forms will behave normally.

How It Works: Overview

The process functionality is nearly identical to the preprocess functionality described above, but whether true or false is returned may be a bit more nuanced. Generally you'll only want _one_ event in the process array, though you can have more if necessary.

One thing to keep in mind is that a return false; is probably desired if you actually do anything here, such as a JSONP request or a modal window call, since that is where the item is added to the cart. If you don't return false then the add-to-cart link or form will fire and the request will likely be duplicated.

How It Works: Details

After any preprocess events have been run, the process event is first checked to determine if any functions have been added. If the process array is empty, true is returned and the default behavior of the add-to-cart element that was submitted continues.

Adding a function to the process array is the same as with the preprocess examples above, but obviously replacing preprocess with process. Here's an example of the way Colorbox is attached to cart-add requests in the default foxycart.complete.js file:

fcc.events.cart.process.add(function(e){
	var href = '';
	if (e.tagName == 'A') {
		href = e.href;
	} else if (e.tagName == 'FORM') {
		href = 'https://'+storedomain+'/cart?'+jQuery(e).serialize();
	}
	if (href.match("cart=(checkout|updateinfo)") || href.match("redirect=")) {
		return true;
	} else {
		jQuery.colorbox({
			href: href,
			iframe: true,
			width: "700px",
			height: "70%",
			onClosed: function(){fcc.events.cart.postprocess.execute(e);}
		});
		return false;
	}
});

This example first checks to see if the element that was submitted is a link (A) or form (FORM). It then sets the URL to be submitted to the cart. If that cart request should bypass the cart, however, it returns true, thus allowing the link or form to complete its behavior unimpeded (and bypassing the modal window entirely). If the cart-add request does belong in a modal window the code instantiates a Colorbox and loads the cart in an iframe. It then returns false, preventing the link or form from submitting again (since loading it in the Colorbox's iframe has already made our cart request.

Notice the onClosed function. That comes next. Onward, ho!

''postprocess'': After the Add-To-Cart

What It Is

The postprocess event is not called directly by foxycart.js, but is available to use if you need it. This can be useful, for example, if you want to refresh the FC.json when your modal window is closed, as is the case with the default foxycart.complete.js.

How It Works: Overview

Just like the proprocess and process, you can add multiple functions to the postprocess even. Notice the call to postprocess in the process example above, in the onClosed parameter. That's telling Colorbox to run the postprocess events when the modal window is closed. If we add a function like below, then the cart_update() method will be called (which refreshes the FC.json and updates the “minicart” helper functions).

	fcc.events.cart.postprocess.add(function(){
		fcc.cart_update.call(fcc);
	});

(The .call(fcc) is necessary to preven the this keyword in javascript from going wonky.)

Site Tools