2

I'm trying to follow this tutorial: http://excellencemagentoblog.com/blog/2011/10/04/magento-add-product-to-cart-ajax/

It seems it's working, it adds the product to the cart, but it don't update it, instead it's returning an error that can't do toHtml on a boolean.

I followed this error to this line:

require_once 'Mage/Checkout/controllers/CartController.php';

class Feliu_Ajaxcart_IndexController extends Mage_Checkout_CartController
{
    public function addAction()
    {
        ... //lot of code omitted
        $this->loadLayout();
        $sidebar_block = $this->getLayout()->getBlock('cart_sidebar');
        $sidebar = $sidebar_block->toHtml();
        ... //lot of code omitted
    }
}

And $sidebar_block is always null, so the toHtml() is returning an error. If I change the line $sidebar = $sidebar_block->toHtml(); to $sidebar = '<div>' . $sidebar_block . '</div>'; then there is no error, but shopping cart is not updating because is replacing the cart by an empty div.

This is the javascript in the view to make the ajax call and replace the cart by the updated one:

//mytheme/template/catalog/product/viewphtml
//<![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","ajaxcart/index");
        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();
                    console.log(data.status + ": " + data.message);
                    console.log(data); // here I see what's returning the controller function add
                    if(jQuery('.block-cart')){
                        jQuery('.block-cart').replaceWith(data.sidebar);
                    }
                    if(jQuery('.header .links')){
                        jQuery('.header .links').replaceWith(data.toplink);
                    }
                },
                error: function(jqXHR, textStatus, response){
                    // will fire when timeout is reached
                    console.log("timeout is reached");
                    console.log(textStatus);
                    console.log(response);
                    jQuery('#ajax_loader').hide();
                },
                timeout: 6000
            });
        } catch (e) {
            console.log("fail");
            console.log(e);
            this.form.action = oldUrl;
            if (e) {
                throw e;
            }
        }
    }
}.bind(productAddToCartForm);

and the config.xml of the module

<config>
<modules>
    <Feliu_Ajaxcart>
        <version>0.1.0</version>
    </Feliu_Ajaxcart>
</modules>
<global>
    <models>
        <feliu_ajaxcart>
            <class>Feliu_Ajaxcart_Model</class>
            <resourceModel>feliu_ajaxcart_resource</resourceModel>
        </feliu_ajaxcart>
        <feliu_ajaxcart_resource>
            <class>Feliu_Ajaxcart_Model_Resource</class>
        </feliu_ajaxcart_resource>
    </models>
    <blocks>
        <feliu_ajaxcart>
            <class>Feliu_Ajaxcart_Block</class>
        </feliu_ajaxcart>
    </blocks>
    <helpers>
        <feliu_ajaxcart>
            <class>Feliu_Ajaxcart_Helper</class>
        </feliu_ajaxcart>
    </helpers>
    <resources>
        <feliu_ajaxcart_setup>
            <setup>
                <module>Feliu_Ajaxcart</module>
            </setup>
            <connection>
                <use>core_setup</use>
            </connection>
        </feliu_ajaxcart_setup>
        <feliu_ajaxcart_write>
            <connection>
                <use>core_write</use>
            </connection>
        </feliu_ajaxcart_write>
        <feliu_ajaxcart_read>
            <connection>
                <use>core_read</use>
            </connection>
        </feliu_ajaxcart_read>
    </resources>
    <rewrite>
        <feliu_ajaxcart> <!--This can be any unique id -->
            <from><![CDATA[#^/checkout/cart/#]]></from>  <!-- the URL which u want to override-->
            <to>/ajaxcart/index/</to>  <!-- destination url -->
        </feliu_ajaxcart>
    </rewrite>
</global>
<frontend>
    <routers>
        <ajaxcart>
            <use>standard</use>
            <args>
                <modules>
                    <Feliu_Ajaxcart before="Mage_Checkout" >Feliu_Ajaxcart</Feliu_Ajaxcart>
                </modules>
                <frontName>ajaxcart</frontName>
            </args>
        </ajaxcart>
    </routers>
</frontend>

The checkout.xml (it is a lot of code, so I omitted a lot of lines):

<default>

    <!-- Mage_Checkout -->
    <reference name="top.links">
        <block type="checkout/links" name="checkout_cart_link">
            <action method="addCartLink"></action>
            <action method="addCheckoutLink"></action>
        </block>
    </reference>

    <reference name="header">
        <block type="checkout/cart_minicart" name="minicart_head" template="checkout/cart/minicart.phtml" before="-">
            <block type="checkout/cart_sidebar" name="minicart_content" template="checkout/cart/minicart/items.phtml">
                <action method="addItemRender"><type>default</type><block>checkout/cart_item_renderer</block><template>checkout/cart/minicart/default.phtml</template></action>
                <action method="addItemRender"><type>simple</type><block>checkout/cart_item_renderer</block><template>checkout/cart/minicart/default.phtml</template></action>
                <action method="addItemRender"><type>grouped</type><block>checkout/cart_item_renderer_grouped</block><template>checkout/cart/minicart/default.phtml</template></action>
                <action method="addItemRender"><type>configurable</type><block>checkout/cart_item_renderer_configurable</block><template>checkout/cart/minicart/default.phtml</template></action>

                <block type="core/text_list" name="cart_sidebar.cart_promotion" as="cart_promotion" translate="label" module="checkout">
                    <label>Mini-cart promotion block</label>
                </block>
                <block type="core/text_list" name="cart_sidebar.extra_actions" as="extra_actions" translate="label" module="checkout">
                    <label>Shopping Cart Sidebar Extra Actions</label>
                </block>
            </block>
        </block>
    </reference>
   ...
</default>

1 Answer 1

2

As in your xml, you can see the line

<block type="checkout/cart_sidebar" name="minicart_content" template="checkout/cart/minicart/items.phtml">

With block name="minicart_content", so you can use this name to get content of that block. This is the default block magento uses to return when action ajaxUpdate is called to update minicart section in header.
Refer Mage_Checkout_CartController::ajaxUpdateAction()

So in your case below code should work for you.

$sidebar_block = $this->getLayout()->createBlock('checkout/cart_sidebar')->setTemplate("checkout/cart/minicart/items.phtml");
$sidebar = $sidebar_block->toHtml();

in place of below,

$sidebar_block = $this->getLayout()->getBlock('cart_sidebar');
$sidebar = $sidebar_block->toHtml();
9
  • it's still null
    – Alex
    Commented Apr 6, 2017 at 9:06
  • check with updated code. The issue is because the block with name cart_sidebar or minicart_content is not defined in your layout. Commented Apr 6, 2017 at 9:14
  • If they are defined than there should not be any issue. can you add both blocks xml code to your question. Commented Apr 6, 2017 at 9:26
  • I added the checkout.xml, at least the first part because it's too long
    – Alex
    Commented Apr 6, 2017 at 9:40
  • Please review updated answer @Alex Commented Apr 6, 2017 at 9:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.