├── .github └── no-response.yml ├── .travis.yml ├── CHANGELOG ├── Controller └── Search │ └── Result │ └── Index.php ├── Helper └── Data.php ├── LICENSE ├── Plugin └── Controller │ └── Category │ └── View.php ├── README.md ├── USER-GUIDE.md ├── UserGuide.pdf ├── composer.json ├── etc ├── acl.xml ├── adminhtml │ └── system.xml ├── config.xml ├── frontend │ └── di.xml └── module.xml ├── i18n └── en_US.csv ├── registration.php ├── travis.yml └── view └── frontend ├── layout ├── catalog_category_view_type_layered.xml ├── catalogsearch_result_index.xml ├── hyva_catalog_category_view.xml ├── hyva_catalog_category_view_type_layered.xml ├── hyva_catalog_list_item.xml └── hyva_catalogsearch_result_index.xml ├── requirejs-config.js ├── templates ├── hyva │ ├── layer │ │ ├── filter.phtml │ │ ├── state.phtml │ │ └── view.phtml │ ├── product │ │ └── list │ │ │ ├── js │ │ │ ├── compare.phtml │ │ │ └── wishlist.phtml │ │ │ └── toolbar.phtml │ └── ui │ │ └── loading.phtml ├── layer.phtml ├── layer │ └── view.phtml └── products.phtml └── web ├── css ├── hyva │ └── view.css └── source │ └── _module.less └── js ├── action └── submit-filter.js ├── model └── loader.js └── view └── layer.js /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-no-response - https://github.com/probot/no-response 2 | 3 | # Number of days of inactivity before an Issue is closed for lack of response 4 | daysUntilClose: 7 5 | # Label requiring a response 6 | responseRequiredLabel: waiting-customer-response 7 | # Comment to post when closing an Issue for lack of response. Set to `false` to disable 8 | closeComment: > 9 | This issue has been automatically closed because there has been no response 10 | to our request for more information from the original author. With only the 11 | information that is currently in the issue, we don't have enough information 12 | to take action. Please reach out if you have or find the answers we need so 13 | that we can investigate further. -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 7.0 4 | - 7.1 5 | sudo: required 6 | dist: trusty 7 | env: 8 | global: 9 | - COMPOSER_BIN_DIR=~/bin 10 | - INTEGRATION_SETS=3 11 | - NODE_JS_VERSION=6 12 | - MAGENTO_HOST_NAME="magento2.travis" 13 | - COMPOSER_MODULE=mageplaza/module-ajax-layered-navigation 14 | matrix: 15 | - MAGENTO_VERSION=2.2.1 TEST_SUITE=integration INTEGRATION_INDEX=1 16 | - MAGENTO_VERSION=2.2.1 TEST_SUITE=integration INTEGRATION_INDEX=2 17 | - MAGENTO_VERSION=2.2.1 TEST_SUITE=integration INTEGRATION_INDEX=3 18 | - MAGENTO_VERSION=2.2.2 TEST_SUITE=static 19 | - MAGENTO_VERSION=2.2.2 TEST_SUITE=js GRUNT_COMMAND=static 20 | - MAGENTO_VERSION=2.2.2 TEST_SUITE=integration INTEGRATION_INDEX=1 21 | - MAGENTO_VERSION=2.2.2 TEST_SUITE=integration INTEGRATION_INDEX=2 22 | - MAGENTO_VERSION=2.2.2 TEST_SUITE=integration INTEGRATION_INDEX=3 23 | - MAGENTO_VERSION=2.2.5 TEST_SUITE=integration INTEGRATION_INDEX=1 24 | - MAGENTO_VERSION=2.2.5 TEST_SUITE=integration INTEGRATION_INDEX=2 25 | - MAGENTO_VERSION=2.2.5 TEST_SUITE=integration INTEGRATION_INDEX=3 26 | - MAGENTO_VERSION=2.2.6 TEST_SUITE=integration INTEGRATION_INDEX=1 27 | - MAGENTO_VERSION=2.2.6 TEST_SUITE=integration INTEGRATION_INDEX=2 28 | - MAGENTO_VERSION=2.2.6 TEST_SUITE=integration INTEGRATION_INDEX=3 29 | 30 | matrix: 31 | exclude: 32 | - php: 7.0 33 | env: MAGENTO_VERSION=2.2.2 TEST_SUITE=js GRUNT_COMMAND=static 34 | - php: 7.0 35 | env: MAGENTO_VERSION=2.2.2 TEST_SUITE=static 36 | cache: 37 | apt: true 38 | directories: 39 | - "$HOME/.composer/cache" 40 | - "$HOME/.nvm" 41 | addons: 42 | apt: 43 | packages: 44 | - mysql-server-5.6 45 | - mysql-client-core-5.6 46 | - mysql-client-5.6 47 | - postfix 48 | firefox: '46.0' 49 | hosts: 50 | - magento2.travis 51 | before_install: 52 | - git clone https://github.com/magento/magento2 --branch $MAGENTO_VERSION 53 | - cd magento2 54 | - bash ./dev/travis/before_install.sh 55 | install: 56 | - composer install --no-interaction --prefer-dist 57 | - composer require $COMPOSER_MODULE 58 | before_script: 59 | #- cp -f ${TRAVIS_BUILD_DIR}/dev/tests/integration/phpunit.xml.dist dev/tests/integration/ 60 | - echo "vendor/$COMPOSER_MODULE" > dev/tests/static/testsuite/Magento/Test/Less/_files/whitelist/common.txt 61 | - echo "vendor/$COMPOSER_MODULE" > dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt 62 | - echo "vendor/$COMPOSER_MODULE/**/*.js" > dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt 63 | - bash ./dev/travis/before_script.sh 64 | script: 65 | - test $TEST_SUITE = "static" && TEST_FILTER='--filter "Magento\\Test\\Php\\LiveCodeTest"' || true 66 | - test $TEST_SUITE = "functional" && TEST_FILTER='dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php' || true 67 | 68 | 69 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | CHANGELOG: https://www.mageplaza.com/releases/ajax-layered-navigation -------------------------------------------------------------------------------- /Controller/Search/Result/Index.php: -------------------------------------------------------------------------------- 1 | _storeManager = $storeManager; 106 | $this->_catalogSession = $catalogSession; 107 | $this->_queryFactory = $queryFactory; 108 | $this->layerResolver = $layerResolver; 109 | $this->_jsonHelper = $jsonHelper; 110 | $this->_moduleHelper = $moduleHelper; 111 | $this->_helper = $helper; 112 | 113 | parent::__construct($context); 114 | } 115 | 116 | /** 117 | * @return ResponseInterface|ResultInterface|void 118 | * @throws LocalizedException 119 | */ 120 | public function execute() 121 | { 122 | $this->layerResolver->create(Resolver::CATALOG_LAYER_SEARCH); 123 | /* @var $query Query */ 124 | $query = $this->_queryFactory->get(); 125 | 126 | $query->setStoreId($this->_storeManager->getStore()->getId()); 127 | 128 | if ($query->getQueryText() !== '') { 129 | if ($this->_helper->isMinQueryLength()) { 130 | $query->setId(0)->setIsActive(1)->setIsProcessed(1); 131 | } else { 132 | $query->saveIncrementalPopularity(); 133 | if ($query->getRedirect()) { 134 | $this->getResponse()->setRedirect($query->getRedirect()); 135 | 136 | return; 137 | } 138 | } 139 | 140 | $this->_helper->checkNotes(); 141 | $this->_view->loadLayout(); 142 | 143 | if ($this->_moduleHelper->ajaxEnabled() && $this->getRequest()->isAjax()) { 144 | $navigation = $this->_view->getLayout()->getBlock('catalogsearch.leftnav'); 145 | $products = $this->_view->getLayout()->getBlock('search.result'); 146 | $result = [ 147 | 'products' => $products->toHtml(), 148 | 'navigation' => $navigation->toHtml() 149 | ]; 150 | $this->getResponse()->representJson($this->_jsonHelper->jsonEncode($result)); 151 | } else { 152 | $this->_view->renderLayout(); 153 | } 154 | } else { 155 | $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl()); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Helper/Data.php: -------------------------------------------------------------------------------- 1 | getConfigGeneral('ajax_enable', $storeId) && $this->isModuleOutputEnabled(); 45 | } 46 | 47 | /** 48 | * @param $filters 49 | * 50 | * @return mixed 51 | */ 52 | public function getLayerConfiguration($filters) 53 | { 54 | $params = $this->_getRequest()->getParams(); 55 | $filterParams = []; 56 | foreach ($params as $key => $param) { 57 | if ($key === 'amp;dimbaar') { 58 | continue; 59 | } 60 | $filterParams[htmlentities($key)] = htmlentities($param); 61 | } 62 | $config = new DataObject([ 63 | 'active' => array_keys($filterParams), 64 | 'params' => $filterParams, 65 | 'isCustomerLoggedIn' => $this->objectManager->create(Session::class)->isLoggedIn() 66 | ]); 67 | 68 | return self::jsonEncode($config->getData()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2016-present Mageplaza Co. Ltd. 2 | 3 | This License is entered by Mageplaza to govern the usage or redistribution of Mageplaza software. This is a legal agreement between you (either an individual or a single entity) and Mageplaza for Mageplaza software product(s) which may include extensions, templates and services. 4 | 5 | By purchasing, installing, or otherwise using Mageplaza products, you acknowledge that you have read this License and agree to be bound by the terms of this Agreement. If you do not agree to the terms of this License, do not install or use Mageplaza products. 6 | 7 | The Agreement becomes effective at the moment when you acquire software from our site or receive it through email or on data medium or by any other means. Mageplaza reserves the right to make reasonable changes to the terms of this license agreement and impose its clauses at any given time. 8 | 9 | 1. GRANT OF LICENSE: By purchasing a product of Mageplaza: 10 | 11 | 1. Customer will receive source code open 100%. 12 | 13 | 2. Customer will obtain a License Certificate which will remain valid until the Customer stops using the Product or until Mageplaza terminates this License because of Customer’s failure to comply with any of its Terms and Conditions. Each License Certificate includes a license serial which is valid for one live Magento installation only and unlimited test Magento installations. 14 | 15 | 3. You are allowed to customize our products to fit with your using purpose. 16 | 17 | 4. DESCRIPTION OF OTHER RIGHTS AND LIMITATIONS 18 | 19 | 5. Installation and Use 20 | 21 | 6. For each new Software installation, you are obliged to purchase a separate License. You are not permitted to use any part of the code in whole or part in any other software or product or website. You are legally bound to preserve the copyright information intact including the text/link at bottom. 22 | 23 | 2. Distribution: You are not allowed to distribute Mageplaza software to third parties. Any distribution without our permission, including non commercial distribution is considered as violation of this Agreement and entails liability, according to the current law. You may not place the Software onto a server that allows access to the Software via a public network or the Internet for distribution purposes. 24 | 25 | 3. Rental: You may not give, sell, sub-license, rent, lease or lend any portion of the Software to anyone. 26 | 27 | 4. Compliance with Applicable Laws: You must comply with all applicable laws regarding use of software products. Mageplaza software and a portion of it are protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. Accordingly, customer is required to treat the software like any other copyrighted material. Any activity violating copyright law will be prosecuted according to the current law. We retain the right to revoke the license of any user holding an invalid license. 28 | 29 | 5. TERMINATION: Without prejudice to any other rights, Mageplaza may terminate this License at any time if you fail to comply with the terms and conditions of this License. In such event, it constitutes a breach of the agreement, and your license to use the program is revoked and you must destroy all copies of Mageplaza products in your possession. After being notified of termination of your license, if you continue to use Mageplaza software, you hereby agree to accept an injunction to prevent you from its further use and to pay all costs (including but not limited to reasonable attorney fees) to enforce our revocation of your license and any damages suffered by us because of your misuse of the Software. We are not bound to return you the amount spent for purchase of the Software for the termination of this License. 30 | 31 | 6. LIMITATION OF LIABILITY: In no event shall Mageplaza be liable for any damages (including, without limitation, lost profits, business interruption, or lost information) rising out of ‘Authorized Users’ use of or inability to use the Mageplaza products, even if Mageplaza has been advised of the possibility of such damages. In no event will Mageplaza be liable for prosecution arising from use of the Software against law or for any illegal use. 32 | 33 | The latest License: https://www.mageplaza.com/LICENSE.txt -------------------------------------------------------------------------------- /Plugin/Controller/Category/View.php: -------------------------------------------------------------------------------- 1 | moduleManager = $moduleManager; 48 | $this->_moduleHelper = $moduleHelper; 49 | } 50 | 51 | /** 52 | * @param \Magento\Catalog\Controller\Category\View $action 53 | * @param $page 54 | * 55 | * @return mixed 56 | */ 57 | public function afterExecute(\Magento\Catalog\Controller\Category\View $action, $page) 58 | { 59 | if ($this->_moduleHelper->ajaxEnabled() && $action->getRequest()->isAjax()) { 60 | $navigation = $page->getLayout()->getBlock('catalog.leftnav'); 61 | $products = $page->getLayout()->getBlock('category.products'); 62 | $result = ['products' => $products->toHtml(), 'navigation' => $navigation->toHtml()]; 63 | if ($this->_moduleHelper->getConfigValue('mpquickview/general/enabled')) { 64 | $quickView = $page->getLayout()->getBlock('mpquickview.quickview'); 65 | $result['quickview'] = $quickView->toHtml(); 66 | } 67 | $action->getResponse()->representJson(LayerData::jsonEncode($result)); 68 | } else { 69 | return $page; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The #1 Magento 2 Ajax Layered Navigation FREE 2 | 3 | Product filtering is one of the most used features which every customer craves on your online store. To clarify, product filtering is an application that buyers select one or multiple product attributes to search for specific products which match their needs. 4 | 5 | On an online store which there is no existence of shopping assistants, customers need nothing but an effective product filtering/searching tool. It would seem strange if your Magento 2 store had no **Layered Navigation** because other e-commerce websites, today, are even trying to enhance their filtering systems to optimize UX on their platforms. 6 | 7 | To boost filtering experience for buyers, [Ajax Layered Navigation extension for Magento 2](https://www.mageplaza.com/magento-2-ajax-layered-navigation/) allows filtered products to appear immediately after every single filtering action. Hence, there is no seem-to-be-painfully-long waiting time between each filter, and customers will be more likely to enjoy their time shopping on your store. 8 | 9 | 10 | ## 1. Documentation 11 | 12 | - [Landing Page](https://github.com/mageplaza/magento-2-ajax-layered-navigation) 13 | - [Installation guide](https://www.mageplaza.com/install-magento-2-extension/) 14 | - [User Guide](https://docs.mageplaza.com/ajax-layered-navigation/index.html) 15 | - [Get Support](https://github.com/mageplaza/magento-2-ajax-layered-navigation/issues) 16 | 17 | 18 | ## 2. FAQs 19 | 20 | - **Q: I got an error: Mageplaza_Core has been already defined** 21 | 22 | - A: Read solution: https://github.com/mageplaza/module-core/issues/3 23 | 24 | - **Q: Is Mageplaza Ajax Layered Navigation extension compatible with Layered Navigation for Magento 2?** 25 | 26 | - A: Yes! Ajax Layered Navigation extension is fully compatible with all packages of [Magento 2 Layered Navigation Ultimate](https://www.mageplaza.com/magento-2-layered-navigation-extension/). This compatibility helps enhance UX for shoppers at the highest level. 27 | 28 | 29 | ## 3. How to install Ajax Layered Navigation extension for Magento 2 30 | 31 | ### Install via composer (recommend) 32 | 33 | Run the following command in Magento 2 root folder: 34 | 35 | With Marketing Automation (recommend): 36 | ``` 37 | composer require mageplaza/module-ajax-layered-navigation mageplaza/module-smtp 38 | php bin/magento setup:upgrade 39 | php bin/magento setup:static-content:deploy 40 | ``` 41 | 42 | Without Marketing Automation: 43 | ``` 44 | composer require mageplaza/module-ajax-layered-navigation 45 | php bin/magento setup:upgrade 46 | php bin/magento setup:static-content:deploy 47 | ``` 48 | 49 | ## 4. Ajax Layered Navigation highlight features 50 | ### Enhance UX by Ajax Technology 51 | 52 | Visually, Ajax plays an amazing role in your store UX improvement because of many advantages. Ajax, according to [Sequetech](https://www.seguetech.com/ajax-technology/), is a method which helps to exchange and update only one or several parts of a web page without reloading the whole site. As a result, the page loading speed is cut down optimally, and this allows your online shoppers to avoid unnecessary waiting time. 53 | 54 | **Ajax Layered Navigation** is also an answer to the question “How to keep your clients on your store when the internet connection sucks”. They will no longer need to wait for all the data to be loaded before performing any of other actions on the page. 55 | 56 | As **Ajax Layered Navigation** enables pages to prevent performing a full postback, filtering products are more responsive, faster and way more user-friendly. This is how shopping experience is boosted. 57 | 58 | ### Lightening-fast Ajax Navigation 59 | 60 | Filtered products are loaded and displayed nearly immediately after a single filtering performance without waiting for other parts of the page to be reloaded. This allows the important content, which includes products, product images, and other product info, to show up first, and to be ready for buyers to perform further actions. 61 | 62 | **Ajax Layered Navigation** saves a bunch of time for customers. Buyers do not even have to hit any button to start loading filtering results because they are automatically loaded after every single filtering act. 63 | 64 | ### Ajax Add to Wishlist 65 | 66 | **Magento 2 Ajax Layered Navigation extension** allows logged-in customers add products to their wishlist, yet still stay on the page without being redirected to the wishlist page. 67 | 68 | ### Compatible with Layered Navigation 69 | 70 | **Mageplaza Ajax Layered Navigation extension** is fully compatible with all packages of **Magento 2 Layered Navigation Ultimate**. This feature implemented to **Mageplaza Layered Navigation module** is a perfect solution to boost shopping experience to the highest level. 71 | 72 | Even when shopper performs multi-filtering, Ajax Layered still supports to display results nicely, smoothly and lightening-fast. 73 | 74 | ## 5. Ajax Layered Navigation User Guide 75 | 76 | **Ajax Layered Navigation** features are added to filters and page blocks, which assists users to select each attribute from filters and various categories without reloading the entire page. As a result, it will enhance the user experience, reduce response and server uploading time. This is the new feature of **Magento 2 Ajax Layered Navigation** which fully compatible with **Layered Navigation Ultimate**. 77 | 78 | The Ajax Layered Navigation tutorial of Mageplaza below will provide detailed instruction on how to use for user interface and how to configure on the admin backend. 79 | 80 | 81 | ### How to Config Magento 2 Ajax Layered Navigation 82 | 83 | From the admin panel, make your way to ``Mageplaza > Layered Navigation > Configuration`` 84 | 85 | ![How to Config M2 Ajax Layered Navigation](https://i.imgur.com/lKM4Yiz.png) 86 | 87 | ![Magento 2 2 Ajax Layered Navigation configuration](https://i.imgur.com/Opo6NTd.png) 88 | 89 | ![Magento 2 layered navigation Free](https://i.imgur.com/8d0Jd3F.gif) 90 | 91 | Besides, Ajax Layered supports the functions of Add to wishlist by Ajax for logged-in customers. 92 | After clicking on Add to wishlist icon on Category Page, customers can continue viewing other products without being navigated to Wishlist Page. 93 | 94 | ![ajax layered navigation 2](https://i.imgur.com/8J10AWl.gif) 95 | 96 | 97 | **People Also Search:** 98 | - magento 2 layered navigation 99 | - magento 2 layered navigation free 100 | - magento 2 layered navigation extension 101 | - magento 2 layered navigation extension free 102 | - ajax layered navigation magento 2 103 | - magento 2 ajax filter 104 | - magento 2 navigation extension 105 | - magento 2 layer navigation 106 | - magento 2 horizontal layered navigation 107 | - magento 2 price slider layered navigation 108 | - magento 2 ajax loader 109 | 110 | 111 | **Other free extension on Github** 112 | - [Magento 2 Sitemap](https://github.com/mageplaza/magento-2-google-xml-sitemap) 113 | - [Magento 2 Twitter Widget](https://github.com/mageplaza/magento-2-twitter-widget) 114 | - [Magento 2 Reindex from backend](https://github.com/mageplaza/magento-2-backend-reindex) 115 | - [Magento 2 Social Share](https://github.com/mageplaza/magento-2-social-share) 116 | - [Magento 2 Multiple Flat Rates Shipping](https://github.com/mageplaza/magento-2-multi-flat-rates) 117 | - [Magento 2 Same Order Number](https://github.com/mageplaza/magento-2-same-order-number) 118 | - [Magento 2 Share Cart](https://github.com/mageplaza/magento-2-share-cart) 119 | - [Magento 2 GeoIP](https://github.com/mageplaza/magento-2-geoip) 120 | 121 | 122 | **Explore more [Magento 2 extensions on Marketplace](https://marketplace.magento.com/partner/Mageplaza):** 123 | - [Magento 2 Layered Navigation](https://marketplace.magento.com/mageplaza-layered-navigation-m2.html) 124 | - [Magento 2 One Step Checkout](https://marketplace.magento.com/mageplaza-magento-2-one-step-checkout-extension.html) 125 | - [Magento 2 PDF invoice](https://marketplace.magento.com/mageplaza-module-pdf-invoice.html) 126 | - [Magento 2 Automatic Related Products](https://marketplace.magento.com/mageplaza-module-automatic-related-products.html) 127 | - [Magento 2 All in one](https://marketplace.magento.com/mageplaza-magento-2-seo-extension.html) 128 | - [Magento 2 Gift Card](https://marketplace.magento.com/mageplaza-module-gift-card.html) 129 | - [Magento 2 Reward Points extension](https://marketplace.magento.com/mageplaza-module-reward-points.html) 130 | - [Magento 2 Affiliate Program](https://marketplace.magento.com/mageplaza-module-affiliate.html) 131 | - [Magento 2 Product Feed](https://marketplace.magento.com/mageplaza-module-product-feed.html) 132 | - [Magento 2 Mass Product Actions](https://marketplace.magento.com/mageplaza-module-mass-product-actions.html) 133 | - [Magento 2 Custom Stock Status](https://marketplace.magento.com/mageplaza-module-custom-stock-status.html) 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /USER-GUIDE.md: -------------------------------------------------------------------------------- 1 | ## Documentation 2 | 3 | - Installation guide: https://www.mageplaza.com/install-magento-2-extension/#solution-1-ready-to-paste 4 | - User Guide: https://docs.mageplaza.com/ajax-layered-navigation/index.html 5 | - Product page: https://www.mageplaza.com/magento-2-ajax-layered-navigation/ 6 | - FAQs: https://www.mageplaza.com/faqs/ 7 | - Get Support: https://www.mageplaza.com/contact.html or support@mageplaza.com 8 | - Changelog: https://www.mageplaza.com/releases/ajax-layered-navigation 9 | - License agreement: https://www.mageplaza.com/LICENSE.txt 10 | 11 | ## How to install 12 | 13 | ### Install ready-to-paste package (Recommended) 14 | 15 | - Installation guide: https://www.mageplaza.com/install-magento-2-extension/ 16 | 17 | ## How to upgrade 18 | 19 | 1. Backup 20 | 21 | Backup your Magento code, database before upgrading. 22 | 23 | 2. Remove AjaxLayer folder 24 | 25 | In case of customization, you should backup the customized files and modify in newer version. 26 | Now you remove `app/code/Mageplaza/AjaxLayer` folder. In this step, you can copy override AjaxLayer folder but this may cause of compilation issue. That why you should remove it. 27 | 28 | 3. Upload new version 29 | Upload this package to Magento root directory 30 | 31 | 4. Run command line: 32 | 33 | ``` 34 | php bin/magento setup:upgrade 35 | php bin/magento setup:static-content:deploy 36 | ``` 37 | 38 | 39 | ## FAQs 40 | 41 | 42 | #### Q: I got error: `Mageplaza_Core has been already defined` 43 | A: Read solution: https://github.com/mageplaza/module-core/issues/3 44 | 45 | 46 | #### Q: My site is down 47 | A: Please follow this guide: https://www.mageplaza.com/blog/magento-site-down.html 48 | 49 | 50 | ## Support 51 | 52 | - FAQs: https://www.mageplaza.com/faqs/ 53 | - https://mageplaza.freshdesk.com/ 54 | - support@mageplaza.com 55 | -------------------------------------------------------------------------------- /UserGuide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mageplaza/magento-2-ajax-layered-navigation/37780e1df51c4ae3f48e21b584bbaca69d7400ff/UserGuide.pdf -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mageplaza/module-ajax-layered-navigation", 3 | "description": "Magento 2 Ajax Layered Navigation Extension", 4 | "require": { 5 | "mageplaza/module-core": "^1.5.13" 6 | }, 7 | "type": "magento2-module", 8 | "version": "4.1.4", 9 | "license": "proprietary", 10 | "authors": [ 11 | { 12 | "name": "Mageplaza", 13 | "email": "support@mageplaza.com", 14 | "homepage": "https://www.mageplaza.com", 15 | "role": "Technical Support" 16 | } 17 | ], 18 | "autoload": { 19 | "files": [ 20 | "registration.php" 21 | ], 22 | "psr-4": { 23 | "Mageplaza\\AjaxLayer\\": "" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /etc/acl.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /etc/adminhtml/system.xml: -------------------------------------------------------------------------------- 1 | 22 | 23 | 24 |
25 | separator-top 26 | 27 | mageplaza 28 | Mageplaza_LayeredNavigation::configuration 29 | 30 | 31 | 32 | Mageplaza\Core\Block\Adminhtml\System\Config\Head 33 | 35 |
  • User Guide
  • 36 |
  • Ask Community
  • 37 |
  • Ask Mageplaza
  • 38 | 39 | ]]>
    40 |
    41 | 42 | 43 | Magento\Config\Model\Config\Source\Yesno 44 | 45 |
    46 |
    47 |
    48 |
    49 | -------------------------------------------------------------------------------- /etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | magento/ajax-layered-navigation 28 | 29 | 30 | 1 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /etc/frontend/di.xml: -------------------------------------------------------------------------------- 1 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /i18n/en_US.csv: -------------------------------------------------------------------------------- 1 | "%1 filter options","%1 filter options" 2 | "%1 filter, 1 available product","%1 filter, 1 available product" 3 | "%1 filter, %2 available products","%1 filter, %2 available products" 4 | "Active filtering","Active filtering" 5 | "Remove active %1 filter: %2","Remove active %1 filter: %2" 6 | "Clear All","Clear All" 7 | "Product filters","Product filters" 8 | "Shop By","Shop By" 9 | "Skip to product list","Skip to product list" 10 | filter,filter 11 | "Could not add item to wishlist.","Could not add item to wishlist." 12 | "%1 has been added to your Wish List.","%1 has been added to your Wish List." 13 | "Shopping Options","Shopping Options" 14 | "Ajax Layered Navigation","Ajax Layered Navigation" 15 | "General Configuration","General Configuration" 16 | Enable,Enable 17 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | dev/tests/static/testsuite/Magento/Test/Less/_files/whitelist/common.txt 56 | - echo "vendor/$COMPOSER_MODULE" > dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt 57 | - echo "vendor/$COMPOSER_MODULE/**/*.js" > dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt 58 | - bash ./dev/travis/before_script.sh 59 | script: 60 | - test $TEST_SUITE = "static" && TEST_FILTER='--filter "Magento\\Test\\Php\\LiveCodeTest"' || true 61 | - test $TEST_SUITE = "functional" && TEST_FILTER='dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php' || true 62 | - if [ $TEST_SUITE == "functional" ]; then dev/tests/functional/vendor/phpunit/phpunit/phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi 63 | - if [ $TEST_SUITE != "functional" ] && [ $TEST_SUITE != "js" ]; then phpunit -c dev/tests/$TEST_SUITE $TEST_FILTER; fi 64 | - if [ $TEST_SUITE == "js" ]; then grunt $GRUNT_COMMAND; fi 65 | 66 | -------------------------------------------------------------------------------- /view/frontend/layout/catalog_category_view_type_layered.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | Mageplaza_AjaxLayer::layer/view.phtml 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /view/frontend/layout/catalogsearch_result_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | Mageplaza_AjaxLayer::layer/view.phtml 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /view/frontend/layout/hyva_catalog_category_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | Mageplaza_AjaxLayer::hyva/product/list/toolbar.phtml 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /view/frontend/layout/hyva_catalog_category_view_type_layered.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Mageplaza_AjaxLayer::css/hyva/view.css 34 | 35 | 36 | 37 | 38 | 39 | Mageplaza_AjaxLayer::hyva/layer/view.phtml 40 | 41 | 42 | 43 | 44 | 45 | Mageplaza_AjaxLayer::hyva/layer/filter.phtml 46 | 47 | 48 | 49 | 50 | 51 | Mageplaza_AjaxLayer::hyva/layer/state.phtml 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /view/frontend/layout/hyva_catalog_list_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | Mageplaza_AjaxLayer::hyva/product/list/js/compare.phtml 28 | 29 | 30 | 31 | 32 | Mageplaza_AjaxLayer::hyva/product/list/js/wishlist.phtml 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /view/frontend/layout/hyva_catalogsearch_result_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Mageplaza_AjaxLayer::css/hyva/view.css 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Mageplaza_AjaxLayer::hyva/product/list/toolbar.phtml 42 | 43 | 44 | 45 | 46 | Mageplaza_AjaxLayer::hyva/layer/view.phtml 47 | 48 | 49 | 50 | 51 | 52 | Mageplaza_AjaxLayer::hyva/layer/filter.phtml 53 | 54 | 55 | 56 | 57 | 58 | Mageplaza_AjaxLayer::hyva/layer/state.phtml 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /view/frontend/requirejs-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Mageplaza 3 | * 4 | * NOTICE OF LICENSE 5 | * 6 | * This source file is subject to the Mageplaza.com license that is 7 | * available through the world-wide-web at this URL: 8 | * https://www.mageplaza.com/LICENSE.txt 9 | * 10 | * DISCLAIMER 11 | * 12 | * Do not edit or add to this file if you wish to upgrade this extension to newer 13 | * version in the future. 14 | * 15 | * @category Mageplaza 16 | * @package Mageplaza_AjaxLayer 17 | * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/) 18 | * @license https://www.mageplaza.com/LICENSE.txt 19 | */ 20 | 21 | var config = { 22 | paths: { 23 | mpAjax: 'Mageplaza_AjaxLayer/js/view/layer' 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/layer/filter.phtml: -------------------------------------------------------------------------------- 1 | helper(Data::class); 32 | 33 | /** @var array $filterItems */ 34 | ?> 35 | 36 |
      37 | 38 |
    1. 39 | getCount() > 0): ?> 40 | getCount() === 1): ?> 43 | aria-label="escapeHtmlAttr(__('%1 filter, 1 available product', 44 | $filterItem->getLabel())) ?>" 45 | 46 | aria-label="escapeHtmlAttr(__('%1 filter, %2 available products', 47 | $filterItem->getLabel(), $filterItem->getCount())) ?>" 48 | 49 | 50 | > 51 | getLabel() ?> 53 | shouldDisplayProductCountOnLayer()): ?> 54 | (formatNumber((int) $filterItem->getCount()) ?>) 56 | 57 | 58 | 59 | 60 | getLabel() ?> 62 | shouldDisplayProductCountOnLayer()): ?> 63 | (formatNumber((int) $filterItem->getCount()) ?>) 65 | 66 | 67 | 68 |
    2. 69 | 70 |
    71 | 72 | 77 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/layer/state.phtml: -------------------------------------------------------------------------------- 1 | require(HeroiconsOutline::class); 32 | ?> 33 | getActiveFilters() ?> 34 | 35 |
    39 |

    40 | 62 |

    63 |
    70 | 71 | getName(); 73 | $filterLabel = $block->stripTags($filter->getLabel()); 74 | ?> 75 |
    76 | 77 | escapeHtml(__($filterName)) ?> 78 | 79 | escapeHtml($filterLabel) ?> 80 | 81 | 82 | 83 | 87 | trashHtml('', 20, 20, ["aria-hidden" => "true"]); ?> 88 | 89 | 90 |
    91 | 92 |
    93 | getLayer()->getState()->getFilters()): ?> 94 |
    95 | escapeHtml(__('Clear All')) ?> 97 |
    98 | 99 |
    100 | 101 | 105 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/layer/view.phtml: -------------------------------------------------------------------------------- 1 | require(\Hyva\Theme\ViewModel\HeroiconsOutline::class); 29 | ?> 30 | canShowBlock()): ?> 31 |
    40 | getBlockHtml('mplayer_loader') ?> 41 |

    45 | 73 |

    74 |
    79 | getChildHtml('state') ?> 80 | 84 | escapeHtml(__('Skip to product list')) ?> 85 | 86 | getFilters() as $filter): ?> 87 | getItemsCount()): ?> 88 |
    92 |

    93 | 118 |

    119 | 129 |
    130 | 131 | 132 |
    133 |
    134 | 206 | 207 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/product/list/js/compare.phtml: -------------------------------------------------------------------------------- 1 | require(ProductCompare::class); 29 | ?> 30 | showInProductList()): ?> 31 | 77 | 78 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/product/list/js/wishlist.phtml: -------------------------------------------------------------------------------- 1 | require(Wishlist::class); 29 | ?> 30 | isEnabled()): ?> 31 | helper(\Mageplaza\AjaxLayer\Helper\Data::class); 33 | $filters = $block->getFilters(); 34 | $layerConfig = $helper->getLayerConfiguration($filters); 35 | ?> 36 | 112 | 113 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/product/list/toolbar.phtml: -------------------------------------------------------------------------------- 1 | 'p']; 29 | ?> 30 | 138 | getCollection()->getSize()): ?> 139 |
    143 | getBlockHtml('mplayer_loader') ?> 144 | getIsBottom()): ?> 145 | fetchView($block->getTemplateFile('Magento_Catalog::product/list/toolbar/amount.phtml')) ?> 147 | getPagerHtml() ?> 148 | fetchView($block->getTemplateFile('Magento_Catalog::product/list/toolbar/limiter.phtml')) ?> 150 | 151 | isExpanded()): ?> 152 | fetchView($block->getTemplateFile('Magento_Catalog::product/list/toolbar/viewmode.phtml')) ?> 154 | fetchView($block->getTemplateFile('Magento_Catalog::product/list/toolbar/sorter.phtml')) ?> 156 | 157 | 158 |
    159 | 160 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/ui/loading.phtml: -------------------------------------------------------------------------------- 1 | require(SvgIcons::class); 29 | ?> 30 |
    40 | loaderHtml('text-primary', 57, 57); ?> 41 |
    42 | escapeHtml(__('Loading...')) ?> 43 |
    44 |
    45 | -------------------------------------------------------------------------------- /view/frontend/templates/layer.phtml: -------------------------------------------------------------------------------- 1 | 22 | 23 |
    24 | getChildHtml() ?> 25 |
    26 | 27 | -------------------------------------------------------------------------------- /view/frontend/templates/layer/view.phtml: -------------------------------------------------------------------------------- 1 | 22 | canShowBlock()) : ?> 23 | helper(\Mageplaza\AjaxLayer\Helper\Data::class); 25 | $filters = $block->getFilters(); 26 | $layerConfig = $helper->getLayerConfiguration($filters); 27 | $filtered = count($block->getLayer()->getState()->getFilters()); 28 | ?> 29 |
    31 |
    32 |
    33 | Loading... 34 |
    35 |
    36 |
    37 | 38 |
    39 |
    40 | getChildHtml('state') ?> 41 | getLayer()->getState()->getFilters()) : ?> 42 |
    43 | 44 | 45 | 46 |
    47 | 48 | 49 | $filter) : ?> 50 | getItemsCount()) : ?> 51 | 52 | 53 | 54 | 55 |
    56 | 58 |
    60 |
    getName()) ?>
    61 |
    62 | getChildBlock('renderer')->setFilter($filter)->render($filter); ?> 63 |
    64 |
    65 | 66 | 67 | 68 |
    69 | 70 | 77 | 78 | ajaxEnabled()) : ?> 79 | 86 | 87 |
    88 |
    89 | 90 | -------------------------------------------------------------------------------- /view/frontend/templates/products.phtml: -------------------------------------------------------------------------------- 1 | 22 | 23 |
    24 | getChildHtml() ?> 25 |
    26 | -------------------------------------------------------------------------------- /view/frontend/web/css/hyva/view.css: -------------------------------------------------------------------------------- 1 | .ln_overlay { 2 | background-color: #FFFFFF; 3 | height: 100vh; 4 | text-align: center; 5 | opacity: 0.5; 6 | filter: alpha(opacity=50); 7 | position: fixed; 8 | cursor: wait; 9 | width: 100vw; 10 | z-index: 555; 11 | display: none; 12 | top: 0; 13 | left: 0; 14 | } 15 | 16 | .ln_overlay img { 17 | margin-top: 300px; 18 | left: 45%; 19 | display: block; 20 | position: fixed; 21 | } 22 | 23 | .ln_slider_container { 24 | width: calc(100% - 20px); 25 | margin: 0 15px 0 5px; 26 | } 27 | 28 | .filter-options-content a { 29 | display: inline-block !important; 30 | } -------------------------------------------------------------------------------- /view/frontend/web/css/source/_module.less: -------------------------------------------------------------------------------- 1 | /** 2 | * Mageplaza 3 | * 4 | * NOTICE OF LICENSE 5 | * 6 | * This source file is subject to the Mageplaza.com license that is 7 | * available through the world-wide-web at this URL: 8 | * https://www.mageplaza.com/LICENSE.txt 9 | * 10 | * DISCLAIMER 11 | * 12 | * Do not edit or add to this file if you wish to upgrade this extension to newer 13 | * version in the future. 14 | * 15 | * @category Mageplaza 16 | * @package Mageplaza_AjaxLayer 17 | * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/) 18 | * @license https://www.mageplaza.com/LICENSE.txt 19 | */ 20 | 21 | .ln_overlay { 22 | background-color: #FFFFFF; 23 | height: 300%; 24 | left: 0; 25 | text-align: center; 26 | opacity: 0.5; 27 | filter: alpha(opacity=50); 28 | position: absolute; 29 | top: 0px; 30 | width: 500%; 31 | z-index: 555; 32 | display: none; 33 | } 34 | 35 | .ln_overlay img { 36 | margin-top: 300px; 37 | left: 45%; 38 | display: block; 39 | position: fixed; 40 | } 41 | 42 | .ln_slider_container { 43 | width: calc(100% - 20px); 44 | margin: 0 15px 0 5px; 45 | } 46 | 47 | .filter-options-content a { 48 | display: inline-block !important; 49 | } -------------------------------------------------------------------------------- /view/frontend/web/js/action/submit-filter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Mageplaza 3 | * 4 | * NOTICE OF LICENSE 5 | * 6 | * This source file is subject to the Mageplaza.com license that is 7 | * available through the world-wide-web at this URL: 8 | * https://www.mageplaza.com/LICENSE.txt 9 | * 10 | * DISCLAIMER 11 | * 12 | * Do not edit or add to this file if you wish to upgrade this extension to newer 13 | * version in the future. 14 | * 15 | * @category Mageplaza 16 | * @package Mageplaza_AjaxLayer 17 | * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/) 18 | * @license https://www.mageplaza.com/LICENSE.txt 19 | */ 20 | 21 | define( 22 | [ 23 | 'jquery', 24 | 'mage/storage', 25 | 'Mageplaza_AjaxLayer/js/model/loader', 26 | 'mage/apply/main', 27 | 'ko' 28 | ], 29 | function ($, storage, loader, mage, ko) { 30 | 'use strict'; 31 | 32 | var productContainer = $('#layer-product-list'), 33 | layerContainer = $('.layered-filter-block-container'), 34 | quickViewContainer = $('#mpquickview-popup'); 35 | 36 | return function (submitUrl, isChangeUrl, method) { 37 | /** save active state */ 38 | var actives = [], 39 | data; 40 | $('.filter-options-item').each(function (index) { 41 | if ($(this).hasClass('active')) { 42 | actives.push($(this).attr('attribute')); 43 | } 44 | }); 45 | window.layerActiveTabs = actives; 46 | 47 | /** start loader */ 48 | loader.startLoader(); 49 | 50 | /** change browser url */ 51 | if (typeof window.history.pushState === 'function' && (typeof isChangeUrl === 'undefined')) { 52 | window.history.pushState({url: submitUrl}, '', submitUrl); 53 | } 54 | if (method === 'post') {// For 'add to wishlist' & 'add to compare' event 55 | return storage.post(submitUrl).done( 56 | ).fail( 57 | function () { 58 | window.location.reload(); 59 | } 60 | ).always(function () { 61 | loader.stopLoader(); 62 | }); 63 | } 64 | 65 | return storage.get(submitUrl).done( 66 | function (response) { 67 | if (response.backUrl) { 68 | window.location = response.backUrl; 69 | return; 70 | } 71 | 72 | if (response.navigation) { 73 | layerContainer.html(response.navigation); 74 | } else { 75 | var layer = $(response).find(".layered-filter-block-container").html(); 76 | if (layer) { 77 | layerContainer.html(layer); 78 | } 79 | } 80 | 81 | if (response.products) { 82 | productContainer.html(response.products); 83 | } else { 84 | var products = $(response).find("#layer-product-list").html(); 85 | if (layer) { 86 | productContainer.html(products); 87 | } 88 | } 89 | 90 | if ($(response).length) { 91 | $(response).each(function (){ 92 | if ($(this)[0].name && $(this)[0].name === 'robots'){ 93 | $('head meta[name="robots"]').first().replaceWith($(this)); 94 | } 95 | }) 96 | } 97 | 98 | if (response.quickview) { 99 | quickViewContainer.html(response.quickview); 100 | } 101 | 102 | if (response.finder) { 103 | $('.mpproductfinder-block').html(response.finder); 104 | } 105 | 106 | ko.cleanNode(productContainer[0]); 107 | productContainer.applyBindings(); 108 | 109 | if (mage) { 110 | mage.apply(); 111 | } 112 | } 113 | ).fail( 114 | function () { 115 | window.location.reload(); 116 | } 117 | ).always( 118 | function () { 119 | 120 | var colorAttr = $('.filter-options .filter-options-item .color .swatch-option-link-layered .swatch-option'); 121 | 122 | colorAttr.each(function(){ 123 | var el = $(this), 124 | hex = el.attr('data-option-tooltip-value'); 125 | if(typeof hex != "undefined"){ 126 | if (hex.charAt(0) === '#') { 127 | hex = hex.substr(1); 128 | } 129 | if ((hex.length < 2) || (hex.length > 6)) { 130 | el.attr('style','background: '+el.attr('data-option-label')+';'); 131 | } 132 | var values = hex.split(''), 133 | r, 134 | g, 135 | b; 136 | 137 | if (hex.length === 2) { 138 | r = parseInt(values[0].toString() + values[1].toString(), 16); 139 | g = r; 140 | b = r; 141 | } else if (hex.length === 3) { 142 | r = parseInt(values[0].toString() + values[0].toString(), 16); 143 | g = parseInt(values[1].toString() + values[1].toString(), 16); 144 | b = parseInt(values[2].toString() + values[2].toString(), 16); 145 | } else if (hex.length === 6) { 146 | r = parseInt(values[0].toString() + values[1].toString(), 16); 147 | g = parseInt(values[2].toString() + values[3].toString(), 16); 148 | b = parseInt(values[4].toString() + values[5].toString(), 16); 149 | } else { 150 | el.attr('style','background: '+el.attr('data-option-label')+';'); 151 | } 152 | 153 | el.attr('style','background: center center no-repeat rgb('+[r, g, b]+');'); 154 | } 155 | 156 | }); 157 | 158 | //selected 159 | 160 | var filterCurrent = $('.layered-filter-block-container .filter-current .items .item .filter-value'); 161 | 162 | filterCurrent.each(function(){ 163 | var el = $(this), 164 | colorLabel = el.html(), 165 | colorAttr = $('.filter-options .filter-options-item .color .swatch-option-link-layered .swatch-option'); 166 | 167 | colorAttr.each(function(){ 168 | var elA = $(this); 169 | if(elA.attr('data-option-label') === colorLabel && !elA.hasClass('selected')){ 170 | elA.addClass('selected'); 171 | } 172 | }); 173 | }); 174 | 175 | loader.stopLoader(); 176 | } 177 | ); 178 | }; 179 | } 180 | ); 181 | -------------------------------------------------------------------------------- /view/frontend/web/js/model/loader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Mageplaza 3 | * 4 | * NOTICE OF LICENSE 5 | * 6 | * This source file is subject to the Mageplaza.com license that is 7 | * available through the world-wide-web at this URL: 8 | * https://www.mageplaza.com/LICENSE.txt 9 | * 10 | * DISCLAIMER 11 | * 12 | * Do not edit or add to this file if you wish to upgrade this extension to newer 13 | * version in the future. 14 | * 15 | * @category Mageplaza 16 | * @package Mageplaza_AjaxLayer 17 | * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/) 18 | * @license https://www.mageplaza.com/LICENSE.txt 19 | */ 20 | 21 | define(['jquery'], function ($) { 22 | 'use strict'; 23 | 24 | return { 25 | /** 26 | * Start full page loader action 27 | */ 28 | startLoader: function () { 29 | $('.ln_overlay').show(); 30 | }, 31 | 32 | /** 33 | * Stop full page loader action 34 | */ 35 | stopLoader: function () { 36 | $('.ln_overlay').hide(); 37 | $('.swatch-option-tooltip').hide(); 38 | } 39 | }; 40 | } 41 | ); 42 | -------------------------------------------------------------------------------- /view/frontend/web/js/view/layer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Mageplaza 3 | * 4 | * NOTICE OF LICENSE 5 | * 6 | * This source file is subject to the Mageplaza.com license that is 7 | * available through the world-wide-web at this URL: 8 | * https://www.mageplaza.com/LICENSE.txt 9 | * 10 | * DISCLAIMER 11 | * 12 | * Do not edit or add to this file if you wish to upgrade this extension to newer 13 | * version in the future. 14 | * 15 | * @category Mageplaza 16 | * @package Mageplaza_AjaxLayer 17 | * @copyright Copyright (c) Mageplaza (http://www.mageplaza.com/) 18 | * @license https://www.mageplaza.com/LICENSE.txt 19 | */ 20 | 21 | define([ 22 | 'jquery', 23 | 'Mageplaza_AjaxLayer/js/action/submit-filter', 24 | 'Magento_Catalog/js/price-utils', 25 | 'jquery-ui-modules/widget', 26 | 'accordion', 27 | 'productListToolbarForm' 28 | ], function ($, submitFilterAction, ultil) { 29 | "use strict"; 30 | 31 | $.widget('mageplaza.layer', $.mage.accordion, { 32 | options: { 33 | openedState: 'active', 34 | collapsible: true, 35 | multipleCollapsible: true, 36 | animate: 200, 37 | mobileShopbyElement: '#layered-filter-block .filter-title [data-role=title]', 38 | collapsibleElement: '[data-role=ln_collapsible]', 39 | header: '[data-role=ln_title]', 40 | content: '[data-role=ln_content]', 41 | isCustomerLoggedIn: false, 42 | params: [], 43 | active: [] 44 | }, 45 | 46 | _create: function () { 47 | this.initActiveItems(); 48 | 49 | this._super(); 50 | 51 | this.initProductListUrl(); 52 | this.initObserve(); 53 | this.initWishlistCompare(); 54 | }, 55 | 56 | initActiveItems: function () { 57 | var layerActives = this.options.active, 58 | actives = []; 59 | 60 | if (typeof window.layerActiveTabs !== 'undefined') { 61 | layerActives = window.layerActiveTabs; 62 | } 63 | if (layerActives.length) { 64 | this.element.find('.filter-options-item').each(function (index) { 65 | if (~$.inArray($(this).attr('attribute'), layerActives)) { 66 | actives.push(index); 67 | } 68 | }); 69 | } 70 | 71 | this.options.active = actives; 72 | 73 | return this; 74 | }, 75 | 76 | initProductListUrl: function () { 77 | var isProcessToolbar = false; 78 | $.mage.productListToolbarForm.prototype.changeUrl = function (paramName, paramValue, defaultValue) { 79 | if (isProcessToolbar) { 80 | return; 81 | } 82 | isProcessToolbar = true; 83 | 84 | var urlPaths = this.options.url.split('?'), 85 | baseUrl = urlPaths[0], 86 | urlParams = urlPaths[1] ? urlPaths[1].split('&') : [], 87 | paramData = {}, 88 | parameters; 89 | for (var i = 0; i < urlParams.length; i++) { 90 | parameters = urlParams[i].split('='); 91 | paramData[parameters[0]] = parameters[1] !== undefined 92 | ? window.decodeURIComponent(parameters[1].replace(/\+/g, '%20')) 93 | : ''; 94 | } 95 | paramData[paramName] = paramValue; 96 | if (paramValue === defaultValue) { 97 | delete paramData[paramName]; 98 | } 99 | paramData = $.param(paramData); 100 | submitFilterAction(baseUrl + (paramData.length ? '?' + paramData : '')); 101 | } 102 | }, 103 | 104 | initObserve: function () { 105 | var self = this; 106 | 107 | // fix browser back, forward button 108 | if (typeof window.history.replaceState === "function") { 109 | window.history.replaceState({url: document.URL}, document.title); 110 | 111 | setTimeout(function () { 112 | window.onpopstate = function (e) { 113 | if (e.state) { 114 | submitFilterAction(e.state.url, 1); 115 | } 116 | }; 117 | }, 0) 118 | } 119 | 120 | var pageElements = $('#layer-product-list').find('.pages a'); 121 | pageElements.each(function () { 122 | var el = $(this), 123 | link = self.checkUrl(el.prop('href')); 124 | if (!link) { 125 | return; 126 | } 127 | 128 | el.bind('click', function (e) { 129 | submitFilterAction(link); 130 | e.stopPropagation(); 131 | e.preventDefault(); 132 | }) 133 | }); 134 | 135 | var currentElements = this.element.find('.filter-current a, .filter-actions a'); 136 | currentElements.each(function (index) { 137 | var el = $(this), 138 | link = self.checkUrl(el.prop('href')); 139 | if (!link) { 140 | return; 141 | } 142 | 143 | el.bind('click', function (e) { 144 | submitFilterAction(link); 145 | e.stopPropagation(); 146 | e.preventDefault(); 147 | }); 148 | }); 149 | 150 | var optionElements = this.element.find('.filter-options a'); 151 | optionElements.each(function (index) { 152 | var el = $(this), 153 | link = self.checkUrl(el.prop('href')); 154 | if (!link) { 155 | return; 156 | } 157 | 158 | el.bind('click', function (e) { 159 | if (el.hasClass('swatch-option-link-layered')) { 160 | self.selectSwatchOption(el); 161 | } 162 | 163 | self.ajaxSubmit(link); 164 | e.stopPropagation(); 165 | e.preventDefault(); 166 | }); 167 | }); 168 | 169 | var swatchElements = this.element.find('.swatch-attribute'); 170 | swatchElements.each(function (index) { 171 | var el = $(this); 172 | var attCode = el.attr('attribute-code'); 173 | if (attCode) { 174 | if (self.options.params.hasOwnProperty(attCode)) { 175 | var attValues = self.options.params[attCode].split(","); 176 | var swatchOptions = el.find('.swatch-option'); 177 | swatchOptions.each(function (option) { 178 | var elOption = $(this); 179 | if ($.inArray(elOption.attr('option-id'), attValues) !== -1) { 180 | elOption.addClass('selected'); 181 | } 182 | }); 183 | } 184 | } 185 | }); 186 | }, 187 | 188 | selectSwatchOption: function (el) { 189 | var childEl = el.find('.swatch-option'); 190 | if (childEl.hasClass('selected')) { 191 | childEl.removeClass('selected'); 192 | } else { 193 | childEl.addClass('selected'); 194 | } 195 | }, 196 | 197 | ajaxSubmit: function (submitUrl) { 198 | this.element.find(this.options.mobileShopbyElement).trigger('click'); 199 | 200 | return submitFilterAction(submitUrl); 201 | }, 202 | 203 | checkUrl: function (url) { 204 | var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/; 205 | 206 | return regex.test(url) ? url : null; 207 | }, 208 | 209 | //Handling 'add to wishlist' & 'add to compare' event 210 | initWishlistCompare: function () { 211 | var isCustomerLoggedIn = this.options.isCustomerLoggedIn, 212 | elClass = 'a.action.tocompare' + (isCustomerLoggedIn ? ',a.action.towishlist' : ''); 213 | $(elClass).each(function () { 214 | var el = $(this); 215 | $(el).bind('click', function (e) { 216 | var dataPost = $(el).data('post'), 217 | formKey = $('input[name="form_key"]').val(), method = 'post'; 218 | if (formKey) { 219 | dataPost.data.form_key = formKey; 220 | } 221 | 222 | var paramData = $.param(dataPost.data), 223 | url = dataPost.action + (paramData.length ? '?' + paramData : ''); 224 | submitFilterAction(url, true, method); 225 | e.stopPropagation(); 226 | e.preventDefault(); 227 | }); 228 | }) 229 | } 230 | }); 231 | 232 | return $.mageplaza.layer; 233 | }); 234 | --------------------------------------------------------------------------------