This is an old revision of the document!
Table of Contents
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
andonsubmit
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
http://cdn.foxycart.tld/YOURDOMAIN/foxycart.complete.js
: Compressed. Includes the code to automatically set your store's domain, your store's FoxyCart domain, to initialize theFC
object asfcc
, and to attach Colorbox to all add-to-cart links and forms.http://cdn.foxycart.tld/YOURDOMAIN/foxycart.js
: Compressed. Includes the code to automatically set your store's domain, your store's FoxyCart domain, and to initialize theFC
object asfcc
.http://cdn.foxycart.tld/YOURDOMAIN/foxycart.raw.js
: Uncompressed. Does not set your store's domain, your store's FoxyCart domain, nor does it initialize thefcc
object. This will generally only be used for special circumstances or advanced users needing access to the uncompressed code.
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 thehref
oraction
of the link or form pointing to your FoxyCart's domain. - The
fc_json
object is now accessible asFC.json
. fc_PreProcess()
has been changed to apreprocess()
method that's more flexible, called differently, expecting different arguments.fc_BuildFoxyCart()
has similarly been changed to apostprocess()
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.
''storedomain'': How Your Links and Forms Are Handled
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 theFC.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 inFC.json.product_count
.#fc_total_price
,.fc_total_price
: The inner HTML will be replaced by the value inFC.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:
- The submitted element itself.
- 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.)