24

I want to create a custom form in frontend and using this form customer can get an appointment.

In my form, I have 4 Fields.

  1. First Name (text filed)
  2. Last Name (text filed)
  3. Phone No. (numeric field)
  4. Booking a time (with date time calendar)

So when a customer fills up this form and does submit I want to insert this data in database and show in the admin section.

How can I achieve this functionality in Magento-2.1

I have referred this link but it's not as per my functionality.

2 Answers 2

53

Assuming you have the following module Company/Module.

Create the frontend router

/app/code/Company/Module/etc/frontend/routes.xml

Create a route to manage :

  • GET request wich going to display HTML form template
  • POST request wich going to send form data to Action Controller Class.
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="companymodule" frontName="companymodule">
            <module name="Company_Module"/>
        </route>
    </router>
</config>

Create the layout

/app/code/Company/Module/view/frontend/layout/module_index_booking.xml

Create a basic layout for associate the Block to the form page phtml template

<?xml version="1.0"?>
<page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <title>HTML title - The booking form page</title>
    </head>
    <body>
        <referenceBlock name="navigation.sections" remove="true" />
        <referenceContainer name="content">
            <block class="Company\Module\Block\Booking" name="companymodule.booking" template="Company_Module::booking.phtml"/>
        </referenceContainer>
    </body>
</page>

Create the Block

/app/code/Company/Module/Block/Booking.php

Create a block with many functions you want for your form.

<?php

namespace Company\Module\Block;

class Booking extends \Magento\Framework\View\Element\Template
{
    /**
     * Construct
     *
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template $context,
        array $data = []
    )
    {
        parent::__construct($context, $data);
       }

    /**
     * Get form action URL for POST booking request
     *
     * @return string
     */
    public function getFormAction()
    {
            // companymodule is given in routes.xml
            // controller_name is folder name inside controller folder
            // action is php file name inside above controller_name folder

        return '/companymodule/controller_name/action';
        // here controller_name is index, action is booking
    }
}

Create the template

/app/code/Company/Module/view/frontend/templates/booking.phtml

Create a template with your HTML form and add the form action corresponding to the routing.

<h1>Booking page</h1>

<form action="<?php echo $block->getFormAction() ?>" method="post">
    <input name="firstname" type="text">
    <input name="lastname" type="text">
    <input name="phone" type="text">
    <input name="bookingTime" type="date">
    <input type="submit" value="Send booking informations">
</form>

Create the Action Controller

/app/code/Company/Module/Controller/Index/Booking.php

Create an Action Controller to manage the requests on the route.

<?php

namespace Company\Module\Controller\Index;

use Magento\Framework\Controller\ResultFactory;

class Booking extends \Magento\Framework\App\Action\Action
{
    /**
     * Booking action
     *
     * @return void
     */
    public function execute()
    {
        // 1. POST request : Get booking data
        $post = (array) $this->getRequest()->getPost();

        if (!empty($post)) {
            // Retrieve your form data
            $firstname   = $post['firstname'];
            $lastname    = $post['lastname'];
            $phone       = $post['phone'];
            $bookingTime = $post['bookingTime'];

            // Doing-something with...

            // Display the succes form validation message
            $this->messageManager->addSuccessMessage('Booking done !');

            // Redirect to your form page (or anywhere you want...)
            $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
            $resultRedirect->setUrl('/companymodule/index/booking');

            return $resultRedirect;
        }
        // 2. GET request : Render the booking page 
        $this->_view->loadLayout();
        $this->_view->renderLayout();
    }
}

In resuming you will have the following architecture :

app
  ├ code
  |   ├ Company
  |   |   ├ Module
  |   |   |   ├ Block
  |   |   |   |   ├ Booking.php
  |   |   |   ├ Controller
  |   |   |   |   ├ Index
  |   |   |   |   |   ├ Booking.php
  |   |   |   ├ etc
  |   |   |   |   ├ frontend
  |   |   |   |   |   ├ routes.xml
  |   |   |   ├ view
  |   |   |   |   ├ frontend
  |   |   |   |   |   ├ layout
  |   |   |   |   |   |   ├ module_index_booking.xml
  |   |   |   |   |   ├ templates
  |   |   |   |   |   |   ├ booking.phtml

Then run following commands :

php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush

Then you can access to your custom form page: http://localhost/companymodule/index/booking

Happy coding!

17
  • how can i see this is in front end?
    – Naveenbos
    Dec 22, 2016 at 10:12
  • Not showing anything in front end, i used routes.xml frontname, but it is redirecting to the 404 not found page
    – Naveenbos
    Dec 22, 2016 at 10:19
  • 2
    Please take note to place your controller in a folder called index. I've tried it also I got 404 page. But as I visited devdocs.magento.com and read the standard instructions, I managed to solve my problem. I hope this will help you. Jun 15, 2017 at 3:43
  • 1
    @MartijnvanHoof If you extend the contact vendor module be sure to follow what is the file structure of the module. and there you can extend and create your own logic. Nov 27, 2017 at 14:50
  • 1
    i get this error any help please Argument 1 passed to Magento\Framework\View\Element\Template::__construct() must be an instance of Magento\Framework\View\Element\Template\Context, instance of Magento\Framework\View\Element\Template given Jan 17, 2020 at 10:07
0

From the choice response I change the line if($post){ to if($post['firstname']){

And so I can see the form from frontend and do a click to send to another action.

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