20

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.

42

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!

  • how can i see this is in front end? – Naveenbos Dec 22 '16 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 '16 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. – MazeStricks Jun 15 '17 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. – MazeStricks Nov 27 '17 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 – jibin george Jan 17 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.