Magento – Magento 2 – Send processed data from Controller to PHTML

blockscontrollersjsonmagento2module

I am working on a simple custom module, where the user can input height and the weight/BMI will be shown as output on form submit. On clicking the submit button user will be redirected to different controller/action. Below is the code

<div class="row clearfix">
    <div class="col-md-12 column">
        <form name="height" method="POST" action="<?php echo $block->getFormAction() ?>">
              <div class="well">
                <strong><?php echo __('Enter Height:')?></strong>
                <input type="text" id="calculateTotalInput" name="calculateTotalInput" class="form-control input-md">
                <input type="submit" id="calculateTotalSubmit"  name="calculate-total-submit" value="Calculate Total">
            </div>

            <?php if(isset($weight && $bmi)){ ?>
            <div class="col-sm-6 col-xs-12" style="margin-bottom: 30px;">
                <?php echo __('Height:')?> <input type="text" value="<?= $weight ?>" name="weight" class="form-control input-md" readonly="">
                <?php echo __('BMI:')?> <input type="text" value="<?= $bmi ?>" name="weight" class="form-control input-md" readonly="">
            </div>  
            <?php } ?>
        </form>
    </div>
</div>

Screenshot

enter image description here

Block File

<?php

namespace Magento2\HelloWorld\Block;

use \Magento\Framework\View\Element\Template;
use \Magento\Framework\View\Element\Template\Context;

class Index extends Template
{

    public function __construct(Context $context, array $data = [])
    {
        parent::__construct($context, $data);
    }


    /**
    * Retrieve form action
    *
    * @return string
    */
    public function getFormAction()

        return $this->getUrl('helloworld/result/result', array('_secure' => $this->getRequest()->isSecure()));
    }


}

Controller File

<?php

namespace Magento2\HelloWorld\Controller\Result;

use \Magento\Framework\App\Action\Action;
use \Magento\Framework\Controller\ResultFactory;


class Result extends Action
{

    public function execute()
    {

        $post = $this->getRequest()->getPostValue();

        if ($post) {

            //retrieve height
            $calculateTotalInput = $post['calculateTotalInput'];

            //calculate weight/bmi
            $weight = ($calculateTotalInput * 2)/2.5 //some calculations
            $bmi    = ($calculateTotalInput * 2)/3.5 //some calculations
        }
        // Render the page 
        $this->_view->loadLayout();
        $this->_view->renderLayout();
    }


}
  • How do I pass & display $weight and $bmi value in phtml file ?
  • Best practice to pass values from controller to phtml ? Using block
    or without block and if yes, then HOW?
  • How do I pass an array containing multiple values from a controller to
    phtml via JSON?
  • What is the difference between Jsonfactory and Pagefactory and when
    to use?

Best Answer

You can use Magento\Framework\App\Request\DataPersistorInterface

Using this class, you can show proceed data to form url.

One of example is Magento_Contact module contacts form.

At post Action,you can set form data

$post = $this->getRequest()->getPostValue();

$postObject = new \Magento\Framework\DataObject();

$postObject->setData($post);

$this->getDataPersistor()->set('{formname}', $post);

And form page, you can get those data by

$this->postData = (array) $this->getDataPersistor()->get({formname});

For particular field by

$this->postData[{fieldName}]

Example:

Post Action:

<?php
namespace {Vendorname}\{Modulename}\Controller\{Controllername};
use Magento\Framework\App\Request\DataPersistorInterface;
class {PostActioName}
{
    public $dataPersistor;
    
    public function __construct(
        .....
        DataPersistorInterface $dataPersistor,
        ....
    )
    {
        $this->dataPersistor = $dataPersistor;
    }
     public function execute()
    {
        $post = $this->getRequest()->getPostValue();
         try {
            $postObject = new \Magento\Framework\DataObject();
            $postObject->setData($post);
            /* clear form data */
            $this->getDataPersistor()->clear('{form_Name}');
        
        } catch (\Exception $e) {
        ....
            /* set  form data */
            $this->getDataPersistor()->set('{form_Name}', $post);
        ....
        }
        
    }
}

Post value to form Url:

You can this data at block class by Magento\Framework\App\Request\DataPersistorInterface

namespace{Vendorname}\{Modulename}\Block;
use Magento\Framework\App\Request\DataPersistorInterface;
class Form extends \Magento\Framework\View\Element\Template
{
    private $postData = null;
    public $dataPersistor;
    
    public function __construct(
    ....
        \Magento\Framework\View\Element\Template\Context $context,
        DataPersistorInterface $dataPersistor,
        ....
    )
    {
            ....
        $this->dataPersistor = $dataPersistor;  
        parent::__construct($context);
        ....
    }

  public function getPostValue($key)
    {
        if (null === $this->postData) {
            $this->postData = (array) $this->getDataPersistor()->get('{form_Name}');
            $this->getDataPersistor()->clear('{form_Name}');
        }

        if (isset($this->postData[$key])) {
            return (string) $this->postData[$key];
        }

        return '';
    }
}