1

How to create a custom form for sending email in Magento 2

Fields are like

  • First name
  • Last name
  • Address
  • City
  • State
  • Zip code
  • Email
  • Phone
  • Product type: checkbox Option like (1) One (2) Two
  • File upload
  • comment
3

4 Answers 4

18

Try below code in your controller

vendorname/modulename/controller/Index/index.php

<?php /** * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Vendor\Module\Controller\Index; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem; use Magento\Framework\App\Request\DataPersistorInterface; class Index extends Action { private $dataPersistor; /** * @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page */ protected $context; private $fileUploaderFactory; private $fileSystem; /** * @var \Magento\Framework\Mail\Template\TransportBuilder */ protected $_transportBuilder; /** * @var \Magento\Framework\Translate\Inline\StateInterface */ protected $inlineTranslation; /** * @var \Magento\Framework\App\Config\ScopeConfigInterface */ protected $scopeConfig; /** * @var \Magento\Store\Model\StoreManagerInterface */ /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig */ public function __construct( \Magento\Framework\App\Action\Context $context, Filesystem $fileSystem, \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory, \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder, \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, \Modia\Cform\Helper\Data $helper, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig ) { parent::__construct($context,$transportBuilder,$inlineTranslation, $scopeConfig ); $this->fileUploaderFactory = $fileUploaderFactory; $this->fileSystem = $fileSystem; $this->_transportBuilder = $transportBuilder; $this->inlineTranslation = $inlineTranslation; $this->helper = $helper; $this->scopeConfig = $scopeConfig; } public function execute() { $post = $this->getRequest()->getPostValue(); $filesData = $this->getRequest()->getFiles('upload_document'); if ($filesData['name']) { $uploader = $this->fileUploaderFactory->create(['fileId' => 'upload_document']); $uploader->setAllowRenameFiles(true); $uploader->setFilesDispersion(true); $uploader->setAllowCreateFolders(true); $path = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath('test-doc'); $result = $uploader->save($path); $upload_document = 'test-doc'.$uploader->getUploadedFilename(); $filePath = $result['path'].$result['file']; $fileName = $result['name']; } else { $upload_document = ''; $filePath = ''; $fileName = ''; } $txt='<table>'; if($post['fname']){ $txt.='<tr><td><strong>Client Name</strong>:'.$post['fname'].'</td></tr>'; } if($post['address']){ $txt.='<tr><td><strong>Address</strong>:'.$post['address'].'</td></tr>'; } if($post['city']){ $txt.='<tr><td><strong>City</strong>:'.$post['city'].'</td></tr>'; } if($post['state']){ $txt.='<tr><td><strong>State/Province</strong>:'.$post['state'].'</td></tr>'; } if($post['zipcode']){ $txt.='<tr><td><strong>Zip Code</strong>:'.$post['zipcode'].'</td></tr>'; } if($post['phone']){ $txt.='<tr><td><strong>Phone</strong>:'.$post['phone'].'</td></tr>'; } if($post['email']){ $txt.='<tr><td><strong>Email</strong>:'.$post['email'].'</td></tr>'; } if(!empty($post['project_type'])){ $projecttypearray = implode(",",$post['project_type']); $txt.='<tr><td><strong>Project Type</strong>:'.$projecttypearray.'</td></tr>'; } if($post['comment']){ $txt.='<tr><td><strong>Comment</strong>:'.$post['comment'].'</td></tr>'; } $txt.='</table>'; //echo $txt; $customerName='Demo Form'; $message=$txt; $userSubject= 'Demo From '; $fromEmail= '[email protected]'; $fromName = 'Test Demo Form'; $templateVars = [ 'store' => 1, 'customer_name' => $customerName, 'subject' => $userSubject, 'message' => $message ]; $from = ['email' => $fromEmail, 'name' => $fromName]; $this->inlineTranslation->suspend(); $to = '[email protected]'; $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; $templateOptions = [ 'area' => \Magento\Framework\App\Area::AREA_FRONTEND, 'store' => 1 ]; $transport = $this->_transportBuilder->setTemplateIdentifier(5, $storeScope) ->setTemplateOptions($templateOptions) ->setTemplateVars($templateVars) ->setFrom($from) ->addTo($to) ->addAttachment($filePath, $fileName) ->getTransport(); $transport->sendMessage(); $this->inlineTranslation->resume(); $this->messageManager->addSuccess(__('Form successfully submitted')); $this->_redirect('form'); } } 

vendorname/modulename/etc/di.xml

 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="\Magento\Framework\Mail\Template\TransportBuilder" type="\Vendorname\Modulename\Magento\Mail\Template\TransportBuilder" /> </config> 

Vendorname/Modulename/Magento/Mail/Template/TransportBuilder.php

<?php namespace Vendorname\Modulename\Magento\Mail\Template; class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder { public function addAttachment($file, $name) { if (!empty($file) && file_exists($file)) { $this->message ->createAttachment( file_get_contents($file), \Zend_Mime::TYPE_OCTETSTREAM, \Zend_Mime::DISPOSITION_ATTACHMENT, \Zend_Mime::ENCODING_BASE64, basename($name) ); } return $this; } } 

Vendorname/Modulename/view/frontend/templates/test.phtml

 <div class="container"> <form class="form-horizontal" method="post" enctype="multipart/form-data" action="url/cform/index/index"> <div class="form-group"> <div class="row"> <div class="col-sm-12"> <label for="">Name</label> </div> </div> <div class="row"> <div class="col-sm-6"> <input class="form-control" type="text" id="" name="fname" placeholder="first name"> </div> <div class="col-sm-6"> <input class="form-control" type="text" id="" name="lname" placeholder="last name"> </div> </div> </div> <div class="form-group"> <label for="">Address</label> <textarea class="col-sm-12 form-control" rows="3" placeholder="" name="address"></textarea> </div> <div class="form-group"> <div class="row"> <div class="col-sm-5"> <label for="">City</label> <input class="form-control" type="text" name="city" id="" placeholder=""> </div> <div class="col-sm-4"> <label for="">State/Province</label> <input class="form-control" type="text" name="state" id="" placeholder=""> </div> <div class="col-sm-3"> <label for="">Zip Code</label> <input class="form-control" type="text" name="zipcode" id="" placeholder=""> </div> </div> </div> <div class="form-group"> <div class="row"> <div class="col-sm-8"> <label for="">Phone</label> <div class="row"> <div class="col-sm-5"> <input class="form-control" type="text" id="" name="phone" placeholder=""> </div> <div class="col-sm-2 phone-or"> <span>OR</span> </div> <div class="col-sm-5"> <input class="form-control" type="text" id="" placeholder=""> </div> </div> </div> <div class="col-sm-4"> <label for="">Email</label> <input class="form-control" type="email" id="email" name="email" placeholder=""> </div> </div> </div> <div class="form-group"> <div class="row"> <div class="col-sm-2"> <label for="">Project Type :</label> </div> <div class="col-sm-10"> <label class="checkbox-inline"> <input type="checkbox" id="" value="One1" name="project_type[]"> <span>Residential</span> </label> <label class="checkbox-inline"> <input type="checkbox" id="" value="One2" name="project_type[]"> <span>Commercial</span> </label> </div> </div> </div> <div class="col-md-4 col-xs-12"> <input accept="image/*" name="upload_document" type="file" value="" /> </div> <div class="form-group"> <div class="row"> <div class="col-sm-2"> <label for="">Comment :</label> </div> <div class="col-sm-10"> <textarea class="form-control comment" rows="3" name="comment" placeholder="additional information about your project"></textarea> </div> </div> </div> <div class="row"> <button type="submit" class="btn btn-primary">SUBMIT</button> </div> </form> </div> 

Now call in cms page

{{block class="Magento\Framework\View\Element\Template" template="Vendorname_Modulename::test.phtml" }} 
2
  • I tried this code but it's not working Commented Oct 4, 2018 at 16:43
  • 1
    This answer is very lacking in context and it has multiple errors in it, but I eventually debugged every error and filled in all the gaps to get it to work somehow. Commented Nov 15, 2019 at 13:54
2

app/code/Vendor/Cform/etc/module.xml

<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_Cform" setup_version="2.2.0"> </module> </config> 

app/code/Vendor/Cform/registration.php

<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_Cform', __DIR__ ); 

app/code/Vendor/Cform/etc/frontend/routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd"> <router id="standard"> <route id="cform" frontName="cform"> <module name="Vendor_Cform" /> </route> </router> </config> 

app/code/Vendor/Cform/Setup/InstallSchema.php

<?php namespace Vendor\Cform\Setup; use Magento\Framework\Setup\InstallSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; /** * @codeCoverageIgnore */ class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $installer = $setup; $installer->startSetup(); /** * Create table 'vendor_contect' */ $table = $installer->getConnection()->newTable( $installer->getTable('vendor_contect') )->addColumn( 'contect_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], 'Contect Id' )->addColumn( 'name', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 255, ['nullable' => false], 'Name' )->addColumn( 'email', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 255, ['nullable' => false], 'Email Id' )->addColumn( 'telephone', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, ['nullable'=> false], 'Phone Number' )->addColumn( 'comment', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 255, ['nullable' => false], 'What’s on your mind?' ); $installer->getConnection()->createTable($table); } } 

app/code/Vendor/Cform/view/frontend/templates/form.phtml

<form id="contact-form" class="form-horizontal" method="post" enctype="multipart/form-data" action="<?php echo $this->getUrl("cform/index/index")?>"> <h1><?= $block->escapeHtml(__('Contact Form')) ?></h1> <fieldset class="fieldset"> <div class="field name"> <label class="label" for="name"><span><?= $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> <input name="name" id="name" class="input-text" type="text" /> </div> </div> <div class="field email"> <label class="label" for="email"><span><?= $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input name="email" id="email" class="input-text" type="email" /> </div> </div> <div class="field telephone"> <label class="label" for="telephone"><span><?= $block->escapeHtml(__('Phone Number')) ?></span></label> <div class="control"> <input name="telephone" id="telephone" class="input-text" type="text" /> </div> </div> <div class="field comment"> <label class="label" for="comment"><span><?= $block->escapeHtml(__('What’s on your mind?')) ?></span></label> <div class="control"> <textarea name="comment" id="comment" class="input-text" cols="5" rows="3" ></textarea> </div> </div> <?= $block->getChildHtml('form.additional.info') ?> </fieldset> <div class="actions-toolbar"> <div class="primary"> <input type="hidden" name="hideit" id="hideit" value="" /> <button type="submit" id="add" title="" class="action submit primary"> <span><?= $block->escapeHtml(__('Submit')) ?></span> </button> </div> </div> </form> <script> require(['jquery'],function($){ $(document).ready(function(){ $("#add").click(function(){ var customurl = "<?php echo $this->getUrl("cform/index/index") ?>"; $.ajax({ url: customurl, type: "POST", data: $(this).closest('form').serialize(), dataType: "json", success: function(result){ console.log(result); } }); $('#contact-form')[0].reset(); return false; }); }); }); </script> 

app/code/Vendor/Cform/Controller/Index/index.php

<?php namespace Vendor\Cform\Controller\Index; use Magento\Framework\App\Action\Action; class Index extends Action { public function __construct( \Magento\Framework\App\Action\Context $context ) { parent::__construct($context); } public function execute() { $post = $this->getRequest()->getPostValue(); $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $data = $objectManager->create('Vendor\Cform\Model\Cform'); $data->setData($post); $data->save(); /* echo "hello"; exit; */ $this->messageManager->addSuccess(__('Form successfully submitted')); } } 

app/code/Vendor/Cform/Model/Cform.php

<?php namespace Vendor\Cform\Model; class Cform extends \Magento\Framework\Model\AbstractModel { /** * Initialize resource model * * @return void */ protected function _construct() { $this->_init('Vendor\Cform\Model\ResourceModel\Cform'); } } 

app/code/Vendor/Cform/Model/ResourceModel/Cform.php

<?php namespace Vendor\Cform\Model\ResourceModel; class Cform extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { protected $storeManager; public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, $connectionName = null ) { parent::__construct($context, $connectionName); $this->storeManager = $storeManager; } protected function _construct() { $this->_init('vendor_contect', 'contect_id'); } } 

app/code/Vendor/Cform/Model/ResourceModel/Cform/Collection.php

<?php namespace Vendor\Cform\Model\ResourceModel\Cform; use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; class Collection extends AbstractCollection { protected $_idFieldName = \Vendor\Cform\Model\Cform::CONTECT_ID; /** * Define resource model * * @return void */ protected function _construct() { $this->_init('Vendor\Cform\Model\Cform', 'Vendor\Cform\Model\ResourceModel\Cform'); } } 

CMS page Call

{{block class="Magento\Framework\View\Element\Template" template="Vendor_Cform::form.phtml" }} 

app/code/Vendor/Cform/view/frontend/layout/contactform_index_index.xml

<?xml version="1.0"?> <!-- /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="Vendor\ContactForm\Block\Form" name="contactForm" template="Vendor_ContactForm::form.phtml"> <container name="form.additional.info" label="Form Additional Info"/> </block> </referenceContainer> </body> </page> 
1
  • 1
    Is this linked to your other answer? I know in test.phtml, it refers to "cform" in the form action - I assume it's this? Commented Jan 14, 2019 at 15:48
1
  1. Create a simple html form and submit data to your controller.
  2. Get all your post values in your controller and send mail using below function.

You can send mail using Zend_Mail() function.

// Get your post values $firstname = "Dinesh"; $lastname = "Yadav"; // Send Mail functionality starts from here $from = "[email protected]"; $nameFrom = "From Name"; $to = "[email protected]"; $nameTo = "To Name"; $body = " <div> <b>".$firstname."</b> <i>".$lastname."</i> </div>"; $email = new \Zend_Mail(); $email->setSubject("Email Subject"); $email->setBodyHtml($body); // use it to send html data //$email->setBodyText($body); // use it to send simple text data $email->setFrom($from, $nameFrom); $email->addTo($to, $nameTo); $email->send(); 
0

Note: Contact is vendor and Us is module.Here i am posting my form data to my frontend controller Post.php

step 1: Create email_templates.xml in app/code/Contact/Us/etc

<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Email/etc/email_templates.xsd"> <template id="send_email_email_template" label="Email Form" file="email_template.html" type="text" module="Contact_Us" area="frontend"/> 

step 2: Create email_template.html in app/code/Contact/Us/view/frontend/email

<!--@subject xMage-support@--> <!--@vars { "var data.comment":"xMage-support", "var data.email":"[email protected]", "var data.name":"XMageStore" } @--> {{template config_path="design/email/header_template"}} {{trans "Dear %name" name=$data.name}} {{trans "we received your request regarding %queryregarding" queryregarding=$data.requestType}} {{template config_path="design/email/footer_template"}} 

Step 3: Create Post.php controller in app/code/Contact/Us/Controller/Post

<?php namespace Contact\Us\Controller\Index; class Post extends \Magento\Framework\App\Action\Action { /** * @var \Magento\Framework\Mail\Template\TransportBuilder */ protected $_transportBuilder; /** * @var \Magento\Framework\Translate\Inline\StateInterface */ protected $inlineTranslation; /** * @var \Magento\Framework\App\Config\ScopeConfigInterface */ protected $scopeConfig; /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; /** * @var \Magento\Framework\Escaper */ protected $_escaper; /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager */ public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder, \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Escaper $escaper ) { parent::__construct($context); $this->_transportBuilder = $transportBuilder; $this->inlineTranslation = $inlineTranslation; $this->scopeConfig = $scopeConfig; $this->storeManager = $storeManager; $this->_escaper = $escaper; } /** * Post user question * * @return void * @throws \Exception */ public function execute() { $post = $this->getRequest()->getPostValue(); if (!$post) { $this->_redirect('/'); return; } $this->inlineTranslation->suspend(); try { $recipientMail = $this->getRequest()->getPostValue('email'); $postObject = new \Magento\Framework\DataObject(); $postObject->setData($post); $error = false; $sender = [ 'name' => 'xMageStore', 'email' => '[email protected]', ]; $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; $transport = $this->_transportBuilder ->setTemplateIdentifier('send_email_email_template') // this code we have mentioned in the email_templates.xml ->setTemplateOptions( [ 'area' => \Magento\Framework\App\Area::AREA_FRONTEND, // this is using frontend area to get the template file 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, ] ) ->setTemplateVars(['data' => $postObject]) ->setFrom($sender) ->addTo($recipientMail) ->getTransport(); $transport->sendMessage(); $this->inlineTranslation->resume(); $this->messageManager->addSuccess( __('Thanks for contacting us. We\'ll respond to you very soon.') ); $this->_redirect('/'); return; } catch (\Exception $e) { $this->inlineTranslation->resume(); $this->messageManager->addError( __('We can\'t process your request right now. Sorry, that\'s all we know.' . $e->getMessage()) ); $this->_redirect('/'); return; } } } 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.