
One of the hottest extensions for Magento is the AJAX Quick Cart, a useful eCommerce feature that allows customers to quickly add a product to their cart without reloading the page or getting redirected to the checkout. In this tutorial I’m going to show you how to create your own AJAX cart from scratch. To see it in action, check out our premium Magento 1.6 theme.
Note: This tutorial requires the Quick View popup from our previous DIY Magento article – Create a Quick View for Your Magento Theme
In order to build an AJAX Quick Cart for Magento, we need to do the following:
- Set up our cart extension and override the checkout cart controller.
- Create the cart dropdown template which will show the cart products in a dropdown.
- Update our frontend layout (local.xml) to append the cart dropdown block to the store header.
- Update header.phtml to append the cart dropdown block to the store header.
- Use jQuery to make an AJAX post call after clicking the “Add to Cart” button in the Quick View popup.
- Use jQuery to attach a hover event to the header cart link.
- Use CSS to style the AJAX cart dropdown.
Create the Extension
The first thing we need to do is set up the folder structure for our extension. Follow the screenshot below and add the folders and files to your /app/code/local directory:

Now let’s override the checkout cart controller. We’re going to do 3 things:
- Override the index action to load the AJAX cart dropdown only if we make an AJAX request.
- Upon saving the cart, we want to redirect to the AJAX cart dropdown when making an AJAX request:
_goBack(). - Create a new function to return the AJAX cart dropdown block:
_sendSideCartHtml().
/app/code/local/FastDivision/QuickCart/controllers/Checkout/CartController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | <?php require_once('Mage/Checkout/controllers/CartController.php'); class FastDivision_QuickCart_Checkout_CartController extends Mage_Checkout_CartController { /** * Shopping cart display action */ public function indexAction() { $cart = $this->_getCart(); if ($cart->getQuote()->getItemsCount()) { $cart->init(); $cart->save(); if (!$this->_getQuote()->validateMinimumAmount()) { $warning = Mage::getStoreConfig('sales/minimum_order/description'); $cart->getCheckoutSession()->addNotice($warning); } } foreach ($cart->getQuote()->getMessages() as $message) { if ($message) { $cart->getCheckoutSession()->addMessage($message); } } /** * if customer enteres shopping cart we should mark quote * as modified bc he can has checkout page in another window. */ $this->_getSession()->setCartWasUpdated(true); // Quick Cart: If AJAX call, then return the cart dropdown HTML if ($this->getRequest()->isXmlHttpRequest()) { $this->_sendSideCartHtml(); } else { Varien_Profiler::start(__METHOD__ . 'cart_display'); $this ->loadLayout() ->_initLayoutMessages('checkout/session') ->_initLayoutMessages('catalog/session') ->getLayout()->getBlock('head')->setTitle($this->__('Shopping Cart')); $this->renderLayout(); Varien_Profiler::stop(__METHOD__ . 'cart_display'); } } /** * Set back redirect url to response * * @return Mage_Checkout_CartController */ protected function _goBack() { // Quick Cart: If AJAX call, then return the cart dropdown HTML if ($this->getRequest()->isXmlHttpRequest()) { $this->_sendSideCartHtml(); } else { $returnUrl = $this->getRequest()->getParam('return_url'); if ($returnUrl) { // clear layout messages in case of external url redirect if ($this->_isUrlInternal($returnUrl)) { $this->_getSession()->getMessages(true); } $this->getResponse()->setRedirect($returnUrl); } elseif (!Mage::getStoreConfig('checkout/cart/redirect_to_cart') && !$this->getRequest()->getParam('in_cart') && $backUrl = $this->_getRefererUrl() ) { $this->getResponse()->setRedirect($backUrl); } else { if (($this->getRequest()->getActionName() == 'add') && !$this->getRequest()->getParam('in_cart')) { $this->_getSession()->setContinueShoppingUrl($this->_getRefererUrl()); } $this->_redirect('checkout/cart'); } return $this; } } protected function _sendSideCartHtml() { // Return the Quick Cart's dropdown block $this->loadLayout(); $output = $this->getLayout()->getBlock('quickcart')->toHtml(); $this->getResponse()->setBody($output); } } |
Next we just need to edit the /etc/config.xml file. We’re simply overriding the /checkout frontend route in Magento to hit our controller before accessing the actions inherited from the Mage_Checkout_CartController.
/app/code/local/FastDivision/QuickCart/etc/config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml version="1.0"?> <config> <modules> <FastDivision_QuickCart> <version>0.1.0</version> </FastDivision_QuickCart> </modules> <frontend> <routers> <checkout> <args> <modules> <FastDivision_QuickCart before="Mage_Checkout">FastDivision_QuickCart_Checkout</FastDivision_QuickCart> </modules> </args> </checkout> </routers> </frontend> </config> |
Create the Cart Dropdown Block
The cart dropdown block will show a list of products in the customer’s cart when mousing over the header cart link.
/app/design/frontend/YOUR_THEME/template/checkout/cart/header.phtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?php if ($this->getIsNeedToDisplaySideBar()):?> <?php $_cartQty = $this->getSummaryCount() ?> <li class="cart"> <a href="<?php echo $this->getUrl('checkout/cart') ?>" class="cart-link"><?php echo $this->__('My Cart') ?> (<?php print (!empty($_cartQty)) ? $_cartQty : '0' ;?>)</a> <div class="quickcart"> <div class="quickcart-container"> <?php $_items = $this->getRecentItems($_cartQty); if(count($_items)): ?> <table> <?php foreach($_items as $_item): ?> <?php echo $this->getItemHtml($_item) ?> <?php endforeach; ?> </table> <div class="quickcart-checkout"> <a href="<?php echo $this->getCheckoutUrl() ?>"><span><?php echo $this->__('Proceed to Checkout') ?></span></a> </div> <?php else: ?> <p class="no-items-in-cart"><?php echo $this->__('You have no items in your shopping cart.') ?></p> <?php endif ?> </div> </div> </li> <?php endif ?> |
Update Your Magento Theme’s Local.xml
In order to display the cart dropdown in the header we need to edit the local.xml file for your theme. We’re also going to remove the existing cart link to make way for the new cart link in our block. If you don’t have a local.xml in your theme’s /layout directory, you can learn more about local.xml files here.
/app/design/frontend/YOUR_THEME/layout/local.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version="1.0"?> <layout version="0.1.0"> <default> <reference name="header"> <!-- Quick Cart Dropdown --> <block type="checkout/cart_sidebar" name="quickcart" template="checkout/cart/header.phtml"> <action method="addItemRender"><type>simple</type><block>checkout/cart_item_renderer</block><template>checkout/cart/sidebar/default.phtml</template></action> <action method="addItemRender"><type>grouped</type><block>checkout/cart_item_renderer_grouped</block><template>checkout/cart/sidebar/default.phtml</template></action> <action method="addItemRender"><type>configurable</type><block>checkout/cart_item_renderer_configurable</block><template>checkout/cart/sidebar/default.phtml</template></action> </block> </reference> <reference name="top.links"> <remove name="checkout_cart_link"/> </reference> </default> </layout> |
Update Your Magento Theme’s Store Header Template
After adding the cart dropdown block to your local.xml file we’ll need to render it in your theme’s header.phtml template file:
/app/design/frontend/base/YOUR_THEME/template/page/html/header.phtml
1 | <?php echo $this->getChildHtml('quickcart') ?> |
Add this line directly under <?php echo $this->getChildHtml('topLinks') ?>.
Write an AJAX Post Call Upon Clicking “Add to Cart” in the Quick View
If you followed our Quick View tutorial you should already have jQuery included in your Magento theme. We’re going to edit the Quick View block and add some code to the productAddToCartForm submit event:
/app/design/frontend/YOUR_THEME/template/catalog/ajax/product/view.phtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | var productAddToCartForm = new VarienForm('order-form'); productAddToCartForm.submit = function(button, url) { if (this.validator.validate()) { var form = this.form; var oldUrl = form.action; if (url) { form.action = url; } var e = null; try { $jQ.post('<?php echo $this->helper('checkout/cart')->getAddUrl($_product, array()) ?>', $jQ('#order-form').serialize(), function(data) { // Close quick view $jQ('.quick-view').trigger('close'); // Update quick cart $jQ('.header .cart').remove(); $jQ('.header .links').append(data); initQuickCart(); // Show quick cart temporarily to customer signifying cart addition $jQ('html, body').animate({ 'scrollTop': $jQ('.header .links').scrollTop() }, 500); $jQ('.header .cart').addClass('cart-active'); var showCartToUser = setTimeout(function() { $jQ('.header .cart').removeClass('cart-active'); }, 5000); }); } catch (e) { throw e; } this.form.action = oldUrl; if (e) { throw e; } if (button && button != 'undefined') { button.disabled = true; } return false; } }.bind(productAddToCartForm); function initQuickCart() { if($jQ('.quickcart').length && !$jQ('.no-items-in-cart').length) { $jQ('.cart').unbind().hoverIntent({ interval: 20, over: function() { $jQ(this).addClass('cart-active').find('.quickcart').show(); }, out: function() { $jQ(this).removeClass('cart-active').find('.quickcart').hide(); } }); } } |
$jQ.post makes an AJAX post to the product add to cart URL. It sends the form parameters from the Quick View order form. The post callback returns the quick cart dropdown block from /checkout/cart/header.phtml. We append the block to our Magento theme’s account menu and display the dropdown for 5 seconds to let the customer know that we added their product to the cart.
Cart Dropdown jQuery Hover Event
Now that we’ve created a way to add products to the cart via AJAX, built the dropdown block, and tied the Quick Cart and Quick View together, we need a way to show the dropdown after mousing over the cart link. I recommend creating a main.js file and making the initQuickCart() function available sitewide:
/js/YOUR_THEME/main.js
1 2 3 4 5 6 7 8 9 10 11 | $jQ(document).ready(function() { function initQuickCart() { if($jQ('.quickcart').length && !$jQ('.no-items-in-cart').length) { $jQ('.cart').hoverIntent({ interval: 20, over: function() { $jQ(this).addClass('cart-active').find('.quickcart').show(); }, out: function() { $jQ(this).removeClass('cart-active').find('.quickcart').hide(); } }); } } }); |
For the hover event I’m using hoverIntent for jQuery. Add hoverIntent to your Magento theme’s JavaScript directory and then load jquery.hoverIntent.minified.js and main.js in your local.xml file (preferably at the bottom of your “head” reference after loading jQuery):
1 2 3 4 5 6 7 8 9 | <?xml version="1.0"?> <layout> <default> <reference name="head"> <action method="addJs"><script>YOUR_THEME/jquery.hoverIntent.minified.js</script></action> <action method="addJs"><script>YOUR_THEME/main.js</script></action> </reference> </default> </layout> |
Style the AJAX Cart Dropdown
The last thing we need to do is style our Quick Cart dropdown with CSS. Add this code to your theme’s stylesheet and revise as you see fit:
1 2 3 4 5 | .quickcart { display: none; position: absolute; z-index: 9999; top: 36px; right: 0; padding: 0 0 4px 4px; background: #fff; } .cart-active .quickcart { display: block; } .quickcart-container { width: 380px; padding: 10px; font-size: 12px; font-weight: normal; text-transform: none; line-height: 1.3em; } .quickcart-checkout { margin: 10px 0 0 0; padding: 16px 0 8px 0; } .quickcart td { margin: 0 6px 0 0; padding: 10px 0 10px 0; color: #333; vertical-align: middle; } |
You should now have a working Quick Cart dropdown that allows customers to purchase products via the Quick View popup without going to the product page. If you have any questions or run into issues leave a comment.

