2

I am using magento 2.1.5, and i am trying to make ajax newslatter.

di.xml

<type name="Magento\Newsletter\Controller\Subscriber\NewAction">
    <plugin name="Newsletter_Subscriber_NewAction"
            type="Namespace\Module\Controller\Plugin\Subscriber\NewAction" sortOrder="10" disabled="false" />
</type>

created new file inside controller as route:

app/code/Namespace/Module/Controller/Plugin/Subscriber/NewAction.php

<?php
/**
 *
 */
  namespace Namespace\Module\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;

 /**
* Class NewAction
  */
 class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
/**
 * @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
) {
    $this->customerAccountManagement = $customerAccountManagement;
    $this->resultJsonFactory = $resultJsonFactory;
    parent::__construct(
        $context,
        $subscriberFactory,
        $customerSession,
        $storeManager,
        $customerUrl,
        $customerAccountManagement
    );
}

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

}

over write the subscribe.phtml file in my theme file

<div class="block-subscribe">

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

        <div class="input-box">
            <div class="input-left">
                <i class="fa fa-envelope"></i>                    
                <input class="input-text" name="email" type="email" id="newsletter"
                            placeholder="<?php /* @escapeNotVerified */ echo __('Enter your email address') ?>"
                            data-validate="{required:true, 'validate-email':true}"/>
            </div>

            <button class="button action subscribe primary" title="<?php /* @escapeNotVerified */ echo __('Subscribe') ?>" type="submit">
                <span><span><?php /* @escapeNotVerified */ echo __('Subscribe') ?></span></span>
            </button>
        </div>
</form>

  <script>

  {
    "*": {
        "js/newsletter_subscriber_ajax": { }
    }
}
 </script>

and then create js/newsletter_subscriber_ajax at

app/design/frontend/NAMESPACE/MY_CUSTOM_THEME/web/js/newsletter_subscriber_ajax.js

require.config({
deps: [
    'jquery'
],
callback: function ($) {
    var form = $('form.subscribe');

    form.submit(function(e) {
        if(form.validation('isValid')){
            var email = $("#newsletter").val();
            var url = form.attr('action');
            var loadingMessage = $('#loading-message');

            if(loadingMessage.length == 0) {
                form.find('.control').append('<div id="loading-message" style="display:none;padding-top:10px;">&nbsp;</div>');
                var loadingMessage = $('#loading-message');
            }

            e.preventDefault();
            try{
                loadingMessage.html('Submitting...').show();
                $.ajax({
                    url: url,
                    dataType: 'json',
                    type: 'POST',
                    data: {email: email},
                    success: function (data){
                        if(data.status != "ERROR"){
                            $('#newsletter').val('');
                        }
                        loadingMessage.html(data.msg);
                    },
                    complete: function(){
                        setTimeout(function(){
                            loadingMessage.hide();
                        },5000);
                    }
                });
            } catch (e){
                loadingMessage.html(e.message);
            }
        }
        return false;
    });
}
 })

its return the result fine in json formate. but js is not working. is there any error with js???

2

add jquery code in your subscribe.phtml file like this:

<script>
  require(['jquery'],function($){
  var form = $('#newsletter-validate-detail');
  form.submit(function(e) {
    if(form.validation('isValid')){
            var email = $("#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();
                $.ajax({
                    url: url,
                    dataType: 'json',
                    type: 'POST',
                    data: {email: email},
                    success: function (data){
                        if(data.status != "ERROR"){
                            $('#newsletter').val('');
                        }
                        loadingMessage.html(data.msg);
                    },
                });
            } catch (e){
                loadingMessage.html(e.message);
            }
        }
    });
  })
</script>
  • I am always getting error Something went wrong with the subscription. But subscriptions are adding in database. Please give me some solution. – Magecode Oct 26 '17 at 11:24
0

Another easy way to do it without creating a custom module, just overriding the Magento newsletter into your theme

app/design/frontend/[Vendor]/[theme]/Magento_Newsletter/Controller/Subscriber/NewAction.php

namespace Magento\Newsletter\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;

/**
 * Class NewAction
*/
class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
/**
 * @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
) {
    $this->customerAccountManagement = $customerAccountManagement;
    $this->resultJsonFactory = $resultJsonFactory;
    parent::__construct(
        $context,
        $subscriberFactory,
        $customerSession,
        $storeManager,
        $customerUrl,
        $customerAccountManagement
    );
}

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

the JS file

<script>
 require(['jquery'],function($){
 var form = $('#newsletter-validate-detail');
 form.submit(function(e) {
   if(form.validation('isValid')){
        var email = $("#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();
            debugger;
            $.ajax({
                url: url,
                dataType: 'json',
                type: 'POST',
                data: {email: email},
                success: function (data){
                    if(data.status != "ERROR"){
                        $('#newsletter').val('');
                    }
                    loadingMessage.html(data.msg);
                },
            });
        } catch (e){
            loadingMessage.html(e.message);
        }
    }
});
})
 </script>
0

Need to modify the following files:

  1. app/code/Namespace/Module/Controller/Plugin/Subscriber/NewAction.php

namespace Namespace\Module\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;

class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{

protected $customerAccountManagement;

protected $resultJsonFactory;

public function __construct(
    Context $context,
    SubscriberFactory $subscriberFactory,
    Session $customerSession,
    StoreManagerInterface $storeManager,
    CustomerUrl $customerUrl,
    CustomerAccountManagement $customerAccountManagement,
    \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
) {
    $this->customerAccountManagement = $customerAccountManagement;
    $this->resultJsonFactory = $resultJsonFactory;
    $this->subscriberFactory = $subscriberFactory;
    parent::__construct(
        $context,
        $subscriberFactory,
        $customerSession,
        $storeManager,
        $customerUrl,
        $customerAccountManagement
    );
}

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

            $subscriber = $this->subscriberFactory->create()->loadByEmail($email);            
            if ($subscriber->getId()
                && $subscriber->getSubscriberStatus() == \Magento\Newsletter\Model\Subscriber::STATUS_SUBSCRIBED
            ) {
                $response = [
                    'status' => 'ERROR',
                    'msg' => __('This email address is already subscribed.'),
                ];
                return $this->resultJsonFactory->create()->setData($response);
            }

            $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. %1',$e->getMessage()),
            ];
        }
    }

    return $this->resultJsonFactory->create()->setData($response);
  }
}
  1. JS Code and HTML Changes

    require(['jquery'],function($){ var form = $('#newsletter-validate-detail'); form.submit(function(e) { if(form.validation('isValid')){ var email = $("#footer_newsletter").val(); var url = form.attr('action'); var loadingMessage = $('#loading-message');
                if(loadingMessage.length == 0) {            
                    var loadingMessage = $('#loading-message');
                }
    
                e.preventDefault();
                try{
                    loadingMessage.html('Submitting...').show();            
                    $.ajax({
                        url: url,
                        dataType: 'json',
                        type: 'POST',
                        data: {email: email},
                        success: function (data){
                            if(data.status != "ERROR"){
                                $('#footer_newsletter').val('');
                            }
                            loadingMessage.html(data.msg);
                        },
                    });
                } catch (e){
                    loadingMessage.html(e.message);
                }
            }
        });
    })        
    

add following code after form :

<div class="message">
   <span id="loading-message"></span>
</div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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