Shopify Tutorial: Creating a Threadless-like Add-to-Cart button using jQuery and AJAX
In this tutorial we will be modifying the product page of the Ripen theme to work more like the product page on Threadless. We’re going to be modifying the Ripen theme, but this tutorial is applicable to any Shopify theme. I would like to thank John Tajima again for teaching me how AJAX and JSON objects work with Shopify. We will also make it so that the number of products in the cart displayed automatically updates after you add an item to the cart.
1. Install jQuery
If you are unsure of how to do this, please see Steps 1 to 3 from this tutorial.
2. Install Colorbox
Grab the jQuery plugin Colorbox here, and upload it to your theme assets. We’re going to be using Colorbox to get the lightbox popup when a product is added to the cart. I usually use Fancybox for lightboxes, but I decided to go with Colorbox for this tutorial because it “can be called directly, without assignment to an element”. This means that I can call a Colorbox method, and create a lightbox on-the-fly when the “Add to Cart” button is clicked, but with Fancybox this would be impossible.
Be sure to add these two files in the <head> section to your theme.liquid as well.
...other assets {{ 'colorbox.css' | asset_url | stylesheet_tag }} {{ 'jquery.colorbox-min.js' | asset_url | script_tag }}
3. Modify the “Add to Cart” button
Open your product.liquid file, and locate the input button for adding to the cart. The input button looks like this:
We want to do two things to this button: first, we want to make it so that even if the user clicks on it, the user is not taken to the cart page. Second, we want to call a custom function (that we’re going to be writing shortly) that makes an AJAX call to add the product to the cart.
onclick="return false; addItem('add-to-cart');"/>
The addItem function takes the form’s id as a parameter. This is so that when we use jQuery later, we know which form to select. The opening tag for your form should look like this:
4. Preparing product.liquid
Add the following line at the top of product.liquid.
The added-box is where the content of the lightbox will be inserted. We need to wrap it in another div with a “display:none;” so that the content of the lightbox are not displayed on the actual page.
5. Preparing theme.liquid
Next, we have to modify theme.liquid a little so that the number displayed for the number of items in the cart updates automagically. In theme.liquid, find a place where you want to show a link to the cart. In this tutorial, I’m going to put it in the right column, under where it says “Shopping Cart”.
{% if cart.item_count == 0 %} Your cart is empty. {% endif %}
What’s important here is that the <a> tag has the id “cart-number”, so that we can select it with jQuery later to modify its contents.
6. Displaying the number of items in the cart when the product page is loaded
In theme.liquid, locate the <head> section. This is where we will be adding the Javascript to make it all happen.
First, we need to add create a variable called cartCount, which will store the number of items that are in the cart. When the product page is loaded, we want to query the number of items that are currently in the cart with Liquid, and then store it in a Javascript variable called ‘cartCount’.
Next, we want to create a function that is called upon when the page is done loading. When the page is loaded, the link with the id “cart-number” that we created in the last step should display the right number of items in the cart. We can do this by adding the the following function in the script:
7. Make the AJAX call to add the product to the cart
Let’s now create the function for adding the product to the cart. Below the document.ready function, add the following function.
The addItem function makes an AJAX request using jQuery.ajax().
- the type option specifies what kind of request we’re going to make. We will be making a POST request.
- the url option tells the server to add the product to the cart.
- the dataType option specifies the type of data that we want back from the server. We want to receive the data as JSON objects.
- the data options specifies what data we want to send to the server. We’re going to be selecting the form from the product page, and using the serialize() method on it to make it into a string that is readable by the server.
- If the AJAX call is successful, the addToCartOk function is called. If it is not, the addToCartFail function is called.
8. addToCartOk – the function for a successful AJAX call
Let’s start off by creating the function that is called when the product is added to the cart successfully.
... data: $('#'+form_id).serialize(), success: addToCartOk, error: addToCartFail }); } function addToCartOk(product) { cartCount++; $('#added-box').html(product.title + ' was added to the cart!'); $('#cart-number').replaceWith("View cart (" + cartCount + ")"); $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); }
Now, the lightbox that I created isn’t the prettiest thing in the world, but you can customize the look and feel by adjusting Colorbox’s properties. You can also modify colorbox.css.
To change the color of the overlay, open colorbox.css, and look for the #cboxOverlay selector and change the background to the color or image of your choice. To make my overlay black, I set #cboxoverlay to the following:
#cboxOverlay{background:#000;}
9. addToCartFail – the function for an unsuccessful AJAX call
The last thing we want to do is to create a function that is called if the product was not able to be added to the cart. The primary reason for not being able to add something to the cart is that there is not enough inventory for that item.
... $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); } function addToCartFail(obj, status) { $('#added-box').html('The product you are trying to add is out of stock.'); $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); }
Alternatively, you can use the code below to receive the actual message of the error. This was my initial approach, but I found that sometimes the Shopify servers won’t return the proper response, which in turn would not make the lightbox appear at all. If anybody could give me some insight on why this happens, that would be awesome.
... $.fn.colorbox({ open:true, width: "400px", innerHeight: "60px", inline:true, href:"#added-box", transition: 'none' }); } function addToCartFail(obj, status) { try { var response = jQuery.parseJSON(obj.responseText); $('#added-box').html(response.description); } catch(e) { $('#added-box').html("There was an error"); } $.fn.colorbox({ open:true, width: "400px", innerHeight: "80px", inline:true, href:"#added-box", transition: 'none' }); }
10. Conclusion
You now have a product page that works similar to that of Threadless. I’m not too happy with the way the addToCartFail function is working right now, but for now it seems like it’s the only way to have the lightbox appear every time there is an error. You can download the completed theme here.
Big thanks again to John Tajima for his help!
15 Comments
does not work on Onyx theme.
Hey dude,
Nice work :)
I’ve done this same thing in mootools 1.3 (not the version that’s on the global asset area at shopify) if you’re interested in seeing the code just let me know.
It makes no difference really, but I just prefer the way mootools code looks ;)
darbotron
I’m having trouble getting this to work. Is there anything assumed you didn’t mention. Other scripts etc.. I’m using my own theme with this. Thanks
Hey Andrew,
Hmm… I don’t think I’ve left anything out. What’s your store’s URL? Maybe I can take a look and help out.
Cheers,
Tets
Hi Tets,
I can’t figure out what I have done. I can’t seem to click add to cart at all now. Does it work with slate theme?
I am not too familiar with js but your tut looked pretty straightforward so I gave it a go. Can you take a look at my shop for me? Password is unibox11 for the storefront. Need to get it sorted pretty soon as my launch is Tuesday.
J
I couldn’t get this to work either… I’m using a heavily customized helvetica theme… I’d really like to be able to use this but just no dice…
I’m not sure but would it be anything to do with the use of the javascript statement ‘return false;’ in the onclick button? It looks like that may be stopping the calling of the addItem function?
Any ideas Tets?
Thanks
Rick
Hey all, just following through the tutorial and yes, pretty sure there’s been a couple of stages missed.
The AddToCart function isn’t defined anywhere?
Lol – just found the rest of the post here – http://blog.tetsutakara.com/1156/creating-a-threadless-like-add-to-cart-button-using-jquery-and-ajax/2/
Gah! Sorry for that Jo, it looks like I messed up the pagination in WordPress. Taking a look now….
UPDATE: I’ve fixed the pagination issue. Thanks for catching that!
Hi,
I am not sure what I am doing wrong but I keep getting a “Failed to load resource: the server responded with a status of 400 (Bad Request) “.
Any advice?
Just curious…. is step one linking to another tutorial the correct link? Doesn’t seem relevant to making sure jQuery is installed.
I wasn’t able to get this working yet, will try again later. I tried a method from a different tutorial and also got a status 400 error.
@Owen ah, I wrote this tutorial 3 years ago and I’ve since updated the “Terms and Conditions” one to auto-include jQuery. When I get a chance I’ll do the same with this one.
I can’t get this to work, but it’s exactly what I need! Any ideas?
Also bummed that this doesn’t work anymore. This is the only tutorial I found which shows shopify users how to do something like this, which is stranger because it’s a pretty common functionality.
@H Thanks for the feedback. Looks like there aren’t too many other resources out there for this.
As soon as I’m finished with the Shopify Theme from Scratch series, I’ll do a re-write of this article with better examples.