iFUEL INTERACTIVE

A NY Interactive Agency and a Division of Agency212

See you on Flickr See you on Twitter See you on FaceBook Subscribe
Adding to the Cart with a jQuery Ajax Call in Magento
September 10th, 2009  |  11 COMMENTS  |  Development, Magento
Tags: , , ,

So, Ajax being the thing and all, I was hunting for a way to add an item to the cart using an Ajax call in Magento.  Recently, I noticed there was a module that apparently does this, but either I hadn’t seen that or it didn’t exist yet when I wrote this, so I hacked my way through it.

PHP isn’t my primary language – I come from the ASP, ASP.Net, C# world, but Magento was compelling enough that I’ve taken the leap.  I’m sure there are lots of things I could be doing better/differently here so if you’ve got some suggestions, I’m all ears!

Add to Cart Page

So first I needed an “Add to Cart” page (called – addToCart.php) that could be called from the client.  This page returns a result in JSON format.  The actual page also returns related items so we can try to cross sell the user, but I’ve removed that in this sample to make it simpler.


<?php

include_once '../app/Mage.php';

Mage::app();

try{
// usage /scripts/addToCart.php?product_id=838&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;qty=1
// product_id OR sku is required

// get query string
if (!isset($_GET['sku'])) { $sku = ''; } else { $sku = $_GET['sku']; }
if (!isset($_GET['product_id'])) { $product_id = ''; } else { $product_id = $_GET['product_id']; }
if (!isset($_GET['qty'])) { $qty = '1'; } else { $qty = $_GET['qty']; }

if ($sku != ""){
$product_id = Mage::getModel('catalog/product')->getIdBySku("$sku");
if ($product_id == '') {
$session->addError("<strong>Product Not Added</strong><br />The SKU you entered ($sku) was not found.");
}
}

$request = Mage::app()->getRequest();

$product = Mage::getModel('catalog/product')->load($product_id);

$session = Mage::getSingleton('core/session', array('name'=>'frontend'));
$cart = Mage::helper('checkout/cart')->getCart();

$cart->addProduct($product, $qty);

$session->setLastAddedProductId($product->getId());
$session->setCartWasUpdated(true);

$cart->save();

$result = "{'result':'success'}";

echo $result;

} catch (Exception $e) {
$result = "{'result':'error'";
$result .= ", 'message': '".$e->getMessage()."'}";
echo $result;
}

Buy Now Button

Then I need a “Buy Now” button that doesn’t do a post to the server that I can attach my jQuery code to.  I’ve added the sku as an attribute to the anchor because I have this in a page that has more than one product on the page and I need to know which product has been selected.


<a href="#" sku="<?php echo $this->__($product->sku) ?>"><img src="/media/upload/image/product-details/buy-now.jpg" border=0 alt="<?php echo $this->__('Buy Now') ?>"></a>

Client Script

Finally, I need the client script that gets attached to the button and calls the server “addToCart.php” page.


