How to Make an Ajax Call in Magento 2 Module
In this article, we are going to understand and implement how to make an ajax call in Magento 2 Module. We will override the Magento 2 Contact us module to submit the contact form data using an ajax call. We will override the contact us module frontend PHTML file and Post Controller in our custom module.
On successful ajax call, we will return a success message from the controller. That message we will display on front side. You can also return the whole HTML using Ajax call.
Getting Started: Development
Step 1: Create module.xml file under app/code/Codextblog/Contactajax/etc
directory
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> <module name="Codextblog_Contactajax" setup_version="1.0.0"></module> <sequence> <module name="Magento_Contact"/> </sequence> </config>
Step 2: Create registration.php file under app/code/Codextblog/Contactajax
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Codextblog_Contactajax', __DIR__ );
Step 3: Override contact_index_index.xml layout file in our module under app/code/Codextblog/Contactajax/view/frontend/layout
directory
<?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"> <referenceBlock name='contactForm'> <action method='setTemplate'> <argument name='template' xsi:type='string'>Codextblog_Contactajax::form.phtml</argument> </action> </referenceBlock> </page>
Step 4: Override form.phtml template file under app/code/Codextblog/Contactajax/view/frontend/templates
directory
<?php /** * Copyright © 2013-2017 Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ ?> <form class="form contact" action="<?php /* @escapeNotVerified */ echo $block->getFormAction(); ?>" id="contact-form" method="post" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" > <fieldset class="fieldset"> <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Write Us') ?></span></legend><br /> <div class="field note no-label"><?php /* @escapeNotVerified */ echo __('Jot us a note and we’ll get back to you as quickly as possible.') ?></div> <div class="field name required"> <label class="label" for="name"><span><?php /* @escapeNotVerified */ echo __('Name') ?></span></label> <div class="control"> <input name="name" id="name" title="<?php /* @escapeNotVerified */ echo __('Name') ?>" value="<?php echo $block->escapeHtml($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><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> <input name="email" id="email" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" value="<?php echo $block->escapeHtml($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 telephone"> <label class="label" for="telephone"><span><?php /* @escapeNotVerified */ echo __('Phone Number') ?></span></label> <div class="control"> <input name="telephone" id="telephone" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" value="<?php echo $block->escapeHtml($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><?php /* @escapeNotVerified */ echo __('What’s on your mind?') ?></span></label> <div class="control"> <textarea name="comment" id="comment" title="<?php /* @escapeNotVerified */ echo __('What’s on your mind?') ?>" class="input-text" cols="5" rows="3" data-validate="{required:true}"><?php echo $block->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getPostValue('comment')) ?></textarea> </div> </div> <?php echo $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="<?php /* @escapeNotVerified */ echo __('Submit') ?>" class="action submit primary"> <span><?php /* @escapeNotVerified */ echo __('Submit') ?></span> </button> </div> </div> </form> <?php $ajaxurl = $block->getFormAction(); ?> <script type="text/x-magento-init"> { "*": { "Codextblog_Contactajax/js/contactajax": { "AjaxUrl": "<?php echo $ajaxurl; ?>" } } } </script>
Here we have removed the data-mage-init='{“validation”:{}}’ form attribute in line no 8. This attribute requires for form validation. We will define this validation in our custom js file in next step. We have added javascript call at the end of the file to include our custom js and pass an AjaxUrl as a parameter.
Make an Ajax Call
Step 5: Create contactajax.js file under app/code/Codextblog/Contactajax/view/frontend/web/js
directory
define([ "jquery", "jquery/ui" ], function($){ "use strict"; function main(config, element) { var $element = $(element); var AjaxUrl = config.AjaxUrl; var dataForm = $('#contact-form'); dataForm.mage('validation', {}); $(document).on('click','.submit',function() { if (dataForm.valid()){ event.preventDefault(); var param = dataForm.serialize(); alert(param); $.ajax({ showLoader: true, url: AjaxUrl, data: param, type: "POST" }).done(function (data) { $('.note').html(data); $('.note').css('color', 'red'); document.getElementById("contact-form").reset(); return true; }); } }); }; return main; });
Here we have defined the main function that is triggered whenever form.phtml file included in HTML. In line no 12, we have defined the validation. On form submit button if form validation is correct we are making an Ajax call to Contact Module Post.php controller. On an Ajax complete, we are printing the response and reset the form.
Override Controller
Step 6: Create di.xml file under app/code/Codextblog/Contactajax/etc
directory with following content
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Contact\Controller\Index\Post" type="Codextblog\Contactajax\Controller\Magento\Contact\Index\Post" /> </config>
Step 7: Override Post.php controller file under app/code/Codextblog/Contactajax/Controller/Magento/Contact/Index
directory
<?php namespace Codextblog\Contactajax\Controller\Magento\Contact\Index; use Magento\Framework\App\Request\DataPersistorInterface; use Magento\Framework\App\ObjectManager; class Post extends \Magento\Contact\Controller\Index\Post { private $dataPersistor; public function execute() { $post = $this->getRequest()->getPostValue(); if (!$post) { $this->_redirect('*/*/'); return; } $this->inlineTranslation->suspend(); try { $postObject = new \Magento\Framework\DataObject(); $postObject->setData($post); $error = false; if (!\Zend_Validate::is(trim($post['name']), 'NotEmpty')) { $error = true; } if (!\Zend_Validate::is(trim($post['comment']), 'NotEmpty')) { $error = true; } if (!\Zend_Validate::is(trim($post['email']), 'EmailAddress')) { $error = true; } if (\Zend_Validate::is(trim($post['hideit']), 'NotEmpty')) { $error = true; } if ($error) { throw new \Exception(); } $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; $transport = $this->_transportBuilder ->setTemplateIdentifier($this->scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE, $storeScope)) ->setTemplateOptions( [ 'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE, 'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, ] ) ->setTemplateVars(['data' => $postObject]) ->setFrom($this->scopeConfig->getValue(self::XML_PATH_EMAIL_SENDER, $storeScope)) ->addTo($this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope)) ->setReplyTo($post['email']) ->getTransport(); $transport->sendMessage(); $this->inlineTranslation->resume(); $message = __('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.'); $this->getDataPersistor()->clear('contact_us'); echo $message; //$this->_redirect('contact/index'); return; } catch (\Exception $e) { $this->inlineTranslation->resume(); $message = __('We can\'t process your request right now. Sorry, that\'s all we know.'); $this->getDataPersistor()->set('contact_us', $post); //$this->_redirect('contact/index'); echo $message; return; } } private function getDataPersistor() { if ($this->dataPersistor === null) { $this->dataPersistor = ObjectManager::getInstance() ->get(DataPersistorInterface::class); } return $this->dataPersistor; } }
Instead of redirecting to contact us page, we are printing success message and error message In line no 67 and 77. These messages are displayed at frontside in an ajax success call.
Run below command and check the contact us form by submitting it. On successful request, you will get the success message like below image.
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
php bin/magento cache:clean
That’s It. We are done with submitting contact us form using an ajax call.
In the next article, we will see How to render an HTML using an Ajax call in Magento 2 Module.
If you liked this post, then please like us on Facebook and follow us on Twitter.
Leave a Comment
(6 Comments)
Hi, I am using Magento 2.3. I am getting an error”undefined properties _transportBuilder”.
Which Magento version are you using? Have you run setup upgrade command?
which is not working. I am getting 404 Not Found error
Not working.
What error are you getting? Please mentioned in the comment so others can help you to figure out your problem.
not working propare
Useful Magento 2 Articles
Author Info
Chirag
Connect With MeWas this post helpful? Please support Us!
To Avoid Spam Downloads, We Want Your Email
away. Please submit form below.
Magento 2
Knowledge
to your Inbox