Magento 2.4 newsletter using ajax, Customers subscribe to the newsletter in your store for any reason, they will get message near to newsletter.
Steps to AJAX Newsletter in Magento 2:
1 Create di.xml at MyVendor/MyModule/etc folder
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Newsletter\Controller\Subscriber\NewAction">
<plugin name="custom_Subscriber_NewAction"
type="MyVendor\MyModule\Plugin\Controller\Subscriber\NewAction" sortOrder="10" disabled="false" />
</type>
</config>
2. Create NewAction.php at MyVendor/MyModule/Plugin/Controller/Subscriber folder
<?php
namespace MyVendor\MyModule\Plugin\Controller\Subscriber;
use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Url as CustomerUrl;
use Magento\Framework\App\Action\Context;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Newsletter\Model\Subscriber;
use Magento\Newsletter\Model\SubscriberFactory;
use Magento\Newsletter\Model\SubscriptionManagerInterface;
use Magento\Framework\Validator\EmailAddress as EmailValidator;
/**
* Class NewAction
*/
class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
/**
* @var CustomerAccountManagement
*/
protected $customerAccountManagement;
protected $resultJsonFactory;
private $emailValidator;
/**
* @var SubscriptionManagerInterface
*/
private $subscriptionManager;
/**
* Initialize dependencies.
*
* @param Context $context
* @param SubscriberFactory $subscriberFactory
* @param Session $customerSession
* @param StoreManagerInterface $storeManager
* @param CustomerUrl $customerUrl
* @param CustomerAccountManagement $customerAccountManagement
* @param SubscriptionManagerInterface $subscriptionManager
* @param EmailValidator $emailValidator
*/
public function __construct(
Context $context,
SubscriberFactory $subscriberFactory,
Session $customerSession,
StoreManagerInterface $storeManager,
CustomerUrl $customerUrl,
CustomerAccountManagement $customerAccountManagement,
SubscriptionManagerInterface $subscriptionManager,
EmailValidator $emailValidator = null,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
)
{
$this->customerAccountManagement = $customerAccountManagement;
$this->resultJsonFactory = $resultJsonFactory;
parent::__construct(
$context,
$subscriberFactory,
$customerSession,
$storeManager,
$customerUrl,
$customerAccountManagement,
$subscriptionManager,
$emailValidator
);
}
/**
* Retrieve available Order fields list
*
* @return array
*/
public function aroundExecute($subject, $procede)
{
$response = [];
if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
$email = (string)$this->getRequest()->getPost('email');
try {
$this->validateEmailFormat($email);
$this->validateGuestSubscription();
$this->validateEmailAvailable($email);
$websiteId = (int)$this->_storeManager->getStore()->getWebsiteId();
$subscriber = $this->_subscriberFactory->create()->loadBySubscriberEmail($email, $websiteId);
if ($subscriber->getId()
&& (int)$subscriber->getSubscriberStatus() === Subscriber::STATUS_SUBSCRIBED) {
$response = [
'status' => 'OK',
'msg' => 'This email address is already subscribed.',
];
return $this->resultJsonFactory->create()->setData($response);
}
$status = $this->_subscriberFactory->create()->subscribe($email);
if ($status == Subscriber::STATUS_NOT_ACTIVE) {
$response = [
'status' => 'OK',
'msg' => 'The confirmation request has been sent.',
];
}else {
$response = [
'status' => 'OK',
'msg' => 'Thank you for your subscription.',
];
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$response = [
'status' => 'ERROR',
'msg' => __('There was a problem with the subscription: %1', $e->getMessage()),
];
} catch (\Exception $e) {
$response = [
'status' => 'ERROR',
'msg' => __('Something went wrong with the subscription.'),
];
}
}
return $this->resultJsonFactory->create()->setData($response);
}
}
3 In your newsletter.phtml file, add below code.
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/** @var \Magento\Newsletter\Block\Subscribe $block */
?>
<div class="block newsletter">
<h3><?= $block->escapeHtml(__('Newsletter')) ?></h3>
<p><?= $block->escapeHtml(__('Join our mailing list for latest news and exclusive offers')) ?></p>
<div class="content">
<form class="form subscribe" novalidate action="<?= $block->escapeUrl($block->getFormActionUrl()) ?>" method="post" data-mage-init='{"validation": {"errorClass": "mage-error"}}' id="newsletter-validate-detail">
<div class="field newsletter">
<div class="control">
<label for="newsletter">
<span class="label">
<?= $block->escapeHtml(__('Sign Up for Our Newsletter:')) ?>
</span>
<input name="email" type="email" id="newsletter"
placeholder="<?= $block->escapeHtml(__('Email address')) ?>"
data-mage-init='{"mage/trim-input":{}}'
data-validate="{required:true, 'validate-email':true}"
/>
</label>
</div>
</div>
<div class="actions">
<button class="action subscribe primary" title="<?= $block->escapeHtmlAttr(__('Subscribe')) ?>" type="submit" aria-label="Subscribe">
<span><?= $block->escapeHtml(__('Subscribe email')) ?></span>
</button>
</div>
<div id="loading-message" style="display:none;padding-top:10px;color: white;font-size: 13px;font-weight: 500;"> </div>
<div class="scg-msg">
<div class="messages">
</div>
</div>
</form>
</div>
</div>
<script type="text/x-magento-init">
{
"*": {
"Magento_Customer/js/block-submit-on-send": {
"formId": "newsletter-validate-detail"
}
}
}
</script>
<script>
require(['jquery'],function($){
var form = $('#newsletter-validate-detail');
form.submit(function(e) {
if(form.validation('isValid')){
var email = $("#newsletter-validate-detail #newsletter").val();
var url = form.attr('action');
var loadingMessage = $('#loading-message');
e.preventDefault();
try{
loadingMessage.html('Submitting...').show();
$('.scg-msg > messages').html();
$.ajax({
url: url,
dataType: 'json',
type: 'POST',
data: {email: email},
success: function (data){
if(data.status != "ERROR"){
$("#newsletter-validate-detail #newsletter").val('');
loadingMessage.css('color','green');
}else{
loadingMessage.css('color','red');
}
loadingMessage.html(data.msg);
setTimeout(function () {
loadingMessage.hide();
$("#newsletter-validate-detail .action.subscribe.primary").removeAttr('disabled');
$("#newsletter-validate-detail .action.subscribe.primary").prop("disabled", false);
}, 5000)
},
});
} catch (e){
loadingMessage.css('color','red');
loadingMessage.html('Something went worng!');
setTimeout(function () {
loadingMessage.hide();
$("#newsletter-validate-detail .action.subscribe.primary").removeAttr('disabled');
$("#newsletter-validate-detail .action.subscribe.primary").prop("disabled", false);
}, 5000)
}
}
});
})
</script>
Using the above steps and you will get functional Ajax Newsletter in Magento 2
Feel free to mention them in the comments section below.
Related Post : Get Block Attribute Value In Phtml