Posting in the Magento forums has been disabled pending the implementation of a new and improved forum solution which should better serve the community.

For new questions please post at magento.stackexchange.com, the community-run support site for the Magento community. We will be providing updates on the new forum solution soon. For questions or concerns please email community@magento.com.

Magento Forum

TIP: Ajax in Magento—the three approaches that I have seen, and the one I am using
 
HAL10001
Member
 
Avatar
Total Posts:  52
Joined:  2008-06-02
Ann Arbor, MI
 

If you’re like me, and you need a bit of Ajax in Magento, your biggest problem is not calling a URL, but calling a template so that an entire layout is not loaded via the URL. I think the most common approach to this problem is here:

http://www.magentocommerce.com/boards/viewthread/12736/

Unfortunately, this requires creating files outside the scope of Magento, which can get messy quick.

The second method is to create an entirely new module, controller and actions, and in the controller for the view and index action you prohibit the loading of the layout. The portion about creating a new module is sufficiently documented on the wiki.

The third option, which is the one I am now using, is to create a new controller/action on an existing module. The only really difference here is that I’m not creating a new module, which can be cumbersome in itself. Instead I create a new folder within the controllers folder for the module I want to use, call it Ajax, and add my new controller at this location. There is a touch more to it than that, and you can read how I managed it here:

http://www.magentocommerce.com/boards/viewthread/19914/

Now you can call that URL directly within the scope of Magento. In case you’re wondering, in the version I am using, this is how the onepage checkout progress update happens. Look at checkout/controllers/OnepageshippingController.php and you will see that in all the actions the loadLayout() is actually loadLayout(false). This is so you can call it directly without loading the layout template (header, footer, etc.). You can use Prototype to call the URL like this:

new Ajax.Request"review/ajax_product/view"{
    method
"post",
    
parameters{
        id 
reviewId
    }
,
    
onSuccess: function( transport {
        
new Insertion.Bottom( $$("body")[0]transport.responseText );
    
}
}
);

In my case the reviewId is a parameter that I needed to get from the page so that I can display a single review in an AJAX layer. If you wanted to get product information, then you might call a different URL for a controller you created in the catalog module, and pass in the product ID. The insertion is just to show that I got the page by inserting it at the end of the body tag.

It is a lot to digest, but if you begin with the other post I linked to and then come back here it will make more sense.

 
Magento Community Magento Community
Magento Community
Magento Community
 
Fibo
Sr. Member
 
Avatar
Total Posts:  107
Joined:  2008-06-25
Marseille, France
 

First, thx for this post and the other one. They will be very useful to lots of people, and presumably not just in the context of Ajax.
As you say, lots to digest!

Learning by reading your post led me to some further questions… they are pure curiosity to enhance my knowledge, and not questioning what you did!

In the second method yous say that it will be needed to “prohibit the loading of the layout”.
Obviously you have found good reasons for that...but can you explain why?
are you meaning the corresponding *.xml or the *.phtml?
how do you “prohibit” the loading?

Thx for your patience!

 
Magento Community Magento Community
Magento Community
Magento Community
 
HAL10001
Member
 
Avatar
Total Posts:  52
Joined:  2008-06-02
Ann Arbor, MI
 
Fibo - 10 October 2008 03:10 AM

First, thx for this post and the other one. They will be very useful to lots of people, and presumably not just in the context of Ajax.
As you say, lots to digest!

Learning by reading your post led me to some further questions… they are pure curiosity to enhance my knowledge, and not questioning what you did!

In the second method yous say that it will be needed to “prohibit the loading of the layout”.
Obviously you have found good reasons for that...but can you explain why?
are you meaning the corresponding *.xml or the *.phtml?
how do you “prohibit” the loading?

Thx for your patience!

Hi Fibo,

When you call a URL, it maps to a module/controller/action. So for instance, Review/controllers/ProductController.php is actually http://www.somedomain.com/review/product/view/id/1 - the ProductController.php has a method to process the view action and a method to process the review ID parameter. I used review ID #1 in the URL just as an example. In the controller’s view action it also loads a layout, which is another way of saying it pulls in all the other template information (header, footer, etc.) and any other blocks on the page. When you make an AJAX call you don’t want all that stuff, and you might just want a single block, or snippet of HTML. So you have to stop the controller from loading the entire layout.

