I am working on a simple custom module, where user can input height and the weight/BMI will be shown as output on form submit. The page where user enters input is Calculation
Page while output is shown on Result
Page.On clicking the submit button user will be redirected to different controller/action. Below is the code
Calculation Layout - Vendor/Module/view/frontend/layout/module_index_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Calculator</title>
</head>
<body>
<referenceContainer name="content">
<block class="Vendor\Module\Block\Index" name="calculation_index" template="Vendor_Module::calculation.phtml" />
</referenceContainer>
</body>
</page>
Calculation Input PHTML -Vendor/Module/view/frontend/templates/calculation.phtml
<div class="row clearfix">
<div class="col-md-12 column">
<form name="post-user-input" method="POST" id="height">
<div class="well">
<strong><?php echo __('Enter Height:')?></strong>
<input type="text" id="calculateTotalInput" name="calculateTotalInput" class="form-control input-md">
<input type="button" id="calculateTotalSubmit" name="calculate-total-submit" value="Calculate Total">
</div>
<div class="col-sm-6 col-xs-12" style="margin-bottom: 30px;">
<?php echo __('Height:')?> <input type="text" value="<?= $weight ?>" name="height" class="form-control input-md" readonly="">
<?php echo __('BMI:')?> <input type="text" value="<?= $bmi ?>" name="weight" class="form-control input-md" readonly="">
</div>
</form>
</div>
</div>
<script>
$(document).ready(function() {
$("#height").submit(function(){
jQuery.ajax({
url: "/vendor/module/result/result",
type: "POST",
data: {height:height,weight:weight},
success: function(response){
console.log(response);
}
});
});
});
</script>
Block - Vendor/Module/Block/Index.php
<?php
namespace Vendor\Module\Block;
use \Magento\Framework\View\Element\Template;
use \Magento\Framework\View\Element\Template\Context;
class Index extends Template
{
public function __construct(Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager
)
{
$this->_storeManager = $storeManager;
parent::__construct($context);
}
public function getBaseUrl()
{
return $this->_storeManager->getStore()->getBaseUrl();
}
public function getAjaxData()
{
return $this->getData();
}
}
Calculation Controller - Vendor/Module/Controller/Index/Index.php
<?php
namespace Vendor\Module\Controller\Index;
use \Magento\Framework\App\Action\Action;
use \Magento\Framework\App\Action\Context;
use \Magento\Framework\View\Result\PageFactory;
class Index extends Action
{
/**
* @var PageFactory
*/
protected $resultPageFactory;
/**
* Result constructor.
* @param Context $context
* @param PageFactory $pageFactory
*/
public function __construct(Context $context, PageFactory $pageFactory)
{
$this->resultPageFactory = $pageFactory;
parent::__construct($context);
}
/**
* The controller action
*
* @return \Magento\Framework\View\Result\Page
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
return $resultPage;
}
}
Result Page Controller - Vendor/Module/Controller/Result/Result.php
<?php
namespace Vendor\Module\Controller\Result;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Controller\Result\JsonFactory;
class Result extends \Magento\Framework\App\Action\Action
{
/**
* @var Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;
protected $resultJsonFactory;
/**
* @param Context $context
* @param PageFactory $resultPageFactory
*/
public function __construct(
Context $context,
PageFactory $resultPageFactory,
JsonFactory $resultJsonFactory
)
{
$this->resultPageFactory = $resultPageFactory;
$this->resultJsonFactory = $resultJsonFactory;
parent::__construct($context);
}
public function execute()
{
$data = $this->getRequest()->getParam('data');
$result = $this->resultJsonFactory->create();
$resultPage = $this->resultPageFactory->create();
$block = $resultPage->getLayout()
->createBlock('Vendor\Module\Block\Index')
->setTemplate('Vendor_Module::result.phtml')
->setData('data',$data)
->toHtml();
$result->setData(['output' => $block]);
return $result;
}
}
Result Layout File - Vendor/Module/view/frontend/layout/module_result_result.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Result</title>
</head>
<body>
<referenceContainer name="content">
<block class="Vendor\Module\Block\Index" name="calculation_result" template="Vendor_Module::result.phtml" />
</referenceContainer>
</body>
</page>
Result PHTML file - Vendor/Module/view/frontend/templates/result.phtml
<?php
echo $block->getAjaxData();
?>
The workflow - user comes on calculation.phtml page > enters input > call result ctrl via ajax on button submit > process data in result ctrl > show the data in updated result.html with page reload.
- While trying to call controller action using AJAX, it is not working. How do I call and pass data to controller via AJAX ?
- How do I return data from controller in JSON format and send it back to result.phtml file in order to show the output ?