/* Cart */
jQuery(document).ready(function($) {
$.ui.dialog.defaults.bgiframe = true;

$(".add-to-cart").click(function(e){
var buyNow = $(e.currentTarget);
var listingItem = $(buyNow).closest(".listing-item");
var colorSelector = $("#colorSelector", listingItem);
var product_id = colorSelector.val();

if (product_id == ""){
showDialog("Please select a color.", "Missing Information");
return false;
}

var stockStatus = $("option:selected", colorSelector).attr("stockstatus");
if (stockStatus == "out of stock"){
showDialog("Sorry, that colour is currently unavailable.", "Out of Stock")
return false;
}

var qty = $("#quantity", listingItem).val();

if (qty == ""){
qty = "1";
}

$(this).siblings(".ajax-loader").show();
var obj = this;

var params = "product_id=" + product_id + "&amp;amp;amp;amp;amp;qty=" + qty;

var result = $.getJSON("/scripts/addToCart.php", params, function(data, textStatus){
$(obj).siblings(".ajax-loader").hide();

if (textStatus == "error"){
showDialog("There was an error adding this item to your cart.  Please call customer service for assistance.", "Error");
return;
}

if (data.result == "error"){
showDialog("Sorry, an error occurred while adding the item to your cart.  The error was: '" + data.message + "'");
return;
}

// SHOW FEEDBACK, ERRORS AND RELATED ITEMS
} // end add to cart

function showDialog(msg, title){
$("#dialog").dialog( 'destroy' );
$("#dialog").html(msg);

$("#dialog").dialog({
buttons: {
"Ok": function() {
$(this).dialog("close");
}
}
// , closeOnEscape: true
// , show: 'slide'
});

$('#dialog').dialog('option', 'title', title);
$("#dialog").dialog('open');
}
});

Few things probably need some explanation:

1. I’ve attached the function to ALL add to cart buttons using the “add-to-cart” class.  (There are multiple products on the page.)

2. Each product has a color selector that has the product_id as the value in the drop down.  There’s also an additional attribute called “stockstatus” that will let me know if the color is out of stock.  My customer didn’t want to hide the out of stock colors, but I obviously can’t let anyone order them.

3. I put a little animated gif (the “ajax loader”) on the page and that gets displayed when the ajax call is being made.

4. If there is an error, I display it using the jQuery UI library and a little showdialog helper function.

5. There’s a feedback panel that shows related items, but I’ve removed that in this code just to make it easier to follow.

So there it is.  Hope this helps someone.  And if there are better ways to do this, I’d love to hear them!

[Update:  I removed the reference to common.php in the code above because it's not needed.  It had some common user functions in it that aren't necessary for this sample]

COMMENTS

  • You just saved me a lot of time. Thanks so much!

  • Andy

    Hey,

    Where is the script being stored and what is the common.php file? Great article by the way!

    • Sorry, should have included that. Common.php is where I have some shared functions. I simplified the code for this article when I originally posted it, so you shouldn’t actually need it anymore.

      I posted it in a folder off the root of my site, but you could really put it anywhere as long as you have the following line correct in your client script:

      var result = $.getJSON(“/scripts/addToCart.php”, params, function(data, textStatus){

      Thanks for the feedback. Really glad you found it helpful!

  • Sam

    This looks like it could be very useful! Where do you put the addToCart.php file?

    • I have the addToCart.php in a folder off the root of my site (see previous comment and reply). Shouldn’t really matter where you have it as long as you have the getJSON call pointing to the right location.

  • Sam

    Hmmmm…still no joy getting this going. Does it require jQuery UI to work correctly?

    I placed the buy now link and the script in default/template/catalog/product/list.phtml. But I get an error if I don’t change $product to $_product as that’s what the default template uses. I’m guessing it’s because I’m not using a color selector, so that bits redundant?

    Also, I suppose the buy now button should have a class of “add-to-cart”? And that it needs to be used with the list view and not grid, as grid doesn’t use the “listing-item” class?

    Any chance you can strip out the custom attributes (#colorSelector) and just use the simplest setup in your example?

    • Hi Sam -

      I’ll try to put together a cleaner version of the code for you. Yes, I do use jquery.ui. I tried to simplify it for the original post and all I succeeded in doing was confusing people. Sorry!

      Andy

  • Sam

    Oh, and just for your own reference, there is a free extension that does this now, but your version seems much simpler (http://www.magentocommerce.com/extension/2101/j2t-ajax-cart)

  • Avril Kuree

    Rather nice place you’ve got here. Thanx for it. I would like to read more on that blog soon.

  • [...] code was based on work found at iFuel Interactive’s Adding to the Cart with a jQuery Ajax Call in Magento. I’ve modified the code to use php’s json_encode() function. I believe that, as [...]

LEAVE COMMENT
Your name:  (required)

Your email:  (required, will not be published)

Website:  (not required)

Message:  (required)

Categories
Archives
Tags
From Our Twitter (@ifuel)
Our Interactive Agency on Facebook
Copyright iFuel Interactive © 2010. All Rights Reserved.
Going up? Click here.A NY INTERACTIVE AGENCY