Magento 2 wishlist – list of products that a customer can share with anyone. Another purpose is to keep products you want to buy at a later date. By default it has some limitations and theme developer often need to customize it.
- Following samples was tested on magento 2.3.0
- You need to update Vendor/Module in filenames and code to correct values
- Number of items in wishlist sidebar
- “Add to wishlist” without redirecting to wishlist page
- Remove “items” text in wishlist top links
- Work with wishlist items in javascript
Number of items in Magento 2 wishlist sidebar
By default you can see 3 last added wishlist items in sidebar. This number is hardcoded in Magento\Wishlist\CustomerData\Wishlist
class. There is no corresponding option in admin panel. To override it we will use dependency injection functionality.
– add following line in module di.xml
to tell magento to use our class instead of standard one.
Filename: Vendor/Module/etc/frontend/di.xml
– create the class. We override only getItems function, which is used to get wishlist items. If you want to limit wishlist collection, you need to use setPageSize function.
Filename: Vendor/Module/CustomerData/Wishlist.php
<?php namespace Vendor\Module\CustomerData; class Wishlist extends \Magento\Wishlist\CustomerData\Wishlist { /** * Get wishlist items * * @return array */ protected function getItems() { $this->view->loadLayout(); $collection = $this->wishlistHelper->getWishlistItemCollection(); //show all wishlist items $collection->clear()->setInStockFilter(true)->setOrder('added_at'); //show 5 wishlist items //$collection->clear()->setPageSize(5)->setInStockFilter(true)->setOrder('added_at'); $items = []; foreach ($collection as $wishlistItem) { $items[] = $this->getItemData($wishlistItem); } return $items; } }
“Add to wishlist” without redirecting to wishlist page
When you click “Add to Wishlist” button, it redirect you wishlist page. To fix it we need to override Magento\Wishlist\Controller\Index\Add
controller.
– add following line in module di.xml
to tell magento to use our class instead of standard one.
Filename: Vendor/Module/etc/frontend/di.xml
– create the class. Basically it duplicate original method, only $resultRedirect
updated to use referer url
Filename: Vendor/Module/Controller/Index/Add.php
<?php namespace Vendor\Module\Controller\Index; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\App\Action; use Magento\Framework\Data\Form\FormKey\Validator; use Magento\Framework\Exception\NotFoundException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Controller\ResultFactory; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Add extends \Magento\Wishlist\Controller\Index\Add { /** * Adding new item * * @return \Magento\Framework\Controller\Result\Redirect * @throws NotFoundException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function execute() { /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); if (!$this->formKeyValidator->validate($this->getRequest())) { return $resultRedirect->setPath('*/'); } $wishlist = $this->wishlistProvider->getWishlist(); if (!$wishlist) { throw new NotFoundException(__('Page not found.')); } $session = $this->_customerSession; $requestParams = $this->getRequest()->getParams(); if ($session->getBeforeWishlistRequest()) { $requestParams = $session->getBeforeWishlistRequest(); $session->unsBeforeWishlistRequest(); } $productId = isset($requestParams['product']) ? (int)$requestParams['product'] : null; if (!$productId) { $resultRedirect->setPath('*/'); return $resultRedirect; } try { $product = $this->productRepository->getById($productId); } catch (NoSuchEntityException $e) { $product = null; } if (!$product || !$product->isVisibleInCatalog()) { $this->messageManager->addErrorMessage(__('We can\'t specify a product.')); $resultRedirect->setPath('*/'); return $resultRedirect; } try { $buyRequest = new \Magento\Framework\DataObject($requestParams); $result = $wishlist->addNewItem($product, $buyRequest); if (is_string($result)) { throw new \Magento\Framework\Exception\LocalizedException(__($result)); } if ($wishlist->isObjectNew()) { $wishlist->save(); } $this->_eventManager->dispatch( 'wishlist_add_product', ['wishlist' => $wishlist, 'product' => $product, 'item' => $result] ); $referer = $session->getBeforeWishlistUrl(); if ($referer) { $session->setBeforeWishlistUrl(null); } else { $referer = $this->_redirect->getRefererUrl(); } $this->_objectManager->get(\Magento\Wishlist\Helper\Data::class)->calculate(); $this->messageManager->addComplexSuccessMessage( 'addProductSuccessMessage', [ 'product_name' => $product->getName(), 'referer' => $referer ] ); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addErrorMessage( __('We can\'t add the item to Wish List right now: %1.', $e->getMessage()) ); } catch (\Exception $e) { $this->messageManager->addExceptionMessage( $e, __('We can\'t add the item to Wish List right now.') ); } $resultRedirect->setUrl($this->_redirect->getRefererUrl()); return $resultRedirect; } }
Remove “items” text in wishlist top links
It can be done in several ways.
– you can use translation file. Like app/design/frontend/Magento/luma/i18n/en_US.csv
"%1 items","%1",module,Magento_Wishlist
– you can override createCounter function in Vendor/Module/CustomerData/Wishlist.php
/** * Create button label based on wishlist item quantity * * @param int $count * @return \Magento\Framework\Phrase|null */ protected function createCounter($count) { return $count; }
– you can update link template ( by default it is view/frontend/templates/link.phtml
) and change
to
Work with wishlist items in javascript
You might want to get wishlist items array in frontend. For example, to mark products that already in customer’s wishlist. It can be done with help of customer-data
object. customer-data
updated via ajax, so it might not have the wishlist information at the initialization. Luckily customer data use knockout observable functionality, so we can subscribe to data update event.
Sample below use wishlist items array to add “selected” class to wishlist button. You can use it to decorate button.
– create wishlist_items.js
Filename: Vendor/Module/view/frontend/web/js/wishlist_items.js
define([ 'jquery', 'uiComponent', 'Magento_Customer/js/customer-data', 'domReady' ], function ($, Component, customerData) { 'use strict'; return Component.extend({ /** @inheritdoc */ initialize: function () { var _this = this; this._super(); this.wishlist = customerData.get('wishlist'); this.wishlist.subscribe(function(newValue) { _this.decorateItems(); }); _this.decorateItems(); }, decorateItems: function() { var items = this.wishlist().items; if (typeof items === 'undefined' || !items.length) return; $('a.action.towishlist').each(function(){ var data = $(this).data('post'), i; for (i = 0; i < items.length; i++) { if (data.data.product === items[i].product_id) { $(this).addClass('selected'); } } }); } }); });
– add initialization code to your wishlist template
<script type="text/x-magento-init"> { "*": { "Magento_Ui/js/core/app": { "components": { "wishlistItems": { "component": "Vendor_Module/js/wishlist_items" } } } } } </script>
Hello I want to make an Ajax add to wishlist Functionality in Magento 2
i am trying to use data-action attribute for that
i searcher in js/add-to-wishlist there are two fuction OnBindSubmit and __Update where action add to wish list is observed and posted to certain url according to paramters i am trying to interupt product on click at add-to-wishlist how can i do this please Guide me thank you
Ajax functionality is out of this article scope. Try to check StackOverflow for code samples. Like https://magento.stackexchange.com/questions/102781/magento-2-add-to-compare-and-add-to-wishlist-with-ajax
Hello,
Can you provide us a demo how it works.
Thank you
Hi
Unfortunately there is no demo available. It is pretty easy to recreate the code on your own installation.
Hello,
can you tell me please what to put into the
app/code/mymodule/wishlist folder?
I now have
etc/
routes.xml & di.xml
controller/Index
Add.php
routes.xml:
di.xml
But it isnt working.
Do I have to copy all of the magento_wishlist folder contents?
Thanks!
Article assume that you already has a module. It should contain basic module files.
– registration.php
– /etc/module.xml
Hi, I am looking for a solution regarding the display price range for the wishlist configurable items.
Can you help me with this
https://magento.stackexchange.com/questions/310131/magento2-display-configurable-product-price-range-on-wishlist-page
Thanks
Nagaraju
Hi
Will take a look, but no promises