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.
2 Answers
You should try below Extension:
https://github.com/php-cuong/magento2-ajax-newsletter-subscription/tree/master
-
-
Maybe you know how to prevent scrolling to the top, after the user input incorrect text in the email field? Commented 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 Commented Feb 6 at 6:06
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;"> </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.
-
Maybe you know how to prevent scrolling to the top, after the user input incorrect text in the email field? Commented Feb 5 at 11:40