Magento – How to get the controller to update a block via Ajax

ajaxcontrollersmagento-1.9

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.

Best Answer

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]));
    }
}

}

Related Topic