Vous êtes sur la page 1sur 46

Ajax Based Product Add to Cart from Category Page

By Manish Prakash in Magento, Modules


Oct 23 rd, 2011 59 Comments
In this blog post we will see how to add products to shopping cart directly from
category page using ajax operations.

We would be able to add all product types simple,configurable,bundled,grouped,


virtual and downloadable from the category page itself. For the products which
require options to be selected before adding to cart e.g configurable,bundled etc ,
a lightbox iframe window will show up showing the options to be selected by user
with a ‘Add to Cart’ button.
This blog is in continuation of the previous blog written, the same code base has
been used and new coded is added. So it would be better to once go through the
previous blog as well. Here are screen shots of the module in action, just so you
know what we are going to develop.
Downloadable Product Add to Cart

Downloadable Product Add to Cart


Virtual Product Category Page Add to Cart

Virtual Product Category Page Add to Cart


Magento Bundled Product Add to Cart

Magento Bundled Product Add to Cart


Grouped Product Add to Cart

Grouped Product Add to Cart


Category Page Simple Product

Category Page Simple Product


Configurable Product with Custom Options

Configurable Product with Custom Options

Attached is source code for this module


Magneto version 1.6(+)
[dm]17[/dm]
Magneto version 1.6(-)
[dm]18[/dm]
Now let see what all we need to do, to achieve the above.
Step1: Override list.phtml

First we will have to override the list.phtml file and create our own list.phtml
file in our module. In default theme, the list.phtml has this code written on the
‘Add to Cart’ button
1

onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"

The setLocation function simply redirects to another page. We cannot use this,
since we need to have ajax. Now we will have to call another function instead of
setLocation which will make an ajax call instead of page redirect. For the ajax
calls we are going to use the jQuery library just like the previous blog. Let name
our new function setLocationAjax(), so in no our code will be
1

onclick="setLocationAjax('<?php echo $this->getAddToCartUrl($_product) ?>')"


We also need to do is put a ajax loading icon next to the add to cart button, and
when the ajax button is clicked the loading should show up. So the final code for
our ‘Add to Cart’ button would be
1
2
3

<p><button type="button" title="<?php echo $this->__('Add to Cart') ?>"


class="button btn-cart" onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?
php echo $this->__('Add to Cart') ?></span></span></button></p>

<span id='ajax_loader<?php echo $_product->getId()?>' style='display:none'><img


src='<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif')?>'/></span>

Here the setLocationAjax has two parameters, first is the add to cart url and
second is the product id. The second parameter is actually required to identify the
loading image placed next to the add to cart button. If you see the id of the ajax
loader image it is id=’ajax_loadergetId()?>’. So based on the product id, we can
hide/show the correct ajax loading image.
But still this code is not complete, we still have to check if the product has some
options (configurable, grouped, bundled, custom options). If the product has
required options, the add to cart will not work until the options have been
selected by the user. So what we will do is check if the product has required
options then show a lightbox with the options only, so that user can select the
options and add the product to cart. Here is the complete code for the ‘Add to
Cart’ button.
1
2
3
4
5
6
7

<?php if ( !($_product->getTypeInstance(true)->hasRequiredOptions($_product) ||
$_product->isGrouped()) ) { ?>
<p><button type="button" title="<?php echo $this->__('Add
to Cart') ?>" class="button btn-cart" onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?
php echo $this->__('Add to Cart') ?></span></span></button></p>
<span id='ajax_loader<?php echo $_product->getId()?>'
style='display:none'><img src='<?php echo $this->getSkinUrl('images/opc-ajax-
loader.gif')?>'/></span>
<?php } else { ?>
<button type="button" title="<?php echo $this->__('Add
to Cart') ?>" class="button btn-cart" onclick="showOptions('<?php echo $_product-
>getId()?>')"><span><span><?php echo $this->__('Add to Cart') ?
></span></span></button>
<a href='<?php echo $this-
>getUrl('ajax/index/options',array('product_id'=>$_product->getId()));?>'
class='fancybox' id='fancybox<?php echo $_product->getId()?>'
style='display:none'>Test</a>
<?php } ?>

If you look in default what we have done here is, put an if condition to check if
product has required options or is a grouped product. If this is true then we then
the ‘Add to Cart’ button has showOptions function and an anchor tag for the
lightbox. If the condition is false then the default ‘Add to Cart’ button is shown
with setLocationAjax() option and the ajax image loader.
The complete list.phtml file is found the in the attached module.
Step2: Javascript

Next in our list.phtml file we need to put in lot of javascript to the following

Initialize Fancybox
For Products which have options, fancybox with iframe should show up when click
on ‘Add to Cart’ button
For Product which don’t have options, product should be added to cart through
Ajax
The top links and cart sidebar should be updated after successful ‘Add to Cart’

First we will download the fancybox library and then unpack the files in our skin
folder i.e skin\frontend\default\default\js\fancybox
Next to add fancybox to category pages add this code to the theme layout file, in
my case ajax.xml
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

<catalog_category_default>
<reference name="head">
<action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action>
<action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
<action method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action>
</reference>
<reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion>
</reference>
</catalog_category_default>
<catalog_category_layered>
<reference name="head">
<action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action>
<action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
<action method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action>
</reference>
<reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion>
</reference>
</catalog_category_layered>

Now when you open the category page, using firebug check if the fancybox library is
loaded or not.
Here is code to initialize fancybox for all anchor tags with ‘fancybox’ class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

