Magento 2 : Add to compare and add to wishlist with ajax
I have added Ajax add to wishlist functionality on product page following below method:
Added custom "Add to wishlist" button to following file inside <?php if ($block->isWishListAllowed()) : ?>
condition
app/design/frontend/Vendor/Module/Magento_Wishlist/templates/catalog/product/view/addto/wishlist.phtml
<button name="add-to-wishlist" onclick="addProductToWishlist()"> Add to Wishlist</button>
<?php $productId = json_decode($block->getWishlistParams(), true)['data']['product']; ?>
It calls addProductToWishlist()
javascript function which I have added in the same wishlist.phtml file
<script>
function addProductToWishlist() {
require(["jquery"], function($){
$.ajax({
url: '<?php echo $this->getUrl('general/index/addtowishlist') ?>',
method: 'get',
data: { productId: <?php echo $productId ?>},
dataType: 'json',
showLoader:true,
success: function(data){
var redirect = data.result.redirect;
if(redirect) {
window.location.href = '<?php echo $this->getUrl('customer/account/login') ?>';
} else {
// show successfully added message
}
}
});
});
}
Here is my controller code which has logic of adding product to wishlist.
app/code/Vendor/Module/Controller/Index/Addtowishlist.php
<?php
namespace Vendor\General\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
class Addtowishlist extends Action {
protected $customerSession;
protected $wishlistRepository;
protected $productRepository;
public function __construct(
Context $context,
\Magento\Customer\Model\Session $customerSession,
\Magento\Wishlist\Model\WishlistFactory $wishlistRepository,
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
ResultFactory $resultFactory,
\Magento\Framework\Controller\Result\JsonFactory $jsonFactory
) {
$this->customerSession = $customerSession;
$this->wishlistRepository= $wishlistRepository;
$this->productRepository = $productRepository;
$this->resultFactory = $resultFactory;
$this->jsonFactory = $jsonFactory;
parent::__construct($context);
}
public function execute() {
$customerId = $this->customerSession->getCustomer()->getId();
if(!$customerId) {
$jsonData = ['result' => ['status' => 200, 'redirect' => 1,'message' => 'Customer not logged in.']];
$result = $this->jsonFactory->create()->setData($jsonData);
return $result;
}
$productId = $this->getRequest()->getParam('productId');
try {
$product = $this->productRepository->getById($productId);
} catch (NoSuchEntityException $e) {
$product = null;
}
$wishlist = $this->wishlistRepository->create()->loadByCustomerId($customerId, true);
$wishlist->addNewItem($product);
$wishlist->save();
$jsonData = ['result' => ['status' => 200, 'redirect' => 0, 'message' => 'Added to wishlist']];
$result = $this->jsonFactory->create()->setData($jsonData);
return $result;
}
}
Above code works fine on product page. Similar way you can add Ajax add to wishlist functionality on listing page.
Note:
Above code needs some improvement like validating form_key
in controller file.
I've managed to come up with a fairly simple solution for AJAX Wishlist functionality:
1) Use the following helper method which returns JSON-encoded parameters:
$this->helper("Magento\Wishlist\Helper\Data")->getAddParams($product)
This returns something like the following:
{
"action": "https://www.mywebsite.com/wishlist/index/add/",
"data": {
"product": "1",
"uenc": "a0bLy9tMhZGlhLWVsZXljbGFya2oZWxY29tL25i5hc3RsZW1lbnRzLXNUusLmhHR0cHM6Ww,"
}
}
2) Include the form key in your data when making a POST request, similar to the following:
var url = "https://www.mywebsite.com/wishlist/index/add/";
var data = {
action : "add-to-wishlist",
form_key : "xyC5IcaqeNg2um6g",
product : "1",
uenc : "a0bLy9tMhZGlhLWVsZXljbGFya2oZWxY29tL25i5hc3RsZW1lbnRzLXNUusLmhHR0cHM6Ww,"
}
$.post(url, data);
The item should now be in your wishlist.
Note: the form key can be obtained either via JavaScript by getting the value of a cookie called form_key
or through Magento's getFormKey()
function.
Edit: there are a couple of drawbacks when using this method:
- There's no
success
callback from the POST request. - Once you add an item, you'll see a message on the next page you visit saying "[item] has been added to your Wish List. Click here to continue shopping."
So although this works, it's far from a robust solution.