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