jQuery(document).ready(function(){
jQuery('.fancybox').fancybox(
{
hideOnContentClick : true,
width: 382,
autoDimensions: true,
type : 'iframe',
showTitle: false,
scrolling: 'no',
onComplete: function(){ //Resize the iframe to correct size
jQuery('#fancybox-frame').load(function() { // wait for frame to
load and then gets it's height
jQuery('#fancybox-
content').height(jQuery(this).contents().find('body').height()+30);
jQuery.fancybox.resize();
});

}
}
);
});

Here is code of the showOptions() function. This will show fancybox with the iframe
URL when click on ‘Add to Cart’.
1
2
3

function showOptions(id){
jQuery('#fancybox'+id).trigger('click');
}

Here is code to to add to product to cart using ajax which don’t have any options
like simple and virtual products.
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

function setAjaxData(data,iframe){
if(data.status == 'ERROR'){
alert(data.message);
}else{
if(jQuery('.block-cart')){
jQuery('.block-cart').replaceWith(data.sidebar);
}
if(jQuery('.header .links')){
jQuery('.header .links').replaceWith(data.toplink);
}
jQuery.fancybox.close();
}
}
function setLocationAjax(url,id){
url += 'isAjax/1';
url = url.replace("checkout/cart","ajax/index");
jQuery('#ajax_loader'+id).show();
try {
jQuery.ajax( {
url : url,
dataType : 'json',
success : function(data) {
jQuery('#ajax_loader'+id).hide();
setAjaxData(data,false);
}
});
} catch (e) {
}
}
Step3: Controller

Now in our controller file we need to put in code first for our
ajax/index/addAction . The same code as the previous blog is used here without any
changes, so i am just pasting the code here
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

public function addAction()


{
$cart = $this->_getCart();
$params = $this->getRequest()->getParams();
if($params['isAjax'] == 1){
$response = array();
try {
if (isset($params['qty'])) {
$filter = new Zend_Filter_LocalizedToNormalized(
array('locale' => Mage::app()->getLocale()->getLocaleCode())
);
$params['qty'] = $filter->filter($params['qty']);
}

$product = $this->_initProduct();
$related = $this->getRequest()->getParam('related_product');

/**
* Check product availability
*/
if (!$product) {
$response['status'] = 'ERROR';
$response['message'] = $this->__('Unable to find Product ID');
}

$cart->addProduct($product, $params);
if (!empty($related)) {
$cart->addProductsByIds(explode(',', $related));
}

$cart->save();

$this->_getSession()->setCartWasUpdated(true);

/**
* @todo remove wishlist observer processAddToCart
*/
Mage::dispatchEvent('checkout_cart_add_product_complete',
array('product' => $product, 'request' => $this->getRequest(),
'response' => $this->getResponse())
);

if (!$cart->getQuote()->getHasError()){
$message = $this->__('%s was added to your shopping cart.',
Mage::helper('core')->htmlEscape($product->getName()));
$response['status'] = 'SUCCESS';
$response['message'] = $message;
//New Code Here
$this->loadLayout();
$toplink = $this->getLayout()->getBlock('top.links')->toHtml();
$sidebar_block = $this->getLayout()->getBlock('cart_sidebar');
Mage::register('referrer_url', $this->_getRefererUrl());
$sidebar = $sidebar_block->toHtml();
$response['toplink'] = $toplink;
$response['sidebar'] = $sidebar;
}
} catch (Mage_Core_Exception $e) {
$msg = "";
if ($this->_getSession()->getUseNotice(true)) {
$msg = $e->getMessage();
} else {
$messages = array_unique(explode("\n", $e->getMessage()));
foreach ($messages as $message) {
$msg .= $message.'<br/>';
}
}

$response['status'] = 'ERROR';
$response['message'] = $msg;
} catch (Exception $e) {
$response['status'] = 'ERROR';
$response['message'] = $this->__('Cannot add the item to shopping
cart.');
Mage::logException($e);
}
$this->getResponse()->setBody(Mage::helper('core')-
>jsonEncode($response));
return;
}else{
return parent::addAction();
}
}
Options Iframe inside Fancybox

We will now see the code of the iframe which shows up inside the fancybox. The URL
of the iframe is ajax/index/options. So so we will edit the controller file and add
this code
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

public function optionsAction(){


$productId = $this->getRequest()->getParam('product_id');
// Prepare helper and params
$viewHelper = Mage::helper('catalog/product_view');

$params = new Varien_Object();


$params->setCategoryId(false);
$params->setSpecifyOptions(false);

// Render page
try {
$viewHelper->prepareAndRender($productId, $this, $params);
} catch (Exception $e) {
if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) {
if (isset($_GET['store']) && !$this->getResponse()->isRedirect())
{
$this->_redirect('');
} elseif (!$this->getResponse()->isRedirect()) {
$this->_forward('noRoute');
}
} else {
Mage::logException($e);
$this->_forward('noRoute');
}
}
}

This code is taking from the catalog/product/view action. In short, what this code
does is loadLayout() and renderLayout(). But it loads proper handles depending on
product type, i.e for configurable product it will load the handle
PRODUCT_TYPE_configurable from the catalog.xml
Next we need to add code in the layout file for the action ajax/index/options
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

<ajax_index_options>
<reference name="root">
<action
method="setTemplate"><template>page/empty.phtml</template></action>
</reference>
<reference name="head">
<action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action>
<action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
</reference>
<reference name="head">
<action method="addJs"><script>varien/product.js</script></action>
<action method="addJs"><script>varien/configurable.js</script></action>

<action method="addItem"><type>js_css</type><name>calendar/calendar-
win2k-1.css</name><params/><!--<if/><condition>can_load_calendar_js</condition>--
></action>
<action
method="addItem"><type>js</type><name>calendar/calendar.js</name><!--
<params/><if/><condition>can_load_calendar_js</condition>--></action>
<action method="addItem"><type>js</type><name>calendar/calendar-
setup.js</name><!--<params/><if/><condition>can_load_calendar_js</condition>--
></action>
</reference>
<reference name="content">
<block type="catalog/product_view" name="product.info"
template="ajax/catalog/product/options.phtml">
<!--
<action
method="addReviewSummaryTemplate"><type>default</type><template>review/helper/summa
ry.phtml</template></action>
<action
method="addReviewSummaryTemplate"><type>short</type><template>review/helper/summary
_short.phtml</template></action>
<action
method="addReviewSummaryTemplate"><type>...</type><template>...</template></action>
-->

<block type="catalog/product_view" name="product.info.addtocart"


as="addtocart" template="ajax/catalog/product/view/addtocart.phtml"/>

<block type="catalog/product_view"
name="product.info.options.wrapper" as="product_options_wrapper"
template="catalog/product/view/options/wrapper.phtml" translate="label">
<label>Info Column Options Wrapper</label>
<block type="core/template" name="options_js"
template="catalog/product/view/options/js.phtml"/>
<block type="catalog/product_view_options"
name="product.info.options" as="product_options"
template="catalog/product/view/options.phtml">
<action
method="addOptionRenderer"><type>text</type><block>catalog/product_view_options_typ
e_text</block><template>catalog/product/view/options/type/text.phtml</template></ac
tion>
<action
method="addOptionRenderer"><type>file</type><block>catalog/product_view_options_typ
e_file</block><template>catalog/product/view/options/type/file.phtml</template></ac
tion>
<action
method="addOptionRenderer"><type>select</type><block>catalog/product_view_options_t
ype_select</block><template>catalog/product/view/options/type/select.phtml</templat
e></action>
<action
method="addOptionRenderer"><type>date</type><block>catalog/product_view_options_typ
e_date</block><template>catalog/product/view/options/type/date.phtml</template></ac
tion>
</block>
<block type="core/html_calendar" name="html_calendar"
as="html_calendar" template="page/js/calendar.phtml"/>
</block>
<block type="catalog/product_view"
name="product.info.options.wrapper.bottom" as="product_options_wrapper_bottom"
template="catalog/product/view/options/wrapper/bottom.phtml" translate="label">
<label>Bottom Block Options Wrapper</label>
<action
method="insert"><block>product.tierprices</block></action>
<block type="catalog/product_view" name="product.clone_prices"
as="prices" template="catalog/product/view/price_clone.phtml"/>
<action
method="append"><block>product.info.addtocart</block></action>
<action
method="append"><block>product.info.addto</block></action>
</block>

<block type="core/template_facade" name="product.info.container1"


as="container1">
<action
method="setDataByKey"><key>alias_in_layout</key><value>container1</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action>
<action
method="append"><block>product.info.options.wrapper</block></action>
<action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block>
<block type="core/template_facade" name="product.info.container2"
as="container2">
<action
method="setDataByKey"><key>alias_in_layout</key><value>container2</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action>
<action
method="append"><block>product.info.options.wrapper</block></action>
<action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block>
<action
method="unsetCallChild"><child>container1</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action>
<action
method="unsetCallChild"><child>container2</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action>
</block>
</reference>
</ajax_index_options>

This code is similar to the <catalog_product_view> layout, except i have removed


some blocks like description, attributes which are not required.
Next we need to add code to the options.phtml file used in the above block.
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

<style>
<!--
body.ajax-index-options{
width:380px;
padding:0px;
margin:0px;
}
body.ajax-index-options .product-shop .product-options-bottom .price-box{
float:left;
}
-->
</style>
<?php $_helper = $this->helper('catalog/output'); ?>
<?php $_product = $this->getProduct(); ?>
<script type="text/javascript">
var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?
>);
</script>
<div class="product-view" style="width:380px">
<div class="product-essential" style="width:330px">
<form action="<?php echo $this->getSubmitUrl($_product) ?>" method="post"
id="product_addtocart_form"<?php if($_product->getOptions()): ?>
enctype="multipart/form-data"<?php endif; ?>>
<div class="no-display">
<input type="hidden" name="product" value="<?php echo $_product-
>getId() ?>" />
<input type="hidden" name="related_product" id="related-products-field"
value="" />
</div>

<div class="product-shop">
<div class="product-name">
<h1><?php echo $_helper->productAttribute($_product, $_product-
>getName(), 'name') ?></h1>
</div>

<?php echo $this->getChildHtml('product_type_data') ?>

<?php if (!$this->hasOptions()):?>
<div class="add-to-box">
<?php if($_product->isSaleable()): ?>
<?php echo $this->getChildHtml('addtocart') ?>
<?php endif; ?>
</div>
<?php endif; ?>

<?php if ($_product->isSaleable() && $this->hasOptions()):?>


<?php echo $this->getChildChildHtml('container1', '', true, true) ?
>
<?php endif;?>

</div>
<div class="clearer"></div>
<?php if ($_product->isSaleable() && $this->hasOptions()):?>
<?php echo $this->getChildChildHtml('container2', '', true, true) ?>
<?php endif;?>
</form>
<script type="text/javascript">
//<![CDATA[
var productAddToCartForm = new VarienForm('product_addtocart_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;
// Start of our new ajax code
if (!url) {
url = jQuery('#product_addtocart_form').attr('action');
}
url = url.replace("checkout/cart","ajax/index"); // New Code
var data = jQuery('#product_addtocart_form').serialize();
data += '&isAjax=1';
jQuery('#ajax_loader').show();
try {
jQuery.ajax( {
url : url,
dataType : 'json',
type : 'post',
data : data,
success : function(data) {
jQuery('#ajax_loader').hide();
parent.setAjaxData(data,true);
}
});
} catch (e) {
}
// End of our new ajax code
this.form.action = oldUrl;
if (e) {
throw e;
}
}
}.bind(productAddToCartForm);
productAddToCartForm.submitLight = function(button, url){
if(this.validator) {
var nv = Validation.methods;
delete Validation.methods['required-entry'];
delete Validation.methods['validate-one-required'];
delete Validation.methods['validate-one-required-by-name'];
if (this.validator.validate()) {
if (url) {
this.form.action = url;
}
this.form.submit();
}
Object.extend(Validation.methods, nv);
}
}.bind(productAddToCartForm);
//]]>
</script>
</div>
</div>

This is all that is required. This module has been tested in magento 1.6 version
only, but should work on all magento version. Please provide comments if something
is missing or bugs show up, so that we can improve this free module.
Share this:

Save

Like this:
Loading...
Tags ajaxajax add to cart
Magento Onestep Checkout – Remove Payment and Shipping Method Step
Ajax Based Add Product to Wishlist and Compare Products
Related Articles.
Ajax Based Add Product to Wishlist and Compare Products
27 Oct, 2011
Add Product to Shopping Cart using Ajax
04 Oct, 2011
My Blogs

Magento
PhoneGap
NodeJS
Magento Certified Developer Guide

RECOMMEND US
Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new
posts by email.

Join 3,584 other subscribers

Email Address
Extensions Source
Search
Most Popular Posts

Magento Add Fee or Discount to Order Totals (181)


Add Product to Shopping Cart using Ajax (152)
Magento Create Custom Payment Method (119)
Add Custom Fields to Customer Account - Magento 1.7 (104)
Magento Create Custom Shipping Method (95)

BLOG CATEGORIES

EC2 (2)
Facebook (4)
Magento (90)
Admin Module Development (5)
EAV and Flat Tables (3)
Magento API (3)
Module Development Series (12)
Modules (13)
Nuts & Bolts (18)
Onepage Checkout (8)
Payment Method (2)
Shipping Method (3)
Tips and Snippets (18)
Magento2 (2)
Magento2 Admin Development Series (4)
Magento2 Module Development Series (5)
Magento2 Quickies (4)
Magento2 Theme Development (2)
Mobile App Development (8)
Uncategorized (3)

