0

I have subscription block before my footer links and after successful subscription the message appears on the top of main part, but I want to show it below subscription input.Of course there should be also different loading, cause now all page refreshes after success input.

enter image description here

2 Answers 2

1

You should try below Extension:

https://github.com/php-cuong/magento2-ajax-newsletter-subscription/tree/master

3
  • Thank you for the tutorial! Feb 2 at 13:33
  • Maybe you know how to prevent scrolling to the top, after the user input incorrect text in the email field? Feb 5 at 11:40
  • Using changes on js file you can fulfill your requirement otherwise move the class using move tag on xml file Feb 6 at 6:06
0

You can implement the below code process to make it ajax based and can make required changes as per your requirements.

Create di.xml at [Namespace][ModuleName]\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_Newsletter_Subscriber_Action" type="[Namespace]\[ModuleName]\Controller\Plugin\Subscriber\NewAction" sortOrder="11" disabled="false" />
    </type>
</config>

Create NewAction.php at [Namespace][ModuleName]\Controller\Plugin\Subscriber folder:

<?php

namespace [Namespace]\[ModuleName]\Controller\Plugin\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\SubscriberFactory;
use Magento\Newsletter\Model\SubscriptionManagerInterface;
use Magento\Framework\Validator\EmailAddress as EmailValidator;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\App\ObjectManager;

/**
 * Class NewAction
 */
class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
    /**
     * @var EmailValidator
     */
    private $emailValidator;

    /**
     * @var SubscriptionManagerInterface
     */
    private $subscriptionManager;

    /**
     * @var CustomerRepositoryInterface
     */
    private $customerRepository;

    /**
     * @var CustomerAccountManagement
     */
    protected $customerAccountManagement;

    protected $resultJsonFactory;

    /**
     * Initialize dependencies.
     *
     * @param Context $context
     * @param SubscriberFactory $subscriberFactory
     * @param Session $customerSession
     * @param StoreManagerInterface $storeManager
     * @param CustomerUrl $customerUrl
     * @param CustomerAccountManagement $customerAccountManagement
     */
    public function __construct(
        Context $context,
        SubscriberFactory $subscriberFactory,
        Session $customerSession,
        StoreManagerInterface $storeManager,
        CustomerUrl $customerUrl,
        CustomerAccountManagement $customerAccountManagement,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        SubscriptionManagerInterface $subscriptionManager,
        EmailValidator $emailValidator = null,
        CustomerRepositoryInterface $customerRepository = null
    ) {
        $this->subscriptionManager = $subscriptionManager;
        $this->emailValidator = $emailValidator ?: ObjectManager::getInstance()->get(EmailValidator::class);
        $this->customerRepository = $customerRepository ?: ObjectManager::getInstance()
            ->get(CustomerRepositoryInterface::class);
        $this->customerAccountManagement = $customerAccountManagement;
        $this->resultJsonFactory = $resultJsonFactory;
        parent::__construct(
            $context,
            $subscriberFactory,
            $customerSession,
            $storeManager,
            $customerUrl,
            $customerAccountManagement,
            $subscriptionManager,
            $emailValidator,
            $customerRepository
        );
    }

    /**
     * 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);

                $status = $this->_subscriberFactory->create()->subscribe($email);
                if ($status == \Magento\Newsletter\Model\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);
    }
}

Create subscribe.phtml file into your theme: eg: app\design\frontend\Theme\child\Magento_Newsletter\templates\subscribe.phtml

<div class="block newsletter">
    <div class="title"><strong>Newsletter </strong></div>
    <div class="content">
        <form class="form subscribe" novalidate action="<?php /* @escapeNotVerified */ echo $block->getFormActionUrl() ?>" method="post" data-mage-init='{"validation": {"errorClass": "mage-error"}}' id="newsletter-validate-detail">

            <div class="field newsletter">
                <label class="label" for="newsletter"><span><?php /* @escapeNotVerified */ echo __('Sign Up for Our Newsletter:') ?></span></label>
                <div class="control">
                    <input name="email" type="email" id="newsletter" placeholder="<?php /* @escapeNotVerified */ echo __('Enter your email address') ?>" data-validate="{required:true, 'validate-email':true}" />
                </div>
            </div>
            <div class="actions">
                <button class="action subscribe primary" title="<?php /* @escapeNotVerified */ echo __('Subscribe sad') ?>" type="submit">
                    <span><?php /* @escapeNotVerified */ echo __('Subscribe') ?></span>
                </button>
            </div>
            <div class="scg-msg">
                <div class="messages">
                </div>
            </div>
        </form>
    </div>
</div>


<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');

                if (loadingMessage.length == 0) {
                    form.find('.input-group').append('<div id="loading-message" style="display:none;padding-top:10px;color: red;font-size: 13px;">&nbsp;</div>');
                    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('');
                                $('#newsletter-validate-detail .scg-msg > .messages').html('<div class="message-success success message" ><div >' +
                                    data.msg + '</div></div>');
                            } else {
                                $('#newsletter-validate-detail .scg-msg > .messages').html('<div class="message-error error message" >' +
                                    '<div>' + data.msg + '</div></div>');
                            }
                            loadingMessage.html(data.msg);
                        },
                    });
                } catch (e) {
                    loadingMessage.html(e.message);
                }
            }
        });
    })
</script>

Just follow the mentioned steps & your newsletter will work as per your requirements.

1
  • Maybe you know how to prevent scrolling to the top, after the user input incorrect text in the email field? Feb 5 at 11:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.