0

I am currently trying to create a custom form in Magento 2.2.7. The purpose of this contact form is to provide our trade (wholesale) customers with a separate contact form to our retail customers (i.e. it will go to a seperate email to the main contact form).

I am using the method given in question 198838 to create this form. However when I click "Submit" nothing happens and in the Google developer console I get the following error:

POST https://mysite.magedemo.co.uk/cform/index/index/ 500

enter image description here

My file system for this module is as follows:

enter image description here

My code is as follows:

Controller > Index > Index.php

    <?php
    /**
     *
     * Copyright © 2016 Magento. All rights reserved.
     * See COPYING.txt for license details.
     */
    namespace Trading\Cform\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 $fileSy

stem;


    /**
     * @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= 'admin@gmail.com.com';
        $fromName = 'Test Demo Form';

         $templateVars = [
                    'store' => 1,
                    'customer_name' => $customerName,
                    'subject' => $userSubject,
                    'message'   => $message
                ];
        $from = ['email' => $fromEmail, 'name' => $fromName];
        $this->inlineTranslation->suspend();


        $to = 'test@gmail.com';     

        $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');
    }

}

Magento > Mail > Template > TransportBuilder.php

<?php
namespace Trading\Cform\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;
    }
}

Model > ResourceModel > Cform > Collection.php

<?php
namespace Trading\Cform\Model\ResourceModel\Cform;

use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{

    protected $_idFieldName = \Trading\Cform\Model\Cform::CONTECT_ID;

    /**
     * Define resource model
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('Trading\Cform\Model\Cform', 'Trading\Cform\Model\ResourceModel\Cform');
    }

}

Model > ResourceModel > Cform.php

<?php

namespace Trading\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('trading_contect', 'contect_id');
    }
}

Model > Cform.php

<?php

namespace Trading\Cform\Model;

class Cform extends \Magento\Framework\Model\AbstractModel
{
    /**
     * Initialize resource model
     *
     * @return void
     */

    protected function _construct()
    {
        $this->_init('Trading\Cform\Model\ResourceModel\Cform');
    }

}

Setup > InstallSchema.php

<?php
namespace Trading\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('trading_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);
    }
}

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="Trading_Cform" />
        </route>
    </router>
</config>

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="\Trading\Cform\Magento\Mail\Template\TransportBuilder" />
</config>

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="Trading_Cform" setup_version="1.0.0">
    </module>
</config>

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>

registration.php

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

If someone could advise me on what I am doing wrong here I would greatly appreciate it.

1

create layout file

view/frontend/layout/cform_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <referenceContainer name="content">
        <block class="Trading\Cform\Block\Custom" name="customer_index_gallery" template="Trading_Cform::form.phtml" cacheable="false"/>
    </referenceContainer>
</page>

Controller file

Controller\Index\Index.php

<?php
namespace Trading\Cform\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action
{
    protected $_pageFactory;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $pageFactory)
    {
        $this->_pageFactory = $pageFactory;
        return parent::__construct($context);
    }

    public function execute()
    {
        return $this->_pageFactory->create();
    }
}

view/frontend/templates/form.phtml

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

/app/codeTrading/Cform/Block

<?php

namespace Trading\Cform\Block;

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

    /**
     * Get form action URL for POST booking request
     *
     * @return string
     */
    public function getFormAction()
    {
        return '/cform/index/index';
        // here controller_name is index, action is booking
    }
}
  • Try this @CJNotts – Arunprabakaran M Jun 28 at 14:36
  • Thanks. Could you let me know the file paths that I need to create those files in please? – CJNotts Jun 28 at 14:43
  • 1
    I updated file path – Arunprabakaran M Jun 28 at 14:46
  • Hi. That seems to be doing something now at least. I'm getting the message "Navigated to mysite.magedemo.co.uk/test-page jquery-migrate.js:21 JQMIGRATE: Logging is active" I'm guessing now that I just have to specify that I want it to send the form details to an email address? – CJNotts Jun 28 at 14:53
  • mysite.magedemo.co.uk/cform/index/index – Arunprabakaran M Jun 28 at 14:55
0

With much thanks to MSA for pointing me in the right direction. I've now created a working form based on a few previously asked questions but in particular 125478:

The file system now looks as follows:

enter image description here

All of these files are placed in the following location:

App > Code > Trade > Tform

First the registration file:

registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Trade_Tform',
    __DIR__
);

Block > Tcontact.php

 <?php

namespace Trade\Tform\Block;

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

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

        return '/tradetform/index/tcontact';
        // here controller_name is index, action is tcontact
    }
}

Controller > Index > Tcontact.php

<?php

namespace Trade\Tform\Controller\Index;

use Magento\Framework\Controller\ResultFactory;

class Tcontact 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
            $name    = $post['name'];
            $email   = $post['email'];
            $phone   = $post['phone'];
            $comment = $post['comment'];
            $messagetitle = "Enquiry From Custom Contact Form";
            $messagecontent = 
            $messagetitle."\n"."\n".
            "name: ".$name."\n"."\n".
            "email: ".$email."\n"."\n".
            "phone: ".$phone."\n"."\n".
            "comment: ".$comment."\n";

            // Send email to the following specified address
            mail("emailaddress@emailprovider.com","Trade Enquiry",$messagecontent);
            // Display the succes form validation message
            $this->messageManager->addSuccessMessage('Message Sent!');

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

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

etc > frontend > routes.xml

<?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="tradetform" frontName="tradetform">
            <module name="Trade_Tform"/>
        </route>
    </router>
</config>

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="Trade_Tform" setup_version="1.0.0" />
</config>

view > frontend > layout > tradetform_index_tcontact.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <title>Trade Form</title>
    </head>
    <body>
        <referenceBlock name="navigation.sections" remove="true" />
        <referenceContainer name="content">
            <block class="Trade\Tform\Block\Tcontact" name="tradetform.tcontact" template="Trade_Tform::tcontact.phtml"/>
        </referenceContainer>
    </body>
</page>

view > frontend > templates > tcontact.phtml

<form action="<?php echo $block->getFormAction() ?>" data-mage-init='{"validation":{}}' method="post">
    <p>Contact Name  <span style=" color: #e02b27; font-size: 1.2rem;">*</span>
    <input name="name" type="text" data-validate='{"required":true}'></p>
    <p>Contact Email <span style=" color: #e02b27; font-size: 1.2rem;">*</span>
    <input name="email" type="text" data-validate='{"required":true}'></p>
    <p>Contact Phone
    <input name="phone" type="text"></p>
    <p>Message
    <textarea name="comment" cols="40" rows="5"></textarea></p>
    <input type="submit" value="Submit">
</form>

After this it was a case of running the upgrade command in CLI.

php bin/magento setup:upgrade

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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