PriceGenie. My Experiments with Robotics. Manish Prakash

Ajax Based Product Add to Cart from Category Page


By Manish Prakash in Magento, Modules
Oct 23 rd, 2011 59 Comments
In this blog post we will see how to add products to shopping cart directly from
category page using ajax operations.

We would be able to add all product types simple,configurable,bundled,grouped,


virtual and downloadable from the category page itself. For the products which
require options to be selected before adding to cart e.g configurable,bundled etc ,
a lightbox iframe window will show up showing the options to be selected by user
with a ‘Add to Cart’ button.
This blog is in continuation of the previous blog written, the same code base has
been used and new coded is added. So it would be better to once go through the
previous blog as well. Here are screen shots of the module in action, just so you
know what we are going to develop.
Downloadable Product Add to Cart

Downloadable Product Add to Cart


Virtual Product Category Page Add to Cart

Virtual Product Category Page Add to Cart


Magento Bundled Product Add to Cart

Magento Bundled Product Add to Cart


Grouped Product Add to Cart

Grouped Product Add to Cart


Category Page Simple Product

Category Page Simple Product


Configurable Product with Custom Options

Configurable Product with Custom Options

Attached is source code for this module


Magneto version 1.6(+)
[dm]17[/dm]
Magneto version 1.6(-)
[dm]18[/dm]
Now let see what all we need to do, to achieve the above.
Step1: Override list.phtml

First we will have to override the list.phtml file and create our own list.phtml
file in our module. In default theme, the list.phtml has this code written on the
‘Add to Cart’ button
1

onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')"

The setLocation function simply redirects to another page. We cannot use this,
since we need to have ajax. Now we will have to call another function instead of
setLocation which will make an ajax call instead of page redirect. For the ajax
calls we are going to use the jQuery library just like the previous blog. Let name
our new function setLocationAjax(), so in no our code will be
1

onclick="setLocationAjax('<?php echo $this->getAddToCartUrl($_product) ?>')"

We also need to do is put a ajax loading icon next to the add to cart button, and
when the ajax button is clicked the loading should show up. So the final code for
our ‘Add to Cart’ button would be
1
2
3

<p><button type="button" title="<?php echo $this->__('Add to Cart') ?>"


class="button btn-cart" onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?
php echo $this->__('Add to Cart') ?></span></span></button></p>

<span id='ajax_loader<?php echo $_product->getId()?>' style='display:none'><img


src='<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif')?>'/></span>

Here the setLocationAjax has two parameters, first is the add to cart url and
second is the product id. The second parameter is actually required to identify the
loading image placed next to the add to cart button. If you see the id of the ajax
loader image it is id=’ajax_loadergetId()?>’. So based on the product id, we can
hide/show the correct ajax loading image.
But still this code is not complete, we still have to check if the product has some
options (configurable, grouped, bundled, custom options). If the product has
required options, the add to cart will not work until the options have been
selected by the user. So what we will do is check if the product has required
options then show a lightbox with the options only, so that user can select the
options and add the product to cart. Here is the complete code for the ‘Add to
Cart’ button.
1
2
3
4
5
6
7

<?php if ( !($_product->getTypeInstance(true)->hasRequiredOptions($_product) ||
$_product->isGrouped()) ) { ?>
<p><button type="button" title="<?php echo $this->__('Add
to Cart') ?>" class="button btn-cart" onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?
php echo $this->__('Add to Cart') ?></span></span></button></p>
<span id='ajax_loader<?php echo $_product->getId()?>'
style='display:none'><img src='<?php echo $this->getSkinUrl('images/opc-ajax-
loader.gif')?>'/></span>
<?php } else { ?>
<button type="button" title="<?php echo $this->__('Add
to Cart') ?>" class="button btn-cart" onclick="showOptions('<?php echo $_product-
>getId()?>')"><span><span><?php echo $this->__('Add to Cart') ?
></span></span></button>
<a href='<?php echo $this-
>getUrl('ajax/index/options',array('product_id'=>$_product->getId()));?>'
class='fancybox' id='fancybox<?php echo $_product->getId()?>'
style='display:none'>Test</a>
<?php } ?>

If you look in default what we have done here is, put an if condition to check if
product has required options or is a grouped product. If this is true then we then
the ‘Add to Cart’ button has showOptions function and an anchor tag for the
lightbox. If the condition is false then the default ‘Add to Cart’ button is shown
with setLocationAjax() option and the ajax image loader.
The complete list.phtml file is found the in the attached module.
Step2: Javascript

Next in our list.phtml file we need to put in lot of javascript to the following

Initialize Fancybox
For Products which have options, fancybox with iframe should show up when click
on ‘Add to Cart’ button
For Product which don’t have options, product should be added to cart through
Ajax
The top links and cart sidebar should be updated after successful ‘Add to Cart’

First we will download the fancybox library and then unpack the files in our skin
folder i.e skin\frontend\default\default\js\fancybox
Next to add fancybox to category pages add this code to the theme layout file, in
my case ajax.xml
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

<catalog_category_default>
<reference name="head">
<action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action>
<action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
<action method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action>
</reference>
<reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion>
</reference>
</catalog_category_default>
<catalog_category_layered>
<reference name="head">
<action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action>
<action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action>
<action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
<action method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action>
</reference>
<reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion>
</reference>
</catalog_category_layered>

Now when you open the category page, using firebug check if the fancybox library is
loaded or not.
Here is code to initialize fancybox for all anchor tags with ‘fancybox’ class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

