How to Render an HTML Using an Ajax Call in Magento 2 Module

AJAX_CALL_HTML_MAGENTO_2

In the previous article, we have displayed the form success action message using ajax. In that article, we have returned only the specific message from our controller and display it on the frontend. Sometimes you need to return the whole HTML and display it on frontend using Ajax. Today we will see How to render an HTML using an Ajax call in Magento 2 Module.

Magento 2 provides a Magento\Framework\Controller\Result\JsonFactory class that can be use to return an JSON response from a controller. We will use factory method of this class to return our HTML in json format.

Create PHTML File

Create a PHTML file index.phtml under app/code/Codextblog/Custom/view/frontend/templates from where we want to initialize our ajax call.

<div id="ajaxresponse"></div>
<?php
$ajaxurl = $block->getAjaxUrl();
?>
<script type="text/x-magento-init">
        {
            "*": {
                "Codextblog_Custom/js/custom": {
                    "AjaxUrl": "<?php echo $ajaxurl; ?>",
                    "CurrentProduct": "<?php echo $currentProductId; ?>",
                }
            }
        }
</script>

In this file, we have created one blank div with id #ajaxresponse. Using ajax call we will call controller file and return an HTML. Using JQUERY we will fill that HTML into div.

Under the script tag, we are passing two parameters to our js file. First is AjaxUrl which is the URL of the controller (in our case it is custom/index/view/, a custom is the front name of our module and view.php is our controller file) from where we will return a JSON response, second is CurrentProduct which is product id. You can pass any other parameters in this call. For demonstration purpose, we have passed product id to CurrentProduct parameter.

Web Hosting


Create JS File

Create a JS file custom.js under app/code/Codextblog/Custom/view/frontend/web/js directory and enter below code.

define([
    "jquery",
    "jquery/ui"
], function($){
    "use strict";

    function main(config, element) {
        var $element = $(element);
        var AjaxUrl = config.AjaxUrl;
        var CurrentProduct = config.CurrentProduct;
        
        $(document).ready(function(){
            setTimeout(function(){
                $.ajax({
                    context: '#ajaxresponse',
                    url: AjaxUrl,
                    type: "POST",
                    data: {currentproduct:CurrentProduct},
                }).done(function (data) {
                    $('#ajaxresponse').html(data.output);
                    return true;
                });
            },2000);
        });


    };
    return main;
});

You can see, in the done method we are filling the div content using data.output, that contains the actual HTML.

Create Controller File

Create a controller file View.php under app/code/Codextblog/Custom/Controller/Index directory and write below code

<?php
namespace Codextblog\Custom\Controller\Index;


use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\View\Result\PageFactory;


class View extends Action
{

    /**
     * @var PageFactory
     */
    protected $_resultPageFactory;

    /**
     * @var JsonFactory
     */
    protected $_resultJsonFactory;


    /**
     * View constructor.
     * @param Context $context
     * @param PageFactory $resultPageFactory
     * @param JsonFactory $resultJsonFactory
     */
    public function __construct(Context $context, PageFactory $resultPageFactory, JsonFactory $resultJsonFactory)
    {

        $this->_resultPageFactory = $resultPageFactory;
        $this->_resultJsonFactory = $resultJsonFactory;

        parent::__construct($context);
    }


    /**
     * @return \Magento\Framework\Controller\Result\Json
     */
    public function execute()
    {
        $result = $this->_resultJsonFactory->create();
        $resultPage = $this->_resultPageFactory->create();
        $currentProductId = $this->getRequest()->getParam('currentproduct');
       

        $data = array('currentproductid'=>$currentProductId);

        $block = $resultPage->getLayout()
                ->createBlock('Codextblog\Custom\Block\Index\View')
                ->setTemplate('Codextblog_Custom::view.phtml')
                ->setData('data',$data)
                ->toHtml();

        $result->setData(['output' => $block]);
        return $result;
    }

}

You can see, in the line no. 54 and 55 we have passed block file and template file in which we will write our business logic and HTML code respectively. We have passed the currentproductid in setData method so that it is available in block file for any business logic. In line number 59 we are setting our data in setData method which is preparing JSON output.

Create Block File

Create View.php under app/code/Codextblog/Custom/Block/Index directory and write below code

<?php
namespace Codextblog\Custom\Block\Index;

use Magento\Framework\View\Element\Template;

class View extends Template
{
  public function __construct(Template\Context $context, array $data = [])
    {
        parent::__construct($context, $data);
    }

  protected function _prepareLayout()
    {
        return parent::_prepareLayout(); // TODO: Change the autogenerated stub
    }

  public function getProducts($productId)
  {
     ---------------ANY BUSINESS LOGIC---------
     return;
  }
}

Create Template File

Create view.phtml file under app/code/Codextblog/Custom/view/frontend/templates directory with your HTML code.

<?php
$productData = $block->getData();
$productId = $productData['data']['currentproductid'];
$products = $block->getProducts($productId);
?>
<div>
  <div>YOUR HTML</div>
</div> 

You can see here currentproductid is available in our template file. Using that variable we can fetch any business logic from block file and render an HTML code in our template file.
 
Hope this AJAX tutorial will help you in your project. Please like us on Facebook and follow us on Twitter.

Want to ask a question or leave a comment?

Leave a Comment

(3 Comments)

  • PAJ

    How does full page cache affect ajax queries like this? Will the response be cached if I want to return customer specific data, e.g. show info specific to the customer on product page which should not be cached and shown to other customers!

    • Chirag

      In POST Ajax request, response will never cache in fpc. In each and every request you will get non cacheble response.

  • Stephen

    Sorry last comment posted before I could correct.

    The dom ready jquery call seems pointless. It is inside a main function and you can also use ‘domReady!’ in the require. You are welcome to correct me if I am missing something.

  • All the comments are goes into moderation before approval. Irrelevant comment with links directly goes to spam. Your email address will not be published.

    Was this post helpful? Please support Us!

    Follow us on twitter or Like us on facebook.

     


    To Avoid Spam Downloads, We Want Your Email

    We will send you download link right
    away. Please submit form below.
    SEND ME DOWNLOAD LINK
    Close

    Increase Your
    Magento 2
    Knowledge

    Get Weekly Tutorial
    to your Inbox
    Subscribe Me
    close-link
    Subscribe Here