phpajaxmagento

Magento - Load products by ajax in current template design


I am building a magento extension in which I need to show all products in tree order on left bar and then click on each category will load products of category by sending ajax request. To display category tree I used a block.

I am new to magento so I thought to send ajax request to my controller, get all products data as JSON and create HTML on front end to display products.

I took the HTML of base theme with 2 column left bar of products listing and used in ajax method. I used like

function loadCategoryProducts(categoryId) {
jQuery.ajax({
    url: '/myModule/index/loadcategoryproduct',
    type: 'post',
    data: {categoryId: categoryId},
    success: function(products) {
        products = jQuery.parseJSON(products);
        if (products != '') {
            var html = '';
            html += '<div class="page-title category-title">';
             // blah blah blah blah blah to draw html from ajax request
            }
            html += '</ul>';
            html += '</div>' // end of category-products product
            jQuery('.col-main').html(html);
        }
    }
});

}

And my controller code

public function loadcategoryproductAction() {
    $id = $this->getRequest()->getParam('categoryId');
    if ($id) {
        $_category = Mage::getModel('catalog/category')->load($id);
        $product = Mage::getModel('catalog/product');

        //load the category's products as a collection
        $_productCollection = $product->getCollection()
                ->addAttributeToSelect('*')
                ->addCategoryFilter($_category)
                ->load();



        // build an array for conversion
        $json_products = array();
        foreach ($_productCollection as $_product) {
            $_product->getData();
            $json_products[] = array(
                'name' => $_product->getName(),
                'url' => $_product->getProductUrl(),
                'description' => nl2br($_product->getShortDescription()),
                'price' => $_product->getFormatedPrice(),
                'image' => $_product->getImageUrl());
        }

        $data = json_encode($json_products);

        echo $data;
        die;
    }
}

It worked great but I know it is just a static thing as I am using HTML and CSS of base theme. It will only work in this theme. What If the theme of the magento store is changed?

So what I am looking is how to display products in current active theme? I just send ajax request to my controller, get products and these product must be rendered in current theme layout? There must be a way to do this that I still couldn't be able to find. I googled but all in vain. I don't like to use any built in extension for it. I want my extension to do it all. Please guide.


Solution

  • Ok, I have figured out the solution. You just need to get the category and set in registry as current category. Then you need to get current active template. For products listing Magento always check list.phtml file of current active theme. So here are the steps

    1. Get Category
    2. Register your category as current category.
    3. Get current template list.phtml file and pass your category to that file
    4. Leave the rest to Magento, It can handle it because It is Magento :-)

    Here is the code that will replace my controller code

     $id = $this->getRequest()->getParam('categoryId');
     $category = Mage::getModel('catalog/category') ->setStoreId(Mage::app()->getStore()->getId()) ->load($id);
     Mage::unregister('current_category');
     Mage::register('current_category', $category);
     echo $this->getLayout() ->createBlock('catalog/product_list') ->setTemplate('catalog/product/list.phtml') ->setCategoryId($id) ->toHtml();
     die;
    

    This will return the product HTML, and I will just need to put the HTML in success function of my ajax request.

    success : function(products) {
      jQuery('col-main').html(products)
    }
    

    And that is it. :-)