jQuery(document).ready(function(){
jQuery('.fancybox').fancybox(
{
hideOnContentClick : true,
width: 382,
autoDimensions: true,
type : 'iframe',
showTitle: false,
scrolling: 'no',
onComplete: function(){ //Resize the iframe to correct size
jQuery('#fancybox-frame').load(function() { // wait for frame to
load and then gets it's height
jQuery('#fancybox-
content').height(jQuery(this).contents().find('body').height()+30);
jQuery.fancybox.resize();
});

}
}
);
});

Here is code of the showOptions() function. This will show fancybox with the iframe
URL when click on ‘Add to Cart’.
1
2
3
function showOptions(id){
jQuery('#fancybox'+id).trigger('click');
}

Here is code to to add to product to cart using ajax which don’t have any options
like simple and virtual products.
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

function setAjaxData(data,iframe){
if(data.status == 'ERROR'){
alert(data.message);
}else{
if(jQuery('.block-cart')){
jQuery('.block-cart').replaceWith(data.sidebar);
}
if(jQuery('.header .links')){
jQuery('.header .links').replaceWith(data.toplink);
}
jQuery.fancybox.close();
}
}
function setLocationAjax(url,id){
url += 'isAjax/1';
url = url.replace("checkout/cart","ajax/index");
jQuery('#ajax_loader'+id).show();
try {
jQuery.ajax( {
url : url,
dataType : 'json',
success : function(data) {
jQuery('#ajax_loader'+id).hide();
setAjaxData(data,false);
}
});
} catch (e) {
}
}
Step3: Controller

Now in our controller file we need to put in code first for our
ajax/index/addAction . The same code as the previous blog is used here without any
changes, so i am just pasting the code here
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

public function addAction()


{
$cart = $this->_getCart();
$params = $this->getRequest()->getParams();
if($params['isAjax'] == 1){
$response = array();
try {
if (isset($params['qty'])) {
$filter = new Zend_Filter_LocalizedToNormalized(
array('locale' => Mage::app()->getLocale()->getLocaleCode())
);
$params['qty'] = $filter->filter($params['qty']);
}

$product = $this->_initProduct();
$related = $this->getRequest()->getParam('related_product');

/**
* Check product availability
*/
if (!$product) {
$response['status'] = 'ERROR';
$response['message'] = $this->__('Unable to find Product ID');
}

$cart->addProduct($product, $params);
if (!empty($related)) {
$cart->addProductsByIds(explode(',', $related));
}

$cart->save();

$this->_getSession()->setCartWasUpdated(true);

/**
* @todo remove wishlist observer processAddToCart
*/
Mage::dispatchEvent('checkout_cart_add_product_complete',
array('product' => $product, 'request' => $this->getRequest(),
'response' => $this->getResponse())
);

if (!$cart->getQuote()->getHasError()){
$message = $this->__('%s was added to your shopping cart.',
Mage::helper('core')->htmlEscape($product->getName()));
$response['status'] = 'SUCCESS';
$response['message'] = $message;
//New Code Here
$this->loadLayout();
$toplink = $this->getLayout()->getBlock('top.links')->toHtml();
$sidebar_block = $this->getLayout()->getBlock('cart_sidebar');
Mage::register('referrer_url', $this->_getRefererUrl());
$sidebar = $sidebar_block->toHtml();
$response['toplink'] = $toplink;
$response['sidebar'] = $sidebar;
}
} catch (Mage_Core_Exception $e) {
$msg = "";
if ($this->_getSession()->getUseNotice(true)) {
$msg = $e->getMessage();
} else {
$messages = array_unique(explode("\n", $e->getMessage()));
foreach ($messages as $message) {
$msg .= $message.'<br/>';
}
}

$response['status'] = 'ERROR';
$response['message'] = $msg;
} catch (Exception $e) {
$response['status'] = 'ERROR';
$response['message'] = $this->__('Cannot add the item to shopping
cart.');
Mage::logException($e);
}
$this->getResponse()->setBody(Mage::helper('core')-
>jsonEncode($response));
return;
}else{
return parent::addAction();
}
}
Options Iframe inside Fancybox

We will now see the code of the iframe which shows up inside the fancybox. The URL
of the iframe is ajax/index/options. So so we will edit the controller file and add
this code
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

public function optionsAction(){


$productId = $this->getRequest()->getParam('product_id');
// Prepare helper and params
$viewHelper = Mage::helper('catalog/product_view');

$params = new Varien_Object();


$params->setCategoryId(false);
$params->setSpecifyOptions(false);

// Render page
try {
$viewHelper->prepareAndRender($productId, $this, $params);
} catch (Exception $e) {
if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) {
if (isset($_GET['store']) && !$this->getResponse()->isRedirect())
{
$this->_redirect('');
} elseif (!$this->getResponse()->isRedirect()) {
$this->_forward('noRoute');
}
} else {
Mage::logException($e);
$this->_forward('noRoute');
}
}
}

This code is taking from the catalog/product/view action. In short, what this code
does is loadLayout() and renderLayout(). But it loads proper handles depending on
product type, i.e for configurable product it will load the handle
PRODUCT_TYPE_configurable from the catalog.xml
Next we need to add code in the layout file for the action ajax/index/options
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

<ajax_index_options>
<reference name="root">
<action
method="setTemplate"><template>page/empty.phtml</template></action>
</reference>
<reference name="head">
<action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action>
<action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
</reference>
<reference name="head">
<action method="addJs"><script>varien/product.js</script></action>
<action method="addJs"><script>varien/configurable.js</script></action>

<action method="addItem"><type>js_css</type><name>calendar/calendar-
win2k-1.css</name><params/><!--<if/><condition>can_load_calendar_js</condition>--
></action>
<action
method="addItem"><type>js</type><name>calendar/calendar.js</name><!--
<params/><if/><condition>can_load_calendar_js</condition>--></action>
<action method="addItem"><type>js</type><name>calendar/calendar-
setup.js</name><!--<params/><if/><condition>can_load_calendar_js</condition>--
></action>
</reference>
<reference name="content">
<block type="catalog/product_view" name="product.info"
template="ajax/catalog/product/options.phtml">
<!--
<action
method="addReviewSummaryTemplate"><type>default</type><template>review/helper/summa
ry.phtml</template></action>
<action
method="addReviewSummaryTemplate"><type>short</type><template>review/helper/summary
_short.phtml</template></action>
<action
method="addReviewSummaryTemplate"><type>...</type><template>...</template></action>
-->

<block type="catalog/product_view" name="product.info.addtocart"


as="addtocart" template="ajax/catalog/product/view/addtocart.phtml"/>

<block type="catalog/product_view"
name="product.info.options.wrapper" as="product_options_wrapper"
template="catalog/product/view/options/wrapper.phtml" translate="label">
<label>Info Column Options Wrapper</label>
<block type="core/template" name="options_js"
template="catalog/product/view/options/js.phtml"/>
<block type="catalog/product_view_options"
name="product.info.options" as="product_options"
template="catalog/product/view/options.phtml">
<action
method="addOptionRenderer"><type>text</type><block>catalog/product_view_options_typ
e_text</block><template>catalog/product/view/options/type/text.phtml</template></ac
tion>
<action
method="addOptionRenderer"><type>file</type><block>catalog/product_view_options_typ
e_file</block><template>catalog/product/view/options/type/file.phtml</template></ac
tion>
<action
method="addOptionRenderer"><type>select</type><block>catalog/product_view_options_t
ype_select</block><template>catalog/product/view/options/type/select.phtml</templat
e></action>
<action
method="addOptionRenderer"><type>date</type><block>catalog/product_view_options_typ
e_date</block><template>catalog/product/view/options/type/date.phtml</template></ac
tion>
</block>
<block type="core/html_calendar" name="html_calendar"
as="html_calendar" template="page/js/calendar.phtml"/>
</block>
<block type="catalog/product_view"
name="product.info.options.wrapper.bottom" as="product_options_wrapper_bottom"
template="catalog/product/view/options/wrapper/bottom.phtml" translate="label">
<label>Bottom Block Options Wrapper</label>
<action
method="insert"><block>product.tierprices</block></action>
<block type="catalog/product_view" name="product.clone_prices"
as="prices" template="catalog/product/view/price_clone.phtml"/>
<action
method="append"><block>product.info.addtocart</block></action>
<action
method="append"><block>product.info.addto</block></action>
</block>

<block type="core/template_facade" name="product.info.container1"


as="container1">
<action
method="setDataByKey"><key>alias_in_layout</key><value>container1</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action>
<action
method="append"><block>product.info.options.wrapper</block></action>
<action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block>
<block type="core/template_facade" name="product.info.container2"
as="container2">
<action
method="setDataByKey"><key>alias_in_layout</key><value>container2</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action>
<action
method="append"><block>product.info.options.wrapper</block></action>
<action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block>
<action
method="unsetCallChild"><child>container1</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action>
<action
method="unsetCallChild"><child>container2</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action>
</block>
</reference>
</ajax_index_options>

This code is similar to the <catalog_product_view> layout, except i have removed


some blocks like description, attributes which are not required.
Next we need to add code to the options.phtml file used in the above block.
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<style>
<!--
body.ajax-index-options{
width:380px;
padding:0px;
margin:0px;
}
body.ajax-index-options .product-shop .product-options-bottom .price-box{
float:left;
}
-->
</style>
<?php $_helper = $this->helper('catalog/output'); ?>
<?php $_product = $this->getProduct(); ?>
<script type="text/javascript">
var optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?
>);
</script>
<div class="product-view" style="width:380px">
<div class="product-essential" style="width:330px">
<form action="<?php echo $this->getSubmitUrl($_product) ?>" method="post"
id="product_addtocart_form"<?php if($_product->getOptions()): ?>
enctype="multipart/form-data"<?php endif; ?>>
<div class="no-display">
<input type="hidden" name="product" value="<?php echo $_product-
>getId() ?>" />
<input type="hidden" name="related_product" id="related-products-field"
value="" />
</div>

<div class="product-shop">
<div class="product-name">
<h1><?php echo $_helper->productAttribute($_product, $_product-
>getName(), 'name') ?></h1>
</div>

<?php echo $this->getChildHtml('product_type_data') ?>

<?php if (!$this->hasOptions()):?>
<div class="add-to-box">
<?php if($_product->isSaleable()): ?>
<?php echo $this->getChildHtml('addtocart') ?>
<?php endif; ?>
</div>
<?php endif; ?>

<?php if ($_product->isSaleable() && $this->hasOptions()):?>


<?php echo $this->getChildChildHtml('container1', '', true, true) ?
>
<?php endif;?>

</div>
<div class="clearer"></div>
<?php if ($_product->isSaleable() && $this->hasOptions()):?>
<?php echo $this->getChildChildHtml('container2', '', true, true) ?>
<?php endif;?>
</form>
<script type="text/javascript">
//<![CDATA[
var productAddToCartForm = new VarienForm('product_addtocart_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;
// Start of our new ajax code
if (!url) {
url = jQuery('#product_addtocart_form').attr('action');
}
url = url.replace("checkout/cart","ajax/index"); // New Code
var data = jQuery('#product_addtocart_form').serialize();
data += '&isAjax=1';
jQuery('#ajax_loader').show();
try {
jQuery.ajax( {
url : url,
dataType : 'json',
type : 'post',
data : data,
success : function(data) {
jQuery('#ajax_loader').hide();
parent.setAjaxData(data,true);
}
});
} catch (e) {
}
// End of our new ajax code
this.form.action = oldUrl;
if (e) {
throw e;
}
}
}.bind(productAddToCartForm);
productAddToCartForm.submitLight = function(button, url){
if(this.validator) {
var nv = Validation.methods;
delete Validation.methods['required-entry'];
delete Validation.methods['validate-one-required'];
delete Validation.methods['validate-one-required-by-name'];
if (this.validator.validate()) {
if (url) {
this.form.action = url;
}
this.form.submit();
}
Object.extend(Validation.methods, nv);
}
}.bind(productAddToCartForm);
//]]>
</script>
</div>
</div>

This is all that is required. This module has been tested in magento 1.6 version
only, but should work on all magento version. Please provide comments if something
is missing or bugs show up, so that we can improve this free module.
Share this:

Save

Like this:
Loading...
Tags ajaxajax add to cart
Magento Onestep Checkout – Remove Payment and Shipping Method Step
Ajax Based Add Product to Wishlist and Compare Products
Related Articles.
Ajax Based Add Product to Wishlist and Compare Products
27 Oct, 2011
Add Product to Shopping Cart using Ajax
04 Oct, 2011
My Blogs

Magento
PhoneGap
NodeJS
Magento Certified Developer Guide

RECOMMEND US
Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new
posts by email.

Join 3,584 other subscribers

Email Address

