3

To understand the new magento 2 design structure i'm trying to create a simple frontend form submitting module. In it i'm submitting a number in an input box and i want to multiply it by 2 and display the result in another page. What is the correct architectural flow to achieve it? And please mention a link for a similar example if available.

1 Answer 1

6

You start by defining a route for your module. This is done in <module_directory>/etc/frontend/routes.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="timestwo" frontName="timestwo">
            <module name="Your_Module"/>
        </route>
    </router>
</config>

Then make the 'Index' controller for this route under <module_directory>/Controller/Index.php

<?php

namespace Your\Module\Controller;


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

class Index extends Action
{
    protected $resultPageFactory;

    public function __construct(Context $context, PageFactory $pageFactory)
    {
        $this->resultPageFactory = $pageFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        $resultPage = $this->resultPageFactory->create();

        return $resultPage;
    }
}

Make the layout file for this page under <module_directory>/view/frontend/layout/timestwo_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>Form</title>
    </head>
    <body>
        <referenceContainer name="content">
            <block name="form" class="Magento\Framework\View\Element\Template" template="Your_Module::form.phtml"/>
        </referenceContainer>
    </body>
</page>

Now make the template <module_directory>/view/frontend/templates/form.phtml

<form class="form" action="result" method="post">

    <fieldset class="fieldset">
        <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Test Form') ?></span></legend><br>
        <div class="field required">
            <label for="number" class="label">
                <span><?php /* @escapeNotVerified */ echo __('Input') ?></span>
            </label>

            <div class="control">
                <input type="text" id="number"
                       name="number"
                       class="input-text">
            </div>
        </div>
    </fieldset>

    <div class="actions-toolbar">
        <div class="primary">
            <button type="submit" class="action submit primary" title="<?php /* @escapeNotVerified */ echo __('Submit') ?>">
                <span><?php /* @escapeNotVerified */ echo __('Submit') ?></span>
            </button>
        </div>
    </div>

</form>

Now make the controller for the result page: <module_directory>/Controller/Result.php

<?php

namespace Your\Module\Controller;


use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Element\Messages;
use Magento\Framework\View\Result\PageFactory;

class Result extends Action
{
    /** @var PageFactory $resultPageFactory */
    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()
    {
        $number = $this->getRequest()->getParam('number');

        $resultPage = $this->resultPageFactory->create();

        /** @var Messages $messageBlock */
        $messageBlock = $resultPage->getLayout()->createBlock(
            'Magento\Framework\View\Element\Messages',
            'answer'
        );
        if (is_numeric($number)) {
            $messageBlock->addSuccess($number . ' times 2 is ' . ($number * 2));
        }else{
            $messageBlock->addError('You didn\'t enter a number!');
        }

        $resultPage->getLayout()->setChild(
            'content',
            $messageBlock->getNameInLayout(),
            'answer_alias'
        );

        return $resultPage;
    }
}

Finally, make the layout xml for the result page in <module_directory>/view/frontend/layout/timestwo_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>
</page>

Run php bin/magento setup:upgrade to enable your module, if you haven't already. Now clear the cache. Go to <magento_location>/timestwo in browser to see the form.

5
  • Thanks alot i was stuck in this because i couldn't find a proper tutorial Jul 11, 2016 at 5:42
  • @AaronAllen I followed same thing, but I am getting 404 error. I have created the module registration and configurations also. Could you please help me. Dec 15, 2016 at 10:07
  • Yes, I got it after creating the Index folder in Controller. I don't know why I am getting 404, if I use the above solution. Dec 15, 2016 at 13:00
  • after adding index folder then rename layout file as timestwo_index_index.xml and timestwo_index_result.xml
    – jassi
    Jun 16, 2017 at 6:28
  • I am getting 404 error after creating this.
    – Amy
    Feb 20, 2019 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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