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.

magento_2_ajax_call_screenshot

 

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

(0 Comments)

All the comments are goes into moderation before approval. Please do not spam. Your email address will not be published. Required fields are marked *

Enjoy this post? Please support Us!

Like our social page for daily new updates….


Want to become
a Magento 2 Expert?

If Yes! Then Subscribe to our newsletter and get weekly article to you email id.
Subscribe Here
SUBSCRIBE NOW
close-link

To Avoid Spam Downloads, We Want Your Email

We will send you download link right
away. Please submit form below.
SEND ME DOWNLOAD LINK
Close