Ajax Based Product Add to Cart from Category Page By Manish Prakash in Magento,
Modules Oct 23 rd, 2011 59 Comments In this blog post we will see how to add
products to shopping cart directly from category page using ajax operations. We
would be able to add all product types simple,configurable,bundled,grouped, virtual
and downloadable from the category page itself. For the products which require
options to be selected before adding to cart e.g configurable,bundled etc , a
lightbox iframe window will show up showing the options to be selected by user with
a ‘Add to Cart’ button. This blog is in continuation of the previous blog written,
the same code base has been used and new coded is added. So it would be better to
once go through the previous blog as well. Here are screen shots of the module in
action, just so you know what we are going to develop. Downloadable Product Add to
Cart Downloadable Product Add to Cart Virtual Product Category Page Add to Cart
Virtual Product Category Page Add to Cart Magento Bundled Product Add to Cart
Magento Bundled Product Add to Cart Grouped Product Add to Cart Grouped Product Add
to Cart Category Page Simple Product Category Page Simple Product Configurable
Product with Custom Options Configurable Product with Custom Options Attached is
source code for this module Magneto version 1.6(+) [dm]17[/dm] Magneto version
1.6(-) [dm]18[/dm] Now let see what all we need to do, to achieve the above. Step1:
Override list.phtml First we will have to override the list.phtml file and create
our own list.phtml file in our module. In default theme, the list.phtml has this
code written on the ‘Add to Cart’ button 1 onclick="setLocation('<?php echo $this-
>getAddToCartUrl($_product) ?>')" The setLocation function simply redirects to
another page. We cannot use this, since we need to have ajax. Now we will have to
call another function instead of setLocation which will make an ajax call instead
of page redirect. For the ajax calls we are going to use the jQuery library just
like the previous blog. Let name our new function setLocationAjax(), so in no our
code will be 1 onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>')" We also need to do is put a ajax loading icon
next to the add to cart button, and when the ajax button is clicked the loading
should show up. So the final code for our ‘Add to Cart’ button would be 1 2 3
<p><button type="button" title="<?php echo $this->__('Add to Cart') ?>"
class="button btn-cart" onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?
php echo $this->__('Add to Cart') ?></span></span></button></p> <span
id='ajax_loader<?php echo $_product->getId()?>' style='display:none'><img src='<?
php echo $this->getSkinUrl('images/opc-ajax-loader.gif')?>'/></span> Here the
setLocationAjax has two parameters, first is the add to cart url and second is the
product id. The second parameter is actually required to identify the loading image
placed next to the add to cart button. If you see the id of the ajax loader image
it is id=’ajax_loadergetId()?>’. So based on the product id, we can hide/show the
correct ajax loading image. But still this code is not complete, we still have to
check if the product has some options (configurable, grouped, bundled, custom
options). If the product has required options, the add to cart will not work until
the options have been selected by the user. So what we will do is check if the
product has required options then show a lightbox with the options only, so that
user can select the options and add the product to cart. Here is the complete code
for the ‘Add to Cart’ button. 1 2 3 4 5 6 7 <?php if ( !($_product-
>getTypeInstance(true)->hasRequiredOptions($_product) || $_product->isGrouped()) )
{ ?> <p><button type="button" title="<?php echo $this->__('Add to Cart') ?>"
class="button btn-cart" onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?
php echo $this->__('Add to Cart') ?></span></span></button></p> <span
id='ajax_loader<?php echo $_product->getId()?>' style='display:none'><img src='<?
php echo $this->getSkinUrl('images/opc-ajax-loader.gif')?>'/></span> <?php } else {
?> <button type="button" title="<?php echo $this->__('Add to Cart') ?>"
class="button btn-cart" onclick="showOptions('<?php echo $_product->getId()?
>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button> <a
href='<?php echo $this->getUrl('ajax/index/options',array('product_id'=>$_product-
>getId()));?>' class='fancybox' id='fancybox<?php echo $_product->getId()?>'
style='display:none'>Test</a> <?php } ?> If you look in default what we have done
here is, put an if condition to check if product has required options or is a
grouped product. If this is true then we then the ‘Add to Cart’ button has
showOptions function and an anchor tag for the lightbox. If the condition is false
then the default ‘Add to Cart’ button is shown with setLocationAjax() option and
the ajax image loader. The complete list.phtml file is found the in the attached
module. Step2: Javascript Next in our list.phtml file we need to put in lot of
javascript to the following Initialize Fancybox For Products which have options,
fancybox with iframe should show up when click on ‘Add to Cart’ button For Product
which don’t have options, product should be added to cart through Ajax The top
links and cart sidebar should be updated after successful ‘Add to Cart’ First we
will download the fancybox library and then unpack the files in our skin folder i.e
skin\frontend\default\default\js\fancybox Next to add fancybox to category pages
add this code to the theme layout file, in my case ajax.xml 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 <catalog_category_default> <reference
name="head"> <action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action> <action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action> <action
method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action> </reference> <reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion> </reference> </catalog_category_default> <catalog_category_layered> <reference
name="head"> <action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action> <action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action> <action
method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action> </reference> <reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion> </reference> </catalog_category_layered> Now when you open the category page,
using firebug check if the fancybox library is loaded or not. Here is code to
initialize fancybox for all anchor tags with ‘fancybox’ class. 1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 jQuery(document).ready(function()
{ jQuery('.fancybox').fancybox( { hideOnContentClick : true, width: 382,
autoDimensions: true, type : 'iframe', showTitle: false, scrolling: 'no',
onComplete: function(){ //Resize the iframe to correct size jQuery('#fancybox-
frame').load(function() { // wait for frame to load and then gets it's height
jQuery('#fancybox-content').height(jQuery(this).contents().find('body').height()
+30); jQuery.fancybox.resize(); }); } } ); }); Here is code of the showOptions()
function. This will show fancybox with the iframe URL when click on ‘Add to Cart’.
1 2 3 function showOptions(id){ jQuery('#fancybox'+id).trigger('click'); } Here is
code to to add to product to cart using ajax which don’t have any options like
simple and virtual products. 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 function setAjaxData(data,iframe){ if(data.status ==
'ERROR'){ alert(data.message); }else{ if(jQuery('.block-cart')){ jQuery('.block-
cart').replaceWith(data.sidebar); } if(jQuery('.header .links'))
{ jQuery('.header .links').replaceWith(data.toplink); }
jQuery.fancybox.close(); } } function setLocationAjax(url,id){ url += 'isAjax/1';
url = url.replace("checkout/cart","ajax/index"); jQuery('#ajax_loader'+id).show();
try { jQuery.ajax( { url : url, dataType : 'json', success : function(data)
{ jQuery('#ajax_loader'+id).hide(); setAjaxData(data,false); } }); } catch (e)
{ } } Step3: Controller Now in our controller file we need to put in code first for
our ajax/index/addAction . The same code as the previous blog is used here without
any changes, so i am just pasting the code here 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 public function addAction() { $cart = $this->_getCart();
$params = $this->getRequest()->getParams(); if($params['isAjax'] == 1){ $response =
array(); try { if (isset($params['qty'])) { $filter = new
Zend_Filter_LocalizedToNormalized( array('locale' => Mage::app()->getLocale()-
>getLocaleCode()) ); $params['qty'] = $filter->filter($params['qty']);
} $product = $this->_initProduct(); $related = $this->getRequest()-
>getParam('related_product'); /** * Check product availability */ if (!$product)
{ $response['status'] = 'ERROR'; $response['message'] = $this->__('Unable to find
Product ID'); } $cart->addProduct($product, $params); if (!empty($related))
{ $cart->addProductsByIds(explode(',', $related)); } $cart->save(); $this-
>_getSession()->setCartWasUpdated(true); /** * @todo remove wishlist observer
processAddToCart */ Mage::dispatchEvent('checkout_cart_add_product_complete',
array('product' => $product, 'request' => $this->getRequest(), 'response' => $this-
>getResponse()) ); if (!$cart->getQuote()->getHasError()){ $message = $this->__('%s
was added to your shopping cart.', Mage::helper('core')->htmlEscape($product-
>getName())); $response['status'] = 'SUCCESS'; $response['message'] = $message;
//New Code Here $this->loadLayout(); $toplink = $this->getLayout()-
>getBlock('top.links')->toHtml(); $sidebar_block = $this->getLayout()-
>getBlock('cart_sidebar'); Mage::register('referrer_url', $this->_getRefererUrl());
$sidebar = $sidebar_block->toHtml(); $response['toplink'] = $toplink;
$response['sidebar'] = $sidebar; } } catch (Mage_Core_Exception $e) { $msg = ""; if
($this->_getSession()->getUseNotice(true)) { $msg = $e->getMessage(); } else
{ $messages = array_unique(explode("\n", $e->getMessage())); foreach ($messages as
$message) { $msg .= $message.'<br/>'; } } $response['status'] = 'ERROR';
$response['message'] = $msg; } catch (Exception $e) { $response['status'] =
'ERROR'; $response['message'] = $this->__('Cannot add the item to shopping cart.');
Mage::logException($e); } $this->getResponse()->setBody(Mage::helper('core')-
>jsonEncode($response)); return; }else{ return parent::addAction(); } } Options
Iframe inside Fancybox We will now see the code of the iframe which shows up inside
the fancybox. The URL of the iframe is ajax/index/options. So so we will edit the
controller file and add this code 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 public function optionsAction(){ $productId = $this-
>getRequest()->getParam('product_id'); // Prepare helper and params $viewHelper =
Mage::helper('catalog/product_view'); $params = new Varien_Object(); $params-
>setCategoryId(false); $params->setSpecifyOptions(false); // Render page try
{ $viewHelper->prepareAndRender($productId, $this, $params); } catch (Exception $e)
{ if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) { if
(isset($_GET['store']) && !$this->getResponse()->isRedirect()) { $this-
>_redirect(''); } elseif (!$this->getResponse()->isRedirect()) { $this-
>_forward('noRoute'); } } else { Mage::logException($e); $this-
>_forward('noRoute'); } } } This code is taking from the catalog/product/view
action. In short, what this code does is loadLayout() and renderLayout(). But it
loads proper handles depending on product type, i.e for configurable product it
will load the handle PRODUCT_TYPE_configurable from the catalog.xml Next we need to
add code in the layout file for the action ajax/index/options 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
<ajax_index_options> <reference name="root"> <action
method="setTemplate"><template>page/empty.phtml</template></action> </reference>
<reference name="head"> <action
method="addItem"><type>js</type><name>jquery/jquery-1.6.4.min.js</name></action>
<action method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
</reference> <reference name="head"> <action
method="addJs"><script>varien/product.js</script></action> <action
method="addJs"><script>varien/configurable.js</script></action> <action
method="addItem"><type>js_css</type><name>calendar/calendar-win2k-
1.css</name><params/><!--<if/><condition>can_load_calendar_js</condition>--
></action> <action
method="addItem"><type>js</type><name>calendar/calendar.js</name><!--
<params/><if/><condition>can_load_calendar_js</condition>--></action> <action
method="addItem"><type>js</type><name>calendar/calendar-setup.js</name><!--
<params/><if/><condition>can_load_calendar_js</condition>--></action> </reference>
<reference name="content"> <block type="catalog/product_view" name="product.info"
template="ajax/catalog/product/options.phtml"> <!-- <action
method="addReviewSummaryTemplate"><type>default</type><template>review/helper/summa
ry.phtml</template></action> <action
method="addReviewSummaryTemplate"><type>short</type><template>review/helper/summary
_short.phtml</template></action> <action
method="addReviewSummaryTemplate"><type>...</type><template>...</template></action>
--> <block type="catalog/product_view" name="product.info.addtocart" as="addtocart"
template="ajax/catalog/product/view/addtocart.phtml"/> <block
type="catalog/product_view" name="product.info.options.wrapper"
as="product_options_wrapper" template="catalog/product/view/options/wrapper.phtml"
translate="label"> <label>Info Column Options Wrapper</label> <block
type="core/template" name="options_js"
template="catalog/product/view/options/js.phtml"/> <block
type="catalog/product_view_options" name="product.info.options"
as="product_options" template="catalog/product/view/options.phtml"> <action
method="addOptionRenderer"><type>text</type><block>catalog/product_view_options_typ
e_text</block><template>catalog/product/view/options/type/text.phtml</template></ac
tion> <action
method="addOptionRenderer"><type>file</type><block>catalog/product_view_options_typ
e_file</block><template>catalog/product/view/options/type/file.phtml</template></ac
tion> <action
method="addOptionRenderer"><type>select</type><block>catalog/product_view_options_t
ype_select</block><template>catalog/product/view/options/type/select.phtml</templat
e></action> <action
method="addOptionRenderer"><type>date</type><block>catalog/product_view_options_typ
e_date</block><template>catalog/product/view/options/type/date.phtml</template></ac
tion> </block> <block type="core/html_calendar" name="html_calendar"
as="html_calendar" template="page/js/calendar.phtml"/> </block> <block
type="catalog/product_view" name="product.info.options.wrapper.bottom"
as="product_options_wrapper_bottom"
template="catalog/product/view/options/wrapper/bottom.phtml" translate="label">
<label>Bottom Block Options Wrapper</label> <action
method="insert"><block>product.tierprices</block></action> <block
type="catalog/product_view" name="product.clone_prices" as="prices"
template="catalog/product/view/price_clone.phtml"/> <action
method="append"><block>product.info.addtocart</block></action> <action
method="append"><block>product.info.addto</block></action> </block> <block
type="core/template_facade" name="product.info.container1" as="container1"> <action
method="setDataByKey"><key>alias_in_layout</key><value>container1</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action> <action
method="append"><block>product.info.options.wrapper</block></action> <action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block> <block type="core/template_facade" name="product.info.container2"
as="container2"> <action
method="setDataByKey"><key>alias_in_layout</key><value>container2</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action> <action
method="append"><block>product.info.options.wrapper</block></action> <action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block> <action
method="unsetCallChild"><child>container1</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action> <action
method="unsetCallChild"><child>container2</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action> </block> </reference>
</ajax_index_options> This code is similar to the <catalog_product_view> layout,
except i have removed some blocks like description, attributes which are not
required. Next we need to add code to the options.phtml file used in the above
block. 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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
109 <style> <!-- body.ajax-index-options{ width:380px; padding:0px; margin:0px; }
body.ajax-index-options .product-shop .product-options-bottom .price-
box{ float:left; } --> </style> <?php $_helper = $this->helper('catalog/output'); ?
> <?php $_product = $this->getProduct(); ?> <script type="text/javascript"> var
optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
</script> <div class="product-view" style="width:380px"> <div class="product-
essential" style="width:330px"> <form action="<?php echo $this-
>getSubmitUrl($_product) ?>" method="post" id="product_addtocart_form"<?php
if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>> <div
class="no-display"> <input type="hidden" name="product" value="<?php echo
$_product->getId() ?>" /> <input type="hidden" name="related_product" id="related-
products-field" value="" /> </div> <div class="product-shop"> <div class="product-
name"> <h1><?php echo $_helper->productAttribute($_product, $_product->getName(),
'name') ?></h1> </div> <?php echo $this->getChildHtml('product_type_data') ?> <?php
if (!$this->hasOptions()):?> <div class="add-to-box"> <?php if($_product-
>isSaleable()): ?> <?php echo $this->getChildHtml('addtocart') ?> <?php endif; ?>
</div> <?php endif; ?> <?php if ($_product->isSaleable() && $this->hasOptions()):?>
<?php echo $this->getChildChildHtml('container1',
'', true, true) ?> <?php endif;?> </div> <div class="clearer"></div> <?php if
($_product->isSaleable() && $this->hasOptions()):?> <?php echo $this-
>getChildChildHtml('container2', '', true, true) ?> <?php endif;?> </form> <script
type="text/javascript"> //<![CDATA[ var productAddToCartForm = new
VarienForm('product_addtocart_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; // Start of our
new ajax code if (!url) { url = jQuery('#product_addtocart_form').attr('action'); }
url = url.replace("checkout/cart","ajax/index"); // New Code var data =
jQuery('#product_addtocart_form').serialize(); data += '&isAjax=1';
jQuery('#ajax_loader').show(); try { jQuery.ajax( { url : url, dataType : 'json',
type : 'post', data : data, success : function(data)
{ jQuery('#ajax_loader').hide(); parent.setAjaxData(data,true); } }); } catch (e) {
} // End of our new ajax code this.form.action = oldUrl; if (e) { throw
e; } } }.bind(productAddToCartForm); productAddToCartForm.submitLight =
function(button, url){ if(this.validator) { var nv = Validation.methods; delete
Validation.methods['required-entry']; delete Validation.methods['validate-one-
required']; delete Validation.methods['validate-one-required-by-name']; if
(this.validator.validate()) { if (url) { this.form.action = url; }
this.form.submit(); } Object.extend(Validation.methods,
nv); } }.bind(productAddToCartForm); //]]> </script> </div> </div> This is all that
is required. This module has been tested in magento 1.6 version only, but should
work on all magento version. Please provide comments if something is missing or
bugs show up, so that we can improve this free module. Share this: Save Like this:
Loading... Tags ajaxajax add to cart Magento Onestep Checkout – Remove Payment and
Shipping Method Step Ajax Based Add Product to Wishlist and Compare Products
Related Articles. Ajax Based Add Product to Wishlist and Compare Products 27 Oct,
2011 Add Product to Shopping Cart using Ajax 04 Oct, 2011 My Blogs Magento PhoneGap
NodeJS Magento Certified Developer Guide RECOMMEND US Subscribe to Blog via Email
Enter your email address to subscribe to this blog and receive notifications of new
posts by email. Join 3,584 other subscribers Email Address Extensions Source Search
Most Popular Posts Magento Add Fee or Discount to Order Totals (181) Add Product to
Shopping Cart using Ajax (152) Magento Create Custom Payment Method (119) Add
Custom Fields to Customer Account - Magento 1.7 (104) Magento Create Custom
Shipping Method (95) BLOG CATEGORIES EC2 (2) Facebook (4) Magento (90) Admin Module
Development (5) EAV and Flat Tables (3) Magento API (3) Module Development Series
(12) Modules (13) Nuts & Bolts (18) Onepage Checkout (8) Payment Method (2)
Shipping Method (3) Tips and Snippets (18) Magento2 (2) Magento2 Admin Development
Series (4) Magento2 Module Development Series (5) Magento2 Quickies (4) Magento2
Theme Development (2) Mobile App Development (8) Uncategorized (3) PriceGenie. My
Experiments with Robotics. Manish Prakash Ajax Based Product Add to Cart from
Category Page By Manish Prakash in Magento, Modules Oct 23 rd, 2011 59 Comments In
this blog post we will see how to add products to shopping cart directly from
category page using ajax operations. We would be able to add all product types
simple,configurable,bundled,grouped, virtual and downloadable from the category
page itself. For the products which require options to be selected before adding to
cart e.g configurable,bundled etc , a lightbox iframe window will show up showing
the options to be selected by user with a ‘Add to Cart’ button. This blog is in
continuation of the previous blog written, the same code base has been used and new
coded is added. So it would be better to once go through the previous blog as well.
Here are screen shots of the module in action, just so you know what we are going
to develop. Downloadable Product Add to Cart Downloadable Product Add to Cart
Virtual Product Category Page Add to Cart Virtual Product Category Page Add to Cart
Magento Bundled Product Add to Cart Magento Bundled Product Add to Cart Grouped
Product Add to Cart Grouped Product Add to Cart Category Page Simple Product
Category Page Simple Product Configurable Product with Custom Options Configurable
Product with Custom Options Attached is source code for this module Magneto version
1.6(+) [dm]17[/dm] Magneto version 1.6(-) [dm]18[/dm] Now let see what all we need
to do, to achieve the above. Step1: Override list.phtml First we will have to
override the list.phtml file and create our own list.phtml file in our module. In
default theme, the list.phtml has this code written on the ‘Add to Cart’ button 1
onclick="setLocation('<?php echo $this->getAddToCartUrl($_product) ?>')" The
setLocation function simply redirects to another page. We cannot use this, since we
need to have ajax. Now we will have to call another function instead of setLocation
which will make an ajax call instead of page redirect. For the ajax calls we are
going to use the jQuery library just like the previous blog. Let name our new
function setLocationAjax(), so in no our code will be 1
onclick="setLocationAjax('<?php echo $this->getAddToCartUrl($_product) ?>')" We
also need to do is put a ajax loading icon next to the add to cart button, and when
the ajax button is clicked the loading should show up. So the final code for our
‘Add to Cart’ button would be 1 2 3 <p><button type="button" title="<?php echo
$this->__('Add to Cart') ?>" class="button btn-cart" onclick="setLocationAjax('<?
php echo $this->getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?
>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button></p>
<span id='ajax_loader<?php echo $_product->getId()?>' style='display:none'><img
src='<?php echo $this->getSkinUrl('images/opc-ajax-loader.gif')?>'/></span> Here
the setLocationAjax has two parameters, first is the add to cart url and second is
the product id. The second parameter is actually required to identify the loading
image placed next to the add to cart button. If you see the id of the ajax loader
image it is id=’ajax_loadergetId()?>’. So based on the product id, we can hide/show
the correct ajax loading image. But still this code is not complete, we still have
to check if the product has some options (configurable, grouped, bundled, custom
options). If the product has required options, the add to cart will not work until
the options have been selected by the user. So what we will do is check if the
product has required options then show a lightbox with the options only, so that
user can select the options and add the product to cart. Here is the complete code
for the ‘Add to Cart’ button. 1 2 3 4 5 6 7 <?php if ( !($_product-
>getTypeInstance(true)->hasRequiredOptions($_product) || $_product->isGrouped()) )
{ ?> <p><button type="button" title="<?php echo $this->__('Add to Cart') ?>"
class="button btn-cart" onclick="setLocationAjax('<?php echo $this-
>getAddToCartUrl($_product) ?>','<?php echo $_product->getId()?>')"><span><span><?
php echo $this->__('Add to Cart') ?></span></span></button></p> <span
id='ajax_loader<?php echo $_product->getId()?>' style='display:none'><img src='<?
php echo $this->getSkinUrl('images/opc-ajax-loader.gif')?>'/></span> <?php } else {
?> <button type="button" title="<?php echo $this->__('Add to Cart') ?>"
class="button btn-cart" onclick="showOptions('<?php echo $_product->getId()?
>')"><span><span><?php echo $this->__('Add to Cart') ?></span></span></button> <a
href='<?php echo $this->getUrl('ajax/index/options',array('product_id'=>$_product-
>getId()));?>' class='fancybox' id='fancybox<?php echo $_product->getId()?>'
style='display:none'>Test</a> <?php } ?> If you look in default what we have done
here is, put an if condition to check if product has required options or is a
grouped product. If this is true then we then the ‘Add to Cart’ button has
showOptions function and an anchor tag for the lightbox. If the condition is false
then the default ‘Add to Cart’ button is shown with setLocationAjax() option and
the ajax image loader. The complete list.phtml file is found the in the attached
module. Step2: Javascript Next in our list.phtml file we need to put in lot of
javascript to the following Initialize Fancybox For Products which have options,
fancybox with iframe should show up when click on ‘Add to Cart’ button For Product
which don’t have options, product should be added to cart through Ajax The top
links and cart sidebar should be updated after successful ‘Add to Cart’ First we
will download the fancybox library and then unpack the files in our skin folder i.e
skin\frontend\default\default\js\fancybox Next to add fancybox to category pages
add this code to the theme layout file, in my case ajax.xml 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 <catalog_category_default> <reference
name="head"> <action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action> <action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action> <action
method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action> </reference> <reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion> </reference> </catalog_category_default> <catalog_category_layered> <reference
name="head"> <action method="addItem"><type>js</type><name>jquery/jquery-
1.6.4.min.js</name></action>
<action method="addItem"><type>skin_js</type><name>js/fancybox/jquery.fancybox-
1.3.4.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.easing-
1.3.pack.js</name></action> <action
method="addItem"><type>skin_js</type><name>js/fancybox/jquery.mousewheel-
3.0.4.pack.js</name></action> <action
method="addItem"><type>js</type><name>jquery/noconflict.js</name></action> <action
method="addCss"><stylesheet>js/fancybox/jquery.fancybox-
1.3.4.css</stylesheet></action> </reference> <reference name='product_list'>
<action
method='setTemplate'><template>ajax/catalog/product/view/list.phtml</template></act
ion> </reference> </catalog_category_layered> Now when you open the category page,
using firebug check if the fancybox library is loaded or not. Here is code to
initialize fancybox for all anchor tags with ‘fancybox’ class. 1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 jQuery(document).ready(function()
{ jQuery('.fancybox').fancybox( { hideOnContentClick : true, width: 382,
autoDimensions: true, type : 'iframe', showTitle: false, scrolling: 'no',
onComplete: function(){ //Resize the iframe to correct size jQuery('#fancybox-
frame').load(function() { // wait for frame to load and then gets it's height
jQuery('#fancybox-content').height(jQuery(this).contents().find('body').height()
+30); jQuery.fancybox.resize(); }); } } ); }); Here is code of the showOptions()
function. This will show fancybox with the iframe URL when click on ‘Add to Cart’.
1 2 3 function showOptions(id){ jQuery('#fancybox'+id).trigger('click'); } Here is
code to to add to product to cart using ajax which don’t have any options like
simple and virtual products. 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 function setAjaxData(data,iframe){ if(data.status ==
'ERROR'){ alert(data.message); }else{ if(jQuery('.block-cart')){ jQuery('.block-
cart').replaceWith(data.sidebar); } if(jQuery('.header .links'))
{ jQuery('.header .links').replaceWith(data.toplink); }
jQuery.fancybox.close(); } } function setLocationAjax(url,id){ url += 'isAjax/1';
url = url.replace("checkout/cart","ajax/index"); jQuery('#ajax_loader'+id).show();
try { jQuery.ajax( { url : url, dataType : 'json', success : function(data)
{ jQuery('#ajax_loader'+id).hide(); setAjaxData(data,false); } }); } catch (e)
{ } } Step3: Controller Now in our controller file we need to put in code first for
our ajax/index/addAction . The same code as the previous blog is used here without
any changes, so i am just pasting the code here 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 public function addAction() { $cart = $this->_getCart();
$params = $this->getRequest()->getParams(); if($params['isAjax'] == 1){ $response =
array(); try { if (isset($params['qty'])) { $filter = new
Zend_Filter_LocalizedToNormalized( array('locale' => Mage::app()->getLocale()-
>getLocaleCode()) ); $params['qty'] = $filter->filter($params['qty']); } $product =
$this->_initProduct(); $related = $this->getRequest()->getParam('related_product');
/** * Check product availability */ if (!$product) { $response['status'] = 'ERROR';
$response['message'] = $this->__('Unable to find Product ID'); } $cart-
>addProduct($product, $params); if (!empty($related)) { $cart-
>addProductsByIds(explode(',', $related)); } $cart->save(); $this->_getSession()-
>setCartWasUpdated(true); /** * @todo remove wishlist observer processAddToCart */
Mage::dispatchEvent('checkout_cart_add_product_complete', array('product' =>
$product, 'request' => $this->getRequest(), 'response' => $this->getResponse()) );
if (!$cart->getQuote()->getHasError()){ $message = $this->__('%s was added to your
shopping cart.', Mage::helper('core')->htmlEscape($product->getName()));
$response['status'] = 'SUCCESS'; $response['message'] = $message; //New Code Here
$this->loadLayout(); $toplink = $this->getLayout()->getBlock('top.links')-
>toHtml(); $sidebar_block = $this->getLayout()->getBlock('cart_sidebar');
Mage::register('referrer_url', $this->_getRefererUrl()); $sidebar = $sidebar_block-
>toHtml(); $response['toplink'] = $toplink; $response['sidebar'] = $sidebar; } }
catch (Mage_Core_Exception $e) { $msg = ""; if ($this->_getSession()-
>getUseNotice(true)) { $msg = $e->getMessage(); } else { $messages =
array_unique(explode("\n", $e->getMessage())); foreach ($messages as $message)
{ $msg .= $message.'<br/>'; } } $response['status'] = 'ERROR'; $response['message']
= $msg; } catch (Exception $e) { $response['status'] = 'ERROR';
$response['message'] = $this->__('Cannot add the item to shopping cart.');
Mage::logException($e); } $this->getResponse()->setBody(Mage::helper('core')-
>jsonEncode($response)); return; }else{ return parent::addAction(); } } Options
Iframe inside Fancybox We will now see the code of the iframe which shows up inside
the fancybox. The URL of the iframe is ajax/index/options. So so we will edit the
controller file and add this code 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 public function optionsAction(){ $productId = $this-
>getRequest()->getParam('product_id'); // Prepare helper and params $viewHelper =
Mage::helper('catalog/product_view'); $params = new Varien_Object(); $params-
>setCategoryId(false); $params->setSpecifyOptions(false); // Render page try
{ $viewHelper->prepareAndRender($productId, $this, $params); } catch (Exception $e)
{ if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) { if
(isset($_GET['store']) && !$this->getResponse()->isRedirect()) { $this-
>_redirect(''); } elseif (!$this->getResponse()->isRedirect()) { $this-
>_forward('noRoute'); } } else { Mage::logException($e); $this-
>_forward('noRoute'); } } } This code is taking from the catalog/product/view
action. In short, what this code does is loadLayout() and renderLayout(). But it
loads proper handles depending on product type, i.e for configurable product it
will load the handle PRODUCT_TYPE_configurable from the catalog.xml Next we need to
add code in the layout file for the action ajax/index/options 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
<ajax_index_options> <reference name="root"> <action
method="setTemplate"><template>page/empty.phtml</template></action> </reference>
<reference name="head"> <action
method="addItem"><type>js</type><name>jquery/jquery-1.6.4.min.js</name></action>
<action method="addItem"><type>js</type><name>jquery/noconflict.js</name></action>
</reference> <reference name="head"> <action
method="addJs"><script>varien/product.js</script></action> <action
method="addJs"><script>varien/configurable.js</script></action> <action
method="addItem"><type>js_css</type><name>calendar/calendar-win2k-
1.css</name><params/><!--<if/><condition>can_load_calendar_js</condition>--
></action> <action
method="addItem"><type>js</type><name>calendar/calendar.js</name><!--
<params/><if/><condition>can_load_calendar_js</condition>--></action> <action
method="addItem"><type>js</type><name>calendar/calendar-setup.js</name><!--
<params/><if/><condition>can_load_calendar_js</condition>--></action> </reference>
<reference name="content"> <block type="catalog/product_view" name="product.info"
template="ajax/catalog/product/options.phtml"> <!-- <action
method="addReviewSummaryTemplate"><type>default</type><template>review/helper/summa
ry.phtml</template></action> <action
method="addReviewSummaryTemplate"><type>short</type><template>review/helper/summary
_short.phtml</template></action> <action
method="addReviewSummaryTemplate"><type>...</type><template>...</template></action>
--> <block type="catalog/product_view" name="product.info.addtocart" as="addtocart"
template="ajax/catalog/product/view/addtocart.phtml"/> <block
type="catalog/product_view" name="product.info.options.wrapper"
as="product_options_wrapper" template="catalog/product/view/options/wrapper.phtml"
translate="label"> <label>Info Column Options Wrapper</label> <block
type="core/template" name="options_js"
template="catalog/product/view/options/js.phtml"/> <block
type="catalog/product_view_options" name="product.info.options"
as="product_options" template="catalog/product/view/options.phtml"> <action
method="addOptionRenderer"><type>text</type><block>catalog/product_view_options_typ
e_text</block><template>catalog/product/view/options/type/text.phtml</template></ac
tion> <action
method="addOptionRenderer"><type>file</type><block>catalog/product_view_options_typ
e_file</block><template>catalog/product/view/options/type/file.phtml</template></ac
tion> <action
method="addOptionRenderer"><type>select</type><block>catalog/product_view_options_t
ype_select</block><template>catalog/product/view/options/type/select.phtml</templat
e></action> <action
method="addOptionRenderer"><type>date</type><block>catalog/product_view_options_typ
e_date</block><template>catalog/product/view/options/type/date.phtml</template></ac
tion> </block> <block type="core/html_calendar" name="html_calendar"
as="html_calendar" template="page/js/calendar.phtml"/> </block> <block
type="catalog/product_view" name="product.info.options.wrapper.bottom"
as="product_options_wrapper_bottom"
template="catalog/product/view/options/wrapper/bottom.phtml" translate="label">
<label>Bottom Block Options Wrapper</label> <action
method="insert"><block>product.tierprices</block></action> <block
type="catalog/product_view" name="product.clone_prices" as="prices"
template="catalog/product/view/price_clone.phtml"/> <action
method="append"><block>product.info.addtocart</block></action> <action
method="append"><block>product.info.addto</block></action> </block> <block
type="core/template_facade" name="product.info.container1"
as="container1"> <action
method="setDataByKey"><key>alias_in_layout</key><value>container1</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action> <action
method="append"><block>product.info.options.wrapper</block></action> <action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block> <block type="core/template_facade" name="product.info.container2"
as="container2"> <action
method="setDataByKey"><key>alias_in_layout</key><value>container2</value></action>
<action
method="setDataByKeyFromRegistry"><key>options_container</key><key_in_registry>prod
uct</key_in_registry></action> <action
method="append"><block>product.info.options.wrapper</block></action> <action
method="append"><block>product.info.options.wrapper.bottom</block></action>
</block> <action
method="unsetCallChild"><child>container1</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action> <action
method="unsetCallChild"><child>container2</child><call>ifEquals</call><if>0</if><ke
y>alias_in_layout</key><key>options_container</key></action> </block> </reference>
</ajax_index_options> This code is similar to the <catalog_product_view> layout,
except i have removed some blocks like description, attributes which are not
required. Next we need to add code to the options.phtml file used in the above
block. 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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
109 <style> <!-- body.ajax-index-options{ width:380px; padding:0px; margin:0px; }
body.ajax-index-options .product-shop .product-options-bottom .price-
box{ float:left; } --> </style> <?php $_helper = $this->helper('catalog/output'); ?
> <?php $_product = $this->getProduct(); ?> <script type="text/javascript"> var
optionsPrice = new Product.OptionsPrice(<?php echo $this->getJsonConfig() ?>);
</script> <div class="product-view" style="width:380px"> <div class="product-
essential" style="width:330px"> <form action="<?php echo $this-
>getSubmitUrl($_product) ?>" method="post" id="product_addtocart_form"<?php
if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>> <div
class="no-display"> <input type="hidden" name="product" value="<?php echo
$_product->getId() ?>" /> <input type="hidden" name="related_product" id="related-
products-field" value="" /> </div> <div class="product-shop"> <div class="product-
name"> <h1><?php echo $_helper->productAttribute($_product, $_product->getName(),
'name') ?></h1> </div> <?php echo $this->getChildHtml('product_type_data') ?> <?php
if (!$this->hasOptions()):?> <div class="add-to-box"> <?php if($_product-
>isSaleable()): ?> <?php echo $this->getChildHtml('addtocart') ?> <?php endif; ?>
</div> <?php endif; ?> <?php if ($_product->isSaleable() && $this->hasOptions()):?>
<?php echo $this->getChildChildHtml('container1', '', true, true) ?> <?php endif;?>
</div> <div class="clearer"></div> <?php if ($_product->isSaleable() && $this-
>hasOptions()):?> <?php echo $this->getChildChildHtml('container2', '', true, true)
?> <?php endif;?> </form> <script type="text/javascript"> //<![CDATA[ var
productAddToCartForm = new VarienForm('product_addtocart_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; // Start of our new ajax code if (!url)
{ url = jQuery('#product_addtocart_form').attr('action'); } url =
url.replace("checkout/cart","ajax/index"); // New Code var data =
jQuery('#product_addtocart_form').serialize(); data += '&isAjax=1';
jQuery('#ajax_loader').show(); try { jQuery.ajax( { url : url, dataType : 'json',
type : 'post', data : data, success : function(data)
{ jQuery('#ajax_loader').hide(); parent.setAjaxData(data,true); } }); } catch (e) {
} // End of our new ajax code this.form.action = oldUrl; if (e) { throw
e; } } }.bind(productAddToCartForm); productAddToCartForm.submitLight =
function(button, url){ if(this.validator) { var nv = Validation.methods; delete
Validation.methods['required-entry']; delete Validation.methods['validate-one-
required']; delete Validation.methods['validate-one-required-by-name']; if
(this.validator.validate()) { if (url) { this.form.action = url; }
this.form.submit(); } Object.extend(Validation.methods,
nv); } }.bind(productAddToCartForm); //]]> </script> </div> </div> This is all that
is required. This module has been tested in magento 1.6 version only, but should
work on all magento version. Please provide comments if something is missing or
bugs show up, so that we can improve this free module. Share this: Save Like this:
Loading... Tags ajaxajax add to cart Magento Onestep Checkout – Remove Payment and
Shipping Method Step Ajax Based Add Product to Wishlist and Compare Products
Related Articles. Ajax Based Add Product to Wishlist and Compare Products 27 Oct,
2011 Add Product to Shopping Cart using Ajax 04 Oct, 2011 My Blogs Magento PhoneGap
NodeJS Magento Certified Developer Guide RECOMMEND US Subscribe to Blog via Email
Enter your email address to subscribe to this blog and receive notifications of new
posts by email. Join 3,584 other subscribers Email Address