I'm trying to write a module that adds a finance section on my product pages. I've managed to get the initial block to show, but on page-load I'm trying to get it to populate the box with finance information from another block via a controller.

I've set up my XML file that is correctly loading in the content on my product page:

<layout version="0.1.0">
    <default>
        <reference name="content">
        </reference>
    </default>
    <finance_ajax_index>
        <reference name="content">
            <block type="finance/finance" name="finance" as="finance" template="finance/init.phtml"/>
        </reference>
    </finance_ajax_index>
    <finance_ajax_ajax>
        <remove name="right"/>
        <remove name="left"/>
        <block type="finance/finance" name="finance_ajax" as="finance_ajax" template="finance/ajax.phtml" output="toHtml"/>
    </finance_ajax_ajax>
</layout>

My AjaxController.php has been set up as follows:

<?php class Eden_Finance_AjaxController extends Mage_Core_Controller_Front_Action {

    public function indexAction() {
        $this->loadLayout();
        $this->renderLayout();
    }

    public function ajaxAction() {
        $isAjax = Mage::app()->getRequest()->isAjax();
        if ( $isAjax ) {
            $layout = $this->getLayout();
            $update = $layout->getUpdate();
            $update->load( 'finance_ajax_ajax' );
            $layout->generateXml();
            $layout->generateBlocks();
            $output = $layout->getOutput();
            $this->getResponse()->setHeader( 'Content-type', 'application/json' );
            $this->getResponse()->setBody( Mage::helper( 'core' )->jsonEncode( array( 'outputHtml' => $output ) ) );
        }
    }

}

and I'm using the following in my init.phtml to try and load the ajax content from ajax.phtml, but when logging data, all I get is {"outputHtml":""}:

<script>
    function getFinance() {
        var months = $j("select[name='finance']").val();
        $j.ajax({
            beforeSend: function() {
                $j('.loader').show();
            },
            url: "<?php echo $this->getUrl('finance/ajax/ajax');?>",
            type: "POST",
            dataType: 'json',
            data: {
                id: <?php echo $_product->getId();?>,
                months: months
            },
            success: function (data) {
                console.log(data);
                $j('#finance_example').html(data.outputHtml);
            },
            complete: function(){
                $j('.loader').hide();
            }
        });
    }
    $j(document).ready(function() {
        getFinance();
        return false;
    });
    $j("select[name='finance']").change(function() {
        getFinance();
        return false;
    });
</script>

No matter what I change, I can't seem to get any output from the controller.

  • Check your console for errors – Sukumar Gorai Jun 21 at 12:44
  • There's nothing in the console other than {"outputHtml":""}. – Liam McArthur Jun 21 at 12:45
  • Can you try this: stackoverflow.com/questions/23322172/… – Sukumar Gorai Jun 21 at 12:48
  • Unfortunately, that's not helping either. The controller is definitely working. What I've worked out is that it's not loading the view onto the page. If I change the content of the ajaxAction() function to echo "test"; and navigate to /finance/ajax/ajax I can see the data. – Liam McArthur Jun 21 at 14:20
  • Are you sure your controller is generating the html? – Piyush Jun 25 at 10:58

You need to change your controller code as below:

public function indexAction() {
    $this->loadLayout();
    $this->renderLayout();
}

public function ajaxAction() {
    $isAjax = Mage::app()->getRequest()->isAjax();
    if ( $isAjax ) {
        $output = $this->getLayout()->createBlock('finance/finance')->setTemplate('finance/ajax.phtml')->toHtml();
        $this->getResponse()->setHeader( 'Content-type', 'application/json' );
        $this->getResponse()->setBody(json_encode(['outputHtml' => $output]));
    }
}

}

  • Perfect. It's working magically now! – Liam McArthur Jun 27 at 8:52
  • @LiamMcArthur , if its working fine then you can mark this as correct answer. Thanks – Chirag Rajput Jun 27 at 8:54
  • Already have. Enjoy the bounty! – Liam McArthur Jun 27 at 9:00

Thoughts on possibly doing it like so?

class Your_Module_Block_Finance_Ajax extends Mage_Core_Block_Template

protected function _construct()
{
    parent::_construct();
    $this->setTemplate('finance/ajax.phtml');       
}

and update your request to

$block = $this->getLayout()->createBlock('Moduleblockname/Finance_Ajax');
$this->getResponse()->setBody(Mage::helper( 'core' )->jsonEncode( array( 'outputHtml' =>$block->toHtml())));
  • This isn't working for me. Surely I'll still need a controller to update the block? – Liam McArthur Jun 26 at 13:43

You're going for some lengths here. No need to do Magento's work on the layout on your own, keep it simple :

public function ajaxAction() {
    $isAjax = Mage::app()->getRequest()->isAjax();
    if ( $isAjax ) {
       $this->loadLayout();
       $this->renderLayout();
    }
}
<layout version="0.1.0">
<!-- The XML handle containing the "content" block is already defined in "page.xml", no need to create this block here again -->
<finance_ajax_index>
    <reference name="content">
        <block type="finance/finance" name="finance" as="finance" template="finance/init.phtml"/>
    </reference>
</finance_ajax_index>
<finance_ajax_ajax>
<!-- Main trick here : name your block "root", because you want to override Magento's default highest level block with everything that is inside (header, footer, default content, etc...) -->
    <block type="finance/finance" name="root" template="finance/ajax.phtml"/>
</finance_ajax_ajax>

And then you can update your block directly from the result of your Ajax request, no need to go for the variable "outputHtml" in the data. Also, don't forget to change the dataType of your request to html.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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