diff --git a/Block/Sidebar.php b/Block/Sidebar.php deleted file mode 100644 index 697eb49..0000000 --- a/Block/Sidebar.php +++ /dev/null @@ -1,67 +0,0 @@ - $this->getMiniCartCanAutoOpen(), - 'autoOpenTimeout' => $this->getMiniCartAutoOpenTimeout() - ]; - } - - /** - * Return whether the minicart can auto open - * - * @return int - */ - private function getMiniCartCanAutoOpen() - { - return (bool)$this->_scopeConfig->getValue( - self::XML_PATH_CHECKOUT_SIDEBAR_AUTO_OPEN, - ScopeInterface::SCOPE_STORE - ); - } - - /** - * Return whether the minicart can auto open - * - * @return int - */ - private function getMiniCartAutoOpenTimeout() - { - return (int)$this->_scopeConfig->getValue( - self::XML_PATH_CHECKOUT_SIDEBAR_AUTO_OPEN_TIMEOUT, - ScopeInterface::SCOPE_STORE - ); - } -} diff --git a/README.md b/README.md index 7634d0c..2fb2149 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,15 @@ -# module-mini-cart-auto-open -Magento 2 Mini Cart Auto Open Extension +# HumanElement_MiniCartAutoOpen -assuming your project has access to the human element composer repo +## Authors + + Ajay Khampariya :bowtie: + Seth Daugherty + Nate Shiff + + +Assuming your project has access to the human element composer repo + +## Installing/Updating to install: @@ -14,3 +22,24 @@ to update: ``` composer update human-element/module-mini-cart-auto-open ``` + +## Configuration: + + Stores > Settings > Configuration > Sales > Checkout > Shopping Cart Sidebar: + + Automatically Open Minicart After Adding Product to Cart + - Set to "Yes" to have the minicart automatically open after adding an item to the cart + + Timeout in Seconds (0-10) Before Automatically Closing Sidebar + - Depends on auto open of minicart being enabled + - Set the number of seconds the minicart should stay open before closing + + Scroll to Top of Page After Adding Product to Cart + - Depends on auto open of minicart being enabled + - Set to "Yes" to have the browser automatically scroll to top of page after adding item to cart + + +## Documentation: + + - Can auto open the minicart after adding product to cart + - Can scroll page to top after adding product to cart \ No newline at end of file diff --git a/ViewModel/Sidebar.php b/ViewModel/Sidebar.php new file mode 100644 index 0000000..14ac9d1 --- /dev/null +++ b/ViewModel/Sidebar.php @@ -0,0 +1,102 @@ +scopeConfig = $scopeConfig; + } + + /** + * Xml path to checkout sidebar auto open value + */ + const XML_PATH_CHECKOUT_SIDEBAR_AUTO_OPEN = 'checkout/sidebar/auto_open'; + + /** + * Xml path to checkout sidebar auto open timeout value + */ + const XML_PATH_CHECKOUT_SIDEBAR_AUTO_OPEN_TIMEOUT = 'checkout/sidebar/auto_open_timeout'; + + /** + * Xml path to checkout sidebar scroll top value + */ + const XML_PATH_CHECKOUT_SIDEBAR_SCROLL_TOP = 'checkout/sidebar/scroll_top'; + + /** + * Returns minicart config + * + * @return array + */ + public function getConfig() + { + return [ + 'canAutoOpen' => $this->getMiniCartCanAutoOpen(), + 'autoOpenTimeout' => $this->getMiniCartAutoOpenTimeout(), + 'canScrollTop' => $this->getMiniCartScrollTop(), + ]; + } + + /** + * Return whether the minicart can auto open + * + * @return int + */ + protected function getMiniCartCanAutoOpen() + { + return (bool)$this->scopeConfig->isSetFlag( + self::XML_PATH_CHECKOUT_SIDEBAR_AUTO_OPEN, + ScopeInterface::SCOPE_STORE + ); + } + + /** + * Return whether the minicart can auto open + * + * @return int + */ + protected function getMiniCartAutoOpenTimeout() + { + return (int)$this->scopeConfig->getValue( + self::XML_PATH_CHECKOUT_SIDEBAR_AUTO_OPEN_TIMEOUT, + ScopeInterface::SCOPE_STORE + ); + } + + /** + * Return whether to scroll to top of page after adding product to cart + * + * @return int + */ + protected function getMiniCartScrollTop() + { + return (bool)$this->scopeConfig->isSetFlag( + self::XML_PATH_CHECKOUT_SIDEBAR_SCROLL_TOP, + ScopeInterface::SCOPE_STORE + ); + } +} diff --git a/composer.json b/composer.json index 0efb362..08b6757 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "human-element/module-mini-cart-auto-open", "description": "Magento 2 Human-Element Mini Cart Auto Open Extension", "type": "magento2-module", - "version": "2.1.0", + "version": "2.2.0", "license": [ "GPL-3.0" ], @@ -14,6 +14,10 @@ { "email": "sdaugherty@human-element.com", "name": "Seth Daugherty" + }, + { + "email": "ajay@human-element.com", + "name": "AK" } ], "require": { diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index addc62c..7edbaf6 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -4,18 +4,26 @@
- + Depends on theme and ajax add to cart being enabled Magento\Config\Model\Config\Source\Yesno - + 1 validate-digits validate-digits-range digits-range-0-10 + + + After adding product to cart, auto scrolls user to top of page to see their mini cart + Magento\Config\Model\Config\Source\Yesno + + 1 + +
diff --git a/etc/config.xml b/etc/config.xml index 5706bdd..9160ec7 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -6,6 +6,7 @@ 0 3 + 0 diff --git a/etc/module.xml b/etc/module.xml index a150e07..23f2722 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,7 +1,7 @@ - + diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml index 0fe1fd4..caddfc5 100644 --- a/view/frontend/layout/default.xml +++ b/view/frontend/layout/default.xml @@ -3,7 +3,12 @@ - + + + HumanElement_MiniCartAutoOpen::minicart_open.phtml + HumanElement\MiniCartAutoOpen\ViewModel\Sidebar + + diff --git a/view/frontend/templates/minicart_open.phtml b/view/frontend/templates/minicart_open.phtml index 7008268..75ece73 100644 --- a/view/frontend/templates/minicart_open.phtml +++ b/view/frontend/templates/minicart_open.phtml @@ -1,7 +1,12 @@ +getViewModel(); +?> + \ No newline at end of file diff --git a/view/frontend/web/js/catalog-add-to-cart-mixin.js b/view/frontend/web/js/catalog-add-to-cart-mixin.js index 91f2a20..204f7ff 100644 --- a/view/frontend/web/js/catalog-add-to-cart-mixin.js +++ b/view/frontend/web/js/catalog-add-to-cart-mixin.js @@ -1,113 +1,18 @@ define([ 'jquery', - 'underscore', - 'mage/translate', - 'Magento_Catalog/js/product/view/product-ids-resolver', - 'jquery/ui', -], function($, _, $t, idsResolver) { +], function($) { "use strict"; return function (originalCatalogAddToCart) { $.widget('mage.catalogAddToCart', originalCatalogAddToCart, { - ajaxSubmit: function (form) { - var self = this, - productIds = idsResolver(form), - formData; + enableAddToCartButton: function (form) { + var self = this; - $(self.options.minicartSelector).trigger('contentLoading'); - self.disableAddToCartButton(form); - formData = new FormData(form[0]); + this._superApply(arguments); - $.ajax({ - url: form.attr('action'), - data: formData, - type: 'post', - dataType: 'json', - cache: false, - contentType: false, - processData: false, - - /** @inheritdoc */ - beforeSend: function () { - if (self.isLoaderEnabled()) { - $('body').trigger(self.options.processStart); - } - }, - - /** @inheritdoc */ - success: function (res) { - var eventData, parameters; - - $(document).trigger('ajax:addToCart', { - 'sku': form.data().productSku, - 'productIds': productIds, - 'form': form, - 'response': res - }); - - if (self.isLoaderEnabled()) { - $('body').trigger(self.options.processStop); - } - - if (res.backUrl) { - eventData = { - 'form': form, - 'redirectParameters': [] - }; - // trigger global event, so other modules will be able add parameters to redirect url - $('body').trigger('catalogCategoryAddToCartRedirect', eventData); - - if (eventData.redirectParameters.length > 0) { - parameters = res.backUrl.split('#'); - parameters.push(eventData.redirectParameters.join('&')); - res.backUrl = parameters.join('#'); - } - - self._redirect(res.backUrl); - - return; - } - - if (res.messages) { - $(self.options.messagesSelector).html(res.messages); - } - - if (res.minicart) { - $(self.options.minicartSelector).replaceWith(res.minicart); - $(self.options.minicartSelector).trigger('contentUpdated'); - } - - if (res.product && res.product.statusText) { - $(self.options.productStatusSelector) - .removeClass('available') - .addClass('unavailable') - .find('span') - .html(res.product.statusText); - } - self.enableAddToCartButton(form); - - // HE Custom Ajax Content Updated Event - $(self.options.minicartSelector).trigger('ajaxContentUpdated'); - }, - - /** @inheritdoc */ - error: function (res) { - $(document).trigger('ajax:addToCart:error', { - 'sku': form.data().productSku, - 'productIds': productIds, - 'form': form, - 'response': res - }); - }, - - /** @inheritdoc */ - complete: function (res) { - if (res.state() === 'rejected') { - location.reload(); - } - } - }); - }, + // HE Custom Ajax Content Updated Event + $(self.options.minicartSelector).trigger('ajaxContentUpdated'); + } }); return $.mage.catalogAddToCart; diff --git a/view/frontend/web/js/view/minicart_open.js b/view/frontend/web/js/view/minicart_open.js index 4af054b..7929744 100644 --- a/view/frontend/web/js/view/minicart_open.js +++ b/view/frontend/web/js/view/minicart_open.js @@ -1,49 +1,66 @@ define([ "jquery", - "jquery/ui" + "jquery/ui", + "domReady!" ], function ($) { var dropDownTimeout = null; return function (config, element) { - var minicart = $(element); - var canAutoOpen = config.canAutoOpen; - var autoOpenTimeout = config.autoOpenTimeout * 1000; - var dropDownDialog = minicart.find('[data-role="dropdownDialog"]'); - var clearDropDownTimeout = function () { + let minicart = $(element); + let canAutoOpen = config.canAutoOpen; + let canScrollTop = config.canScrollTop; + let autoOpenTimeout = config.autoOpenTimeout * 1000; + let scrollTopDuration = 1000; + let dropDownDialog = minicart.find('[data-role="dropdownDialog"]'); + + // Reusable function to cancel the closing of the minicart + let cancelCloseMinicart = () => { if (dropDownTimeout) { clearTimeout(dropDownTimeout); dropDownTimeout = null; } }; + // Reusable function to open minicart and start timeout for eventually closing minicart + let openMinicart = () => { + // Cancel pre-existing timeout + cancelCloseMinicart(); + + // Scroll Page to top + if (canScrollTop) { + $("html, body").animate({scrollTop: 0}, scrollTopDuration, () => { + dropDownDialog.dropdownDialog("open"); + }); + } else { + dropDownDialog.dropdownDialog("open"); + } + + // Create new timeout + dropDownTimeout = setTimeout(function () { + dropDownDialog.dropdownDialog("close"); + }, autoOpenTimeout); + }; + + // Trigger to determine whether minicart is allowed to auto open and if so, + // whether the is page done being busy to so it can happen + let openMiniCartTrigger = () => { + if (canAutoOpen) { + if ($('body').attr('aria-busy') === 'true') { + setTimeout(openMiniCartTrigger, 500); + } else { + openMinicart(); + } + } + }; + + // Cancel the closing of minicart if user mouses over it while it's open dropDownDialog.on('mouseenter', function (event) { event.stopPropagation(); - clearDropDownTimeout(); + cancelCloseMinicart(); }); - minicart.on('contentLoading', function () { - minicart.on('ajaxContentUpdated', function () { - var showCart = function () { - if (canAutoOpen && $('body').attr('aria-busy') == 'true') { - setTimeout(function(){ - showCart(); - },1000); - } else { - dropDownDialog.dropdownDialog("open"); - - // Cancel pre-existing timeout - clearDropDownTimeout(); - - // Create new timeout - dropDownTimeout = setTimeout(function () { - dropDownDialog.dropdownDialog("close"); - }, autoOpenTimeout); - } - }; - - showCart(); - }); - }); + // Kick off "open minicart" trigger to eventually open minicart + minicart.on('ajaxContentUpdated', openMiniCartTrigger); } }); \ No newline at end of file