23

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.

Nikunj Vadariya
4,0371 gold badge21 silver badges30 bronze badges
asked Jul 13, 2016 at 7:48

2 Answers 2

52

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!

Hardik Makwana
1,40417 silver badges39 bronze badges
answered Oct 10, 2016 at 13:30
17
  • how can i see this is in front end? Commented 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 Commented 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. Commented 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. Commented 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 Commented 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.

Piyush
5,9249 gold badges35 silver badges67 bronze badges
answered Oct 24, 2017 at 6:24

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.