Building an Off Canvas Shopping Cart for WooCommerce

Woocommerce currently powers 29% of all e-commerce websites. That’s a pretty staggering number when you consider the amount of websites that are on the internet. So it’s no wonder that all kinds of extensions and add-ons exist for this great plugin.

While the team here at HIBR was working on the new website, we wondered how we could really make it unique. One such thing that crossed our minds was to develop a shopping cart that slid out from the side – similar to an off-canvas menu navigation pattern. After a quick google search it seemed that no one had already built and add-on or extension for this type of thing.

So we set out to build our own solution that would mimic the functionality found on this example.

Woocommerce Default Functionality

The default functionality for Woocommerce’s shopping cart sends a user to the ‘cart’ page first – this is where coupons can be applied, quantities adjusted, and items can be removed. From the ‘cart’ page the user moves to the ‘checkout’ page. The ‘checkout’ page is where the user can enter their payment information, their shipping information, create an account, and a few other things that can be adjusted by the site owner.

This process of moving from one page to the other was simply too many steps for our process. We only sell a few products and we keep things very simple. For our purpose, users don’t need to do things like create an account or select shipping rates. Our checkout process is very simple: users choose a product, selecting the quantity, then enter their payment information. So we set out to make this simplified process a reality.

Where Did We Start?

We started by building in the proper HTML, CSS, and JS to make the slide out cart work. For the purpose of this article, we’ll call it the “sidecart”. The sidecart HTML exists in the header.php file, while the CSS and JS exist in their appropriate files. The sidecart is hidden unless activated by one of two triggers:

  • an item is added to the cart
  • the cart icon in the header is clicked

The sidecart is always hidden via CSS. To do this we give the sidecart a width of 500px, then we set the position to absolute and give it a right position of -500px. This effectively moves the sidecart completely out of view.

Example of OffCanvas Sidecart


.sidecart {
  position: absolute;
  width: 500px;
  right: -500px;
}

Once a trigger is activated, we need the sidecart to come into view. To do this, we simply set the right position to zero like this: right: 0; In order to spice things up a bit, we then add a nice CSS transition that makes the sidecart “slide” into view, as opposed to abruptly appearing on the screen. We achieve this smooth transition like this: transition: right .3s linear; So how to do we activate a trigger? We’ll get to that in a bit. However I’ll let you in on a super simple way of making the sidecart open and close – simply add a class to the body tag. We’ll call that class “open”. Therefore the cart will open whenever the body has the class “open” and will close whenever the “open” class is removed from the body tag.


body.open .sidecart {
  right: 0;
}

So now that we’ve established the basics of how the sidecart can slide out and the essential elements that make it do that, we need to establish what should happen next.

Adding Content to the Sidecart

The entire premise of the sidecart relies upon AJAX. AJAX will allow the sidecart to slide out with all the proper information that it should be holding – without having to reload the entire page. We’ll start by taking a high level look at what we want to do, then dig in from there.

The first trigger that we determined would open the sidecart was when a product was added to the cart. On hibr.com, the only place you can add a product to the cart is on that product’s page. There’s one button on that page that traditionally adds the product to the cart and reloads the page. In Woocommerce there is a setting that enables AJAX when a product is added to the cart. The premise behind that is you can immediately go to the ‘cart’ page or simply stay on the product page once that button is clicked. However we want to do something different. We want to add a product to the cart and have the sidecart slide out immediately. We also might want a certain quantity added to the cart at the same time.

Woocommerce lets you add products to the cart via a query string in the URL. So if you wanted to add a simple pillow to your cart by just clicking a link, you could form a URL that looks like this: https://hibr.com/?add-to-cart=249 (the 249 is the product’s ID and will be unique for every product in Woocommerce.) We essentially hijack the “add to cart” button on the product page (https://hibr.com/product/simple-pillow/), then send an ajax request to that link (which would add that item to the cart), then open up the sidecart by adding the “open” class to the body tag. Then one last thing was necessary – we needed to have something inside the sidecart. Getting the actual cart table inside the sidecart will be the last step.

Unfortunately, sending an AJAX request using a pre-formatted URL like that with the product in the query string (?add-to-cart=249) doesn’t work perfectly in certain situations. It caused a conflict with other javascript. We needed to slightly different way to add add products to the cart that worked well with AJAX – simply using a POST request. We’re using jQuery, so .ajax was the perfect method to handle this situation. We were able to pass along the add-to-cart parameter as the ‘data’ for the ajax request.

To effectively “hijack” the button from working like it normally would, we used jQuery by attaching an on-click event handler and using e.preventDefault(); to stop the button from doing what it normally would do. Then we could tell the browser what to do from there. It looks something like this:


<script>
$('#single_add_ajax').click(function(e) {
  e.preventDefault();
  addToCart(productID, quanTity);
});
</script>

We also used a similar piece of javascript to open the sidecart once the cart icon in the header is clicked. The difference between this and the add to cart button is that when just the cart icon is clicked, it opens the sidecart and nothing else. It doesn’t add anything to the cart.

So the add to cart button is clicked, normal functionality is halted, the product is added to the cart via ajax, the sidecart opens – but then what is displayed within the sidecart? How do we get those contents from the cart into the sidecart?

Where the magic happens.

We created a page template within our theme that only held the contents from the Woocommerce cart, we could then pull in that HTML to the sidecart and display whatever we want. We now need the Woocommerce ‘cart’ code – which is pretty straight-forward.

Woocommerce provides a nice template structure whereas you can pull in these files to your own theme and customize them as you wish. We used the appropriate code located in the cart folder and made our own custom page template with just that cart code on it. For security reasons, I am not going to show that code 😉

An important part to note is that when you make the AJAX request – you are actually making that request directly to the page that holds the sidecart template code, then upon success of the AJAX call, will pull in the HTML from that page template and insert it into the sidecart div. The nice thing about a website running Woocommerce is that you can actually use any URL to post an AJAX request. For example, adding a product with this query: https://hibr.com/pillows/?add-to-cart=249 is the same as this query: https://hibr.com/product/simple-pillow/?add-to-cart=249

So once the AJAX request is made, the HTML from that page template is loaded to the sidecart, then the sidecart is opened (by simply adding the “open” class to the body tag).

Wrapping Up

So there you have it – sidecart functionality that is completely custom and built with Woocommerce. There are a ton of customizations here that you can do with your own site – ours is a very simple example of just how flexible Woocommerce can really be.