I need to create a modal that pops up and shows the default Magento 2 contact form. What I need it to do is submit the form and then display a "Thank you" message in the same modal without refreshing the page. Where I am stuck is creating the controller to handle the submission.
I'm new to Magento 2 development so I apologize in advance for any stupidity contained in this post. Anyways, here is my controller:
Code:
namespace AdamGreenwell\ContactUs\Controller\Modal;
use Magento\Contact\Model\ConfigInterface;
use Magento\Contact\Model\MailInterface;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\HTTP\PhpEnvironment\Request;
use Psr\Log\LoggerInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\DataObject;
use Magento\Framework\UrlFactory;
class Ajaxcontact extends \Magento\Contact\Controller\Index
{
/**
* @var DataPersistorInterface
*/
private $dataPersistor;
/**
* @var Context
*/
private $context;
/**
* @var MailInterface
*/
private $mail;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var \Magento\Framework\Json\Helper\Data $helper
*/
protected $helper;
/**
* @var \Magento\Framework\Controller\Result\JsonFactory
*/
protected $resultJsonFactory;
/**
* @var \Magento\Framework\Controller\Result\RawFactory
*/
protected $resultRawFactory;
/**
* @param Context $context
* @param ConfigInterface $contactsConfig
* @param MailInterface $mail
* @param DataPersistorInterface $dataPersistor
* @param LoggerInterface $logger
* @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
* @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
*/
public function __construct(
Context $context,
ConfigInterface $contactsConfig,
MailInterface $mail,
DataPersistorInterface $dataPersistor,
LoggerInterface $logger = null,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
\Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
UrlFactory $urlFactory
) {
parent::__construct($context, $contactsConfig);
$this->context = $context;
$this->mail = $mail;
$this->dataPersistor = $dataPersistor;
$this->resultJsonFactory = $resultJsonFactory;
$this->resultRawFactory = $resultRawFactory;
$this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
$this->urlModel = $urlFactory->create();
}
/**
* Post user question
*
* @return Redirect
*/
public function execute() {
if (!$this->isPostRequest()) {
return $this->resultRedirectFactory->create()->setPath('/');
}
/** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
$credentials = null;
$httpBadRequestCode = 400;
try {
$credentials = $this->getRequest()->getParams();
$this->sendEmail($this->validatedParams());
$this->messageManager->addSuccessMessage(
__('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon. And hopefully this works')
);
$this->dataPersistor->clear('contactus');
$response['redirectUrl'] = $this->urlModel->getUrl('/');
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
$this->dataPersistor->set('contactus', $this->getRequest()->getParams());
} catch (\Exception $e) {
$this->logger->critical($e);
$this->messageManager->addErrorMessage(
__('An error occurred while processing your form. Please try again later.')
);
$this->dataPersistor->set('contact_us', $this->getRequest()->getParams());
}
return $this->resultRedirectFactory->create()->setPath('contact/index');
}
/**
* @param array $post Post data from contact form
* @return void
*/
private function sendEmail($post)
{
$this->mail->send(
$post['email'],
['data' => new DataObject($post)]
);
}
/**
* @return bool
*/
private function isPostRequest()
{
/** @var Request $request */
$request = $this->getRequest();
return !empty($request->getPostValue());
}
/**
* @return array
* @throws \Exception
*/
private function validatedParams()
{
$request = $this->getRequest();
if (trim($request->getParam('name')) === '') {
throw new LocalizedException(__('Name is missing'));
}
if (trim($request->getParam('comment')) === '') {
throw new LocalizedException(__('Comment is missing'));
}
if (false === \strpos($request->getParam('email'), '@')) {
throw new LocalizedException(__('Invalid email address'));
}
if (trim($request->getParam('hideit')) !== '') {
throw new \Exception();
}
return $request->getParams();
}
}
and my frontend template file:
Code:
<div class="block contact-us-modal" id="contact-us-modal" style="display:none;">
<div class="block-title form-heading">
<h5 class="block-contact-us-heading" role="heading" aria-level="2"><?= $block->escapeHtml(__('Contact Us')) ?></h5>
</div>
<div class="block-content" aria-labelledby="block-contact-us-heading">
<form class="form contact-us"
action="<?= $block->escapeUrl($block->getFormAction()) ?>"
id="contact-form"
method="post"
data-hasrequired="<?= $block->escapeHtmlAttr(__('* Required Fields')) ?>"
data-mage-init='{"validation":{}}'>
<fieldset class="fieldset">
<div class="field firstname required">
<label class="label" for="name"><span><?= $block->escapeHtml(__('First Name')) ?></span></label>
<div class="control">
<input name="firstname" id="firstname" title="<?= $block->escapeHtmlAttr(__('First Name')) ?>" value="<?= $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('name') ?: $this->helper('Magento\Contact\Helper\Data')->getUserName()) ?>" class="input-text" type="text" data-validate="{required:true}"/>
</div>
</div>
<div class="field lastname required">
<label class="label" for="name"><span><?= $block->escapeHtml(__('Last Name')) ?></span></label>
<div class="control">
<input name="lastname" id="lastname" title="<?= $block->escapeHtmlAttr(__('Last Name')) ?>" value="<?= $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('name') ?: $this->helper('Magento\Contact\Helper\Data')->getUserName()) ?>" class="input-text" type="text" data-validate="{required:true}"/>
</div>
</div>
<div class="field email required">
<label class="label" for="email"><span><?= $block->escapeHtml(__('Email')) ?></span></label>
<div class="control">
<input name="email" id="email" title="<?= $block->escapeHtmlAttr(__('Email')) ?>" value="<?= $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('email') ?: $this->helper('Magento\Contact\Helper\Data')->getUserEmail()) ?>" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}"/>
</div>
</div>
<div class="field order">
<label class="label" for="order"><span><?= $block->escapeHtml(__('Order Number')) ?></span></label>
<div class="control">
<input name="order" id="order" title="<?= $block->escapeHtmlAttr(__('Order Number')) ?>" value="<?= $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('telephone')) ?>" class="input-text" type="text" />
</div>
</div>
<div class="field comment required">
<label class="label" for="comment"><span><?= $block->escapeHtml(__('Message')) ?></span></label>
<div class="control">
<textarea name="comment" id="comment" title="<?= $block->escapeHtmlAttr(__('Message')) ?>" class="input-text" cols="5" rows="6" data-validate="{required:true}"><?= $block->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getPostValue('comment')) ?></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" title="<?= $block->escapeHtmlAttr(__('Submit')) ?>" class="action submit primary contact-submit">
<span><?= $block->escapeHtml(__('Submit')) ?></span>
</button>
</div>
</div>
</form>
<p class="contact-us-required">* Required</p>
</div>
</div>
<script>
require(
[
'jquery',
'Magento_Ui/js/modal/modal'
],
function (
$,
modal
) {
var options = {
type: 'popup',
responsive: true,
innerScroll: true,
modalClass: 'contact-us-modal',
buttons: false
};
var footerElem = $('.footer-links');
var contactusLink = footerElem.find('#contact-us');
contactusLink.click(function(e){
e.preventDefault(e);
});
modal(options, $('#contact-us-modal'));
var popup = '';
$("#contact-us").on('click', function () {
popup = $('#contact-us-modal').modal("openModal");
});
}
);
</script>
<script>
require([
'jquery',
'mage/mage'
], function ($) {
var dataForm = $('#contact-form');
dataForm.mage('validation', {});
$('.contact-submit').on('click', function () {
if (dataForm.validation('isValid')) {
var formData = new FormData();
$.ajax({
url: '<?php echo $this->getUrl('contactus/modal/ajaxcontact'); ?>',
data: formData,
processData: false,
contentType: "application/json",
showLoader: true,
type: 'POST',
dataType: 'json',
success: function (response) {
if (!response.errors) {
if (response.redirectUrl) {
location.href = response.redirectUrl;
}
} else {
$(' .contact-us .messages .message div').text(response.message);
$(' .contact-us .messages .message').show();
setTimeout(function () {
$('.contact-us .messages .message').hide();
}, 5000);
}
}
});
return false;
}
})
});
</script>
I'm getting either a 400 or a 500 error when I try to submit the form. Since I am extending the built-in Contact module, I'm trying to use as little customization as possible but am not sure where I am going wrong. Any help or direction is certainly appreciated.
View more threads in the same category:
Bookmarks