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>
The post Magento 2: Working with Wishlist appeared first on NWDthemes.com.