This is a simplified explanation, and I am sure there is more happening behind the scenes than I touched on, but it should get you started with it.

Hope that helps!

 
Magento Community Magento Community
Magento Community
Magento Community
 
Fibo
Sr. Member
 
Avatar
Total Posts:  107
Joined:  2008-06-25
Marseille, France
 

OK, thx.
B-))

 
Magento Community Magento Community
Magento Community
Magento Community
 
kainobi
Jr. Member
 
Total Posts:  6
Joined:  2008-12-02
 

Hi!

I have a question regarding the third method (creating a new controller).

To load the product view per ajax request I created a new controller catalog/controllers/Ajax/ProductController.php:

require_once('app/code/core/Mage/Catalog/controllers/ProductController.php');

class 
Mage_Catalog_Ajax_ProductController extends Mage_Catalog_ProductController
{    

    
/**
     * View product action
     */
    
public function viewAction()
    
{
        
if ($product $this->_initProduct()) {
            Mage
::dispatchEvent('catalog_controller_product_view', array('product'=>$product));

            
Mage::getSingleton('catalog/session')->setLastViewedProductId($product->getId());
            
Mage::getModel('catalog/design')->applyDesign($productMage_Catalog_Model_Design::APPLY_FOR_PRODUCT);
            
            
$this->loadLayout(false); 
            
$this->renderLayout();
        
}
        
else {
            
if (isset($_GET['store'])) {
                $this
->_redirect('');
            
else {
                $this
->_forward('noRoute');
            
}
        }
    }

    
}

In catalog.xml I added the following:

<catalog_ajax_product_view>
    <
block type="catalog/product_view" name="product_info" output="toHtml" template="catalog/ajax/product/view.phtml" />
</
catalog_ajax_product_view>

The category view where the ajax request ist done looks like this:

<?php echo $this->getMessagesBlock()->getGroupedHtml() ?>

    
<script type="text/javascript">
                
        function 
doAjaxRequest(urldivid{

            
new Ajax.Updater(dividurl{
              evalScripts
true,
              
method'post'
            
});

            
        
}
    </script>


    <?php
    $category 
$this->getCurrentCategory();
  
$store_id Mage::app()->getStore()->getId();
    
$arraySubCategories explode(',',$category->getChildren());
    
$_iteratior=0;

    foreach(
$arraySubCategories as $subCateporyId):
        
$subCategory   Mage::getModel('catalog/category')->load($subCateporyId);
        
$arrayProducts $subCategory->getProductCollection()->addStoreFilter($store_id);
        
$_iterator=0;
        
?>
        <?php 
if(count($arrayProducts)): ?>
            
<div class="category"><img src="<?php echo $subCategory->getImageUrl(); ?>" width="35" height="100" border="0" alt="<?php echo $subCategory->getName();?>" title="<?php echo $subCategory->getName();?>" /></div>
            
<?php foreach ($arrayProducts as $_product): ?>
            <?php $_product
->load($_product->getID()); ?>
                    
<div class="item">
                        <
div class="hidden"><img src="<?php echo $this->getSkinUrl('images/customer/clear.gif') ?>" width="30" height="100" border="0" /></div>
                        <
div class="img">
                            <
a href="<?php echo $_product->getProductUrl(); ?>" onclick="doAjaxRequest('<?php echo str_replace('/catalog/product/view/', '/catalog/ajax_product/view/', $_product->getProductUrl()); ?>', 'productpanel'); return false;" title="<?php echo $this->htmlEscape($_product->getName()) ?>" >
                                
<?php if($_product->getTypeInstance()->isSalable()):?>
                                    
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(30, 85); ?>" width="30" height="85" border="0" class="tips-product" title="<?php echo $this->htmlEscape($_product->getName()) ?> :: <?php echo $this->htmlEscape($_product->getSku()) ?>" id="prodimage_<?php echo ++$_iterator; ?>" alt="<?php echo $this->htmlEscape($_product->getName()) ?>" />
                                
<?php else: ?>
                                    
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(30, 85); ?>" width="30" height="85" border="0" class="tips-product outofstock" title="<?php echo $this->htmlEscape($_product->getName()) ?> :: <?php echo $this->htmlEscape($_product->getSku()) ?>" id="prodimage_<?php echo ++$_iterator; ?>" alt="<?php echo $this->htmlEscape($_product->getName()) ?>" />
                                
<?php endif; ?>
                            
</a>
                        </
div>
                    </
div>
            
<?php endforeach; ?>
        <?php 
endif;?>
    <?php 
endforeach; ?>

This works perfectly.

BUT as you can see i get the ajax request url with

<?php echo str_replace('/catalog/product/view/''/catalog/ajax_product/view/'$_product->getProductUrl()); ?>

just by a simple str_replace to get the correct path for the new controller, which isn´s really nice imho.

My question is, if it is possible to write a new method $_product->getProductAjaxUrl() and how it can be done in a proper way.

What do you think - is it worth the effort? Any hints I can do this?

Best regards
Kai

 
Magento Community Magento Community
Magento Community
Magento Community
 
illo_sdrawkcab
Member
 
Total Posts:  63
Joined:  2008-10-23
 

Thank you! Very Nice, that makes me one step better understanding magento!

I tried this and i finally see the html output under modulename/controllerclass/action but how do i call php methods from that point?
In my Block i wrote the code to get a product object from the sku but i cannot call it from there.

Where do i do my methods to parse the request?

 
Magento Community Magento Community
Magento Community
Magento Community
 
illo_sdrawkcab
Member
 
Total Posts:  63
Joined:  2008-10-23
 

Solved my problem in simply leaving out the $this->renderLayout();.
I put my code to parse the sku into a model and called it from the controller.

Exept from the problem that cannot get url to add the article to the cart, the controller is correctly calling the model.

Is it usual to write code like this into a model class? Or should it be elsewhere?

$storeId    Mage::app()->getStore()->getId();
        
$product    Mage::getModel('catalog/product');
        
        
$products   $product->setStoreId($storeId)->getCollection();

        
$product $products->addAttributeToFilter('sku'$sku)->addAttributeToSelect('*'); 
        
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($products);
        
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($products);        
        
#Mage::getSingleton('core/abstract')->load();

        
if(count($product) == 1{
            
return $product;
        
else {
            
return false
 
Magento Community Magento Community
Magento Community
Magento Community
 
illo_sdrawkcab
Member
 
Total Posts:  63
Joined:  2008-10-23
 

Ok so far so good. My output is right but after retrieving the url and adding the item to the cart magento redirects to the module witch is handling this.
Can i turn this off ?

 
Magento Community Magento Community
Magento Community
Magento Community
 
FMEExtensions
Mentor
 
Avatar
Total Posts:  1298
Joined:  2009-08-07
 

Ajax Add to Cart Magento extension enables your customers to add or remove products from the cart ,wishlist without any page reloads and while staying on the very same page whether it is home page, category listing page, product detail page, cross sells, upsells or related products. It works for each and every kind or product such as simple, virtual, configurable or any other type.

http://www.magentocommerce.com/magento-connect/catalog/product/view/id/13651/

 
Magento Community Magento Community
Magento Community
Magento Community
 
Magestore
Mentor
 
Avatar
Total Posts:  1015
Joined:  2009-08-07
Viet Nam
 

With Ajax Cart extension (http://www.magentocommerce.com/magento-connect/ajaxcart-extension-7163.html), your customers continue shopping without waiting for pages to reload each time adding items to cart or removing items from cart:
- Add products to cart from the cart page or product list pages via pop-up forms.
- No redirect to the product page.
- And edit minicart by Ajax.
You could go to the Product page of this extension to request for the trial and test right on your site to learn more.
If you have any questions of this product, please email us at . We will be here to assist you.
Hope you succeed.

 
Magento Community Magento Community
Magento Community
Magento Community
 
Hardik Gajjar
Jr. Member
 
Avatar
Total Posts:  8
Joined:  2012-04-06
 

Yes, here is a great AJAX add to cart extension which provides best support for all type of products from any page also It provides great functionality in admin panel to add custom cart blocks in AJAX update.

http://www.magentocommerce.com/magento-connect/catalog/product/view/id/15606/

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
Back to top