Refactored button display logic

Replaced show / hide buttons mode with enable / disable buttons mode
This commit is contained in:
Pedro Silva 2023-06-23 08:23:11 +01:00
parent 583dea8d99
commit 587e065fba
No known key found for this signature in database
GPG key ID: E2EE20C0669D24B3
4 changed files with 98 additions and 67 deletions

View file

@ -1,4 +1,3 @@
import ButtonsToggleListener from '../Helper/ButtonsToggleListener';
import Product from '../Entity/Product'; import Product from '../Entity/Product';
import onApprove from '../OnApproveHandler/onApproveForContinue'; import onApprove from '../OnApproveHandler/onApproveForContinue';
import {payerData} from "../Helper/PayerData"; import {payerData} from "../Helper/PayerData";

View file

@ -1,7 +1,6 @@
import UpdateCart from "../Helper/UpdateCart"; import UpdateCart from "../Helper/UpdateCart";
import SingleProductActionHandler from "../ActionHandler/SingleProductActionHandler"; import SingleProductActionHandler from "../ActionHandler/SingleProductActionHandler";
import {hide, show, setVisible} from "../Helper/Hiding"; import {disable, enable} from "../Helper/ButtonDisabler";
import ButtonsToggleListener from "../Helper/ButtonsToggleListener";
class SingleProductBootstap { class SingleProductBootstap {
constructor(gateway, renderer, messages, errorHandler) { constructor(gateway, renderer, messages, errorHandler) {
@ -10,56 +9,70 @@ class SingleProductBootstap {
this.messages = messages; this.messages = messages;
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
this.mutationObserver = new MutationObserver(this.handleChange.bind(this)); this.mutationObserver = new MutationObserver(this.handleChange.bind(this));
this.formSelector = 'form.cart';
} }
form() {
return document.querySelector(this.formSelector);
}
handleChange() { handleChange() {
const shouldRender = this.shouldRender(); if (!this.shouldRender()) {
setVisible(this.gateway.button.wrapper, shouldRender);
setVisible(this.gateway.messages.wrapper, shouldRender);
if (!shouldRender) {
return; return;
} }
this.render(); this.render();
this.handleButtonStatus();
}
handleButtonStatus() {
if (!this.shouldEnable()) {
disable(this.gateway.button.wrapper, this.formSelector);
disable(this.gateway.messages.wrapper);
return;
}
enable(this.gateway.button.wrapper);
enable(this.gateway.messages.wrapper);
this.messages.renderWithAmount(this.priceAmount())
} }
init() { init() {
const form = document.querySelector('form.cart'); const form = this.form();
if (!form) { if (!form) {
return; return;
} }
form.addEventListener('change', this.handleChange.bind(this)); form.addEventListener('change', this.handleChange.bind(this));
this.mutationObserver.observe(form, {childList: true, subtree: true}); this.mutationObserver.observe(form, { childList: true, subtree: true });
const buttonObserver = new ButtonsToggleListener( const addToCartButton = form.querySelector('.single_add_to_cart_button');
form.querySelector('.single_add_to_cart_button'),
() => { if (addToCartButton) {
show(this.gateway.button.wrapper); (new MutationObserver(this.handleButtonStatus.bind(this)))
show(this.gateway.messages.wrapper); .observe(addToCartButton, { attributes : true });
this.messages.renderWithAmount(this.priceAmount()) }
},
() => {
hide(this.gateway.button.wrapper);
hide(this.gateway.messages.wrapper);
},
);
buttonObserver.init();
if (!this.shouldRender()) { if (!this.shouldRender()) {
hide(this.gateway.button.wrapper);
hide(this.gateway.messages.wrapper);
return; return;
} }
this.render(); this.render();
this.handleButtonStatus();
} }
shouldRender() { shouldRender() {
return document.querySelector('form.cart') !== null return this.form() !== null
&& !this.isDisabledReasonExternalPlugins();
}
shouldEnable() {
const form = this.form();
const addToCartButton = form ? form.querySelector('.single_add_to_cart_button') : null;
return this.shouldRender()
&& !this.priceAmountIsZero() && !this.priceAmountIsZero()
&& !this.isSubscriptionMode(); && ((null === addToCartButton) || !addToCartButton.classList.contains('disabled'));
} }
priceAmount() { priceAmount() {
@ -93,7 +106,7 @@ class SingleProductBootstap {
return !price || price === 0; return !price || price === 0;
} }
isSubscriptionMode() { isDisabledReasonExternalPlugins() {
// Check "All products for subscriptions" plugin. // Check "All products for subscriptions" plugin.
return document.querySelector('.wcsatt-options-product:not(.wcsatt-options-product--hidden) .subscription-option input[type="radio"]:checked') !== null return document.querySelector('.wcsatt-options-product:not(.wcsatt-options-product--hidden) .subscription-option input[type="radio"]:checked') !== null
|| document.querySelector('.wcsatt-options-prompt-label-subscription input[type="radio"]:checked') !== null; // grouped || document.querySelector('.wcsatt-options-prompt-label-subscription input[type="radio"]:checked') !== null; // grouped
@ -106,7 +119,7 @@ class SingleProductBootstap {
this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.endpoint,
this.gateway.ajax.change_cart.nonce, this.gateway.ajax.change_cart.nonce,
), ),
document.querySelector('form.cart'), this.form(),
this.errorHandler, this.errorHandler,
); );

View file

@ -0,0 +1,58 @@
/**
* @param selectorOrElement
* @returns {Element}
*/
const getElement = (selectorOrElement) => {
if (typeof selectorOrElement === 'string') {
return document.querySelector(selectorOrElement);
}
return selectorOrElement;
}
export const setEnabled = (selectorOrElement, enable, form = null) => {
const element = getElement(selectorOrElement);
if (!element) {
return;
}
if (enable) {
jQuery(element).css({
'cursor': '',
'-webkit-filter': '',
'filter': '',
} )
.off('mouseup')
.find('> *')
.css('pointer-events', '');
} else {
jQuery(element).css( {
'cursor': '',
'-webkit-filter': '',
'filter': '',
} )
.css({
'cursor': 'not-allowed',
'-webkit-filter': 'grayscale(100%)',
'filter': 'grayscale(100%)',
})
.on('mouseup', function(event) {
event.stopImmediatePropagation();
if (form) {
// Trigger form submit to show the error message
jQuery(form).find(':submit').trigger('click');
}
})
.find('> *')
.css('pointer-events', 'none');
}
};
export const disable = (selectorOrElement, form = null) => {
setEnabled(selectorOrElement, false, form);
};
export const enable = (selectorOrElement) => {
setEnabled(selectorOrElement, true);
};

View file

@ -1,39 +0,0 @@
/**
* When you can't add something to the cart, the PayPal buttons should not show.
* Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.
*/
class ButtonsToggleListener {
constructor(element, showCallback, hideCallback)
{
this.element = element;
this.showCallback = showCallback;
this.hideCallback = hideCallback;
this.observer = null;
}
init()
{
if (!this.element) {
return;
}
const config = { attributes : true };
const callback = () => {
if (this.element.classList.contains('disabled')) {
this.hideCallback();
return;
}
this.showCallback();
}
this.observer = new MutationObserver(callback);
this.observer.observe(this.element, config);
callback();
}
disconnect()
{
this.observer.disconnect();
}
}
export default ButtonsToggleListener;