mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
Adding the spinner and overlay on top of the submit button
This commit is contained in:
parent
38fc9906b7
commit
0ba33e9bb8
3 changed files with 188 additions and 58 deletions
|
@ -12,6 +12,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
.email-submit-button {
|
||||
position: relative;
|
||||
.loader:before {
|
||||
display: inline;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
margin-left: -6px;
|
||||
margin-top: -6px;
|
||||
left: auto;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.ppcp-axo-payment-container {
|
||||
padding: 1rem 0;
|
||||
background-color: #ffffff;
|
||||
|
@ -101,7 +114,7 @@
|
|||
}
|
||||
|
||||
.email-submit-button {
|
||||
padding: 5px 10px;
|
||||
padding: 5px 20px;
|
||||
background-color: #007cba;
|
||||
color: white;
|
||||
border: none;
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import Fastlane from "./Connection/Fastlane";
|
||||
import {log} from "./Helper/Debug";
|
||||
import { log } from "./Helper/Debug";
|
||||
import DomElementCollection from "./Components/DomElementCollection";
|
||||
import ShippingView from "./Views/ShippingView";
|
||||
import BillingView from "./Views/BillingView";
|
||||
import CardView from "./Views/CardView";
|
||||
import PayPalInsights from "./Insights/PayPalInsights";
|
||||
import {disable,enable} from "../../../ppcp-button/resources/js/modules/Helper/ButtonDisabler";
|
||||
import {getCurrentPaymentMethod} from "../../../ppcp-button/resources/js/modules/Helper/CheckoutMethodState";
|
||||
import { disable, enable } from "../../../ppcp-button/resources/js/modules/Helper/ButtonDisabler";
|
||||
import { getCurrentPaymentMethod } from "../../../ppcp-button/resources/js/modules/Helper/CheckoutMethodState";
|
||||
|
||||
class AxoManager {
|
||||
|
||||
constructor(axoConfig, ppcpConfig) {
|
||||
this.axoConfig = axoConfig;
|
||||
this.ppcpConfig = ppcpConfig;
|
||||
|
@ -51,7 +50,7 @@ class AxoManager {
|
|||
|
||||
this.registerEventHandlers();
|
||||
|
||||
this.shippingView = new ShippingView(this.el.shippingAddressContainer.selector, this.el, this.states );
|
||||
this.shippingView = new ShippingView(this.el.shippingAddressContainer.selector, this.el, this.states);
|
||||
this.billingView = new BillingView(this.el.billingAddressContainer.selector, this.el);
|
||||
this.cardView = new CardView(this.el.paymentContainer.selector + '-details', this.el, this);
|
||||
|
||||
|
@ -64,9 +63,9 @@ class AxoManager {
|
|||
}
|
||||
|
||||
if (
|
||||
this.axoConfig?.insights?.enabled
|
||||
&& this.axoConfig?.insights?.client_id
|
||||
&& this.axoConfig?.insights?.session_id
|
||||
this.axoConfig?.insights?.enabled &&
|
||||
this.axoConfig?.insights?.client_id &&
|
||||
this.axoConfig?.insights?.session_id
|
||||
) {
|
||||
PayPalInsights.config(this.axoConfig?.insights?.client_id, { debug: true });
|
||||
PayPalInsights.setSessionId(this.axoConfig?.insights?.session_id);
|
||||
|
@ -88,7 +87,6 @@ class AxoManager {
|
|||
}
|
||||
|
||||
registerEventHandlers() {
|
||||
|
||||
this.$(document).on('change', 'input[name=payment_method]', (ev) => {
|
||||
const map = {
|
||||
'ppcp-axo-gateway': 'card',
|
||||
|
@ -101,7 +99,6 @@ class AxoManager {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
// Listen to Gateway Radio button changes.
|
||||
this.el.gatewayRadioButton.on('change', (ev) => {
|
||||
if (ev.target.checked) {
|
||||
|
@ -163,7 +160,7 @@ class AxoManager {
|
|||
// Prevents sending checkout form when pressing Enter key on input field
|
||||
// and triggers customer lookup
|
||||
this.$('form.woocommerce-checkout input').on('keydown', async (ev) => {
|
||||
if(ev.key === 'Enter' && getCurrentPaymentMethod() === 'ppcp-axo-gateway' ) {
|
||||
if (ev.key === 'Enter' && getCurrentPaymentMethod() === 'ppcp-axo-gateway') {
|
||||
ev.preventDefault();
|
||||
log(`Enter key attempt - emailInput: ${this.emailInput.value}`);
|
||||
log(`this.lastEmailCheckedIdentity: ${this.lastEmailCheckedIdentity}`);
|
||||
|
@ -182,7 +179,7 @@ class AxoManager {
|
|||
// Listening to status update event
|
||||
document.addEventListener('axo_status_updated', (ev) => {
|
||||
const termsField = document.querySelector("[name='terms-field']");
|
||||
if(termsField) {
|
||||
if (termsField) {
|
||||
const status = ev.detail;
|
||||
const shouldHide = status.active && status.validEmail === false && status.hasProfile === false;
|
||||
|
||||
|
@ -245,11 +242,13 @@ class AxoManager {
|
|||
this.showAxoEmailField();
|
||||
this.el.watermarkContainer.show();
|
||||
|
||||
|
||||
// Move watermark to after email.
|
||||
this.$(this.el.fieldBillingEmail.selector).append(
|
||||
this.$(this.el.watermarkContainer.selector)
|
||||
);
|
||||
|
||||
// Add the submit button to the email field container.
|
||||
this.renderEmailSubmitNew();
|
||||
} else {
|
||||
this.el.emailWidgetContainer.hide();
|
||||
if (!scenario.defaultEmailField) {
|
||||
|
@ -258,7 +257,6 @@ class AxoManager {
|
|||
}
|
||||
|
||||
if (scenario.axoProfileViews) {
|
||||
|
||||
this.shippingView.activate();
|
||||
this.cardView.activate();
|
||||
|
||||
|
@ -272,7 +270,6 @@ class AxoManager {
|
|||
);
|
||||
|
||||
this.el.watermarkContainer.show();
|
||||
|
||||
} else {
|
||||
this.shippingView.deactivate();
|
||||
this.billingView.deactivate();
|
||||
|
@ -378,7 +375,7 @@ class AxoManager {
|
|||
|
||||
log(`Status updated: ${JSON.stringify(this.status)}`);
|
||||
|
||||
document.dispatchEvent(new CustomEvent("axo_status_updated", {detail: this.status}));
|
||||
document.dispatchEvent(new CustomEvent("axo_status_updated", { detail: this.status }));
|
||||
|
||||
this.rerender();
|
||||
}
|
||||
|
@ -448,7 +445,6 @@ class AxoManager {
|
|||
}
|
||||
|
||||
if (this.useEmailWidget()) {
|
||||
|
||||
// Display email widget.
|
||||
const ec = this.el.emailWidgetContainer;
|
||||
if (!document.querySelector(ec.selector)) {
|
||||
|
@ -460,7 +456,6 @@ class AxoManager {
|
|||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Move email to the AXO container.
|
||||
let emailRow = document.querySelector(this.el.fieldBillingEmail.selector);
|
||||
wrapperElement.prepend(emailRow);
|
||||
|
@ -510,6 +505,19 @@ class AxoManager {
|
|||
}
|
||||
}
|
||||
|
||||
async renderEmailSubmitNew() {
|
||||
const billingEmailSubmitButton = this.el.billingEmailSubmitButton;
|
||||
if (!document.querySelector(billingEmailSubmitButton.selector)) {
|
||||
|
||||
}
|
||||
|
||||
const submitButton = this.el.billingEmailSubmitButton.selector;
|
||||
// submitButton.innerText = this.axoConfig.billing_email_button_text;
|
||||
|
||||
const submitButtonSpinner = this.el.billingEmailSubmitButtonSpinner.selector;
|
||||
console.log(submitButton);
|
||||
}
|
||||
|
||||
async renderEmailSubmit() {
|
||||
// Create the submit button element
|
||||
const submitButton = document.createElement('button');
|
||||
|
@ -517,13 +525,33 @@ class AxoManager {
|
|||
submitButton.innerText = this.axoConfig.billing_email_button_text;
|
||||
submitButton.className = 'email-submit-button'; // Add a class for styling if needed
|
||||
|
||||
// Create the spinner element
|
||||
const spinner = document.createElement('span');
|
||||
spinner.className = 'loader ppcp-axo-overlay'; // Use the native loader class
|
||||
spinner.style.display = 'none'; // Initially hidden
|
||||
|
||||
// Append the spinner to the button
|
||||
submitButton.appendChild(spinner);
|
||||
|
||||
// Add an event listener to handle the button click
|
||||
submitButton.addEventListener('click', async () => {
|
||||
const emailInput = document.querySelector(this.el.fieldBillingEmail.selector + ' input');
|
||||
if (emailInput && emailInput.checkValidity()) {
|
||||
if (this.lastEmailCheckedIdentity !== emailInput.value) {
|
||||
log(`Submit button clicked - emailInput: ${emailInput.value}`);
|
||||
await this.onChangeEmail();
|
||||
|
||||
// Show the spinner, add the class to adjust padding and disable the button
|
||||
spinner.style.display = 'inline-block';
|
||||
submitButton.disabled = true;
|
||||
|
||||
|
||||
try {
|
||||
await this.onChangeEmail();
|
||||
} finally {
|
||||
// Hide the spinner and re-enable the button after the lookup is complete
|
||||
spinner.style.display = 'none';
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
emailInput.reportValidity(); // Trigger the HTML5 validation message
|
||||
|
@ -560,34 +588,7 @@ class AxoManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
watchEmail() {
|
||||
|
||||
if (this.useEmailWidget()) {
|
||||
|
||||
// TODO
|
||||
|
||||
} else {
|
||||
this.emailInput.addEventListener('change', async ()=> {
|
||||
log(`Change event attempt - emailInput: ${this.emailInput.value}`);
|
||||
log(`this.lastEmailCheckedIdentity: ${this.lastEmailCheckedIdentity}`);
|
||||
if (this.emailInput && this.lastEmailCheckedIdentity !== this.emailInput.value) {
|
||||
this.onChangeEmail();
|
||||
}
|
||||
});
|
||||
|
||||
log(`Last, this.emailInput.value attempt - emailInput: ${this.emailInput.value}`);
|
||||
log(`this.lastEmailCheckedIdentity: ${this.lastEmailCheckedIdentity}`);
|
||||
if (this.emailInput.value) {
|
||||
this.onChangeEmail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async onChangeEmail () {
|
||||
async onChangeEmail() {
|
||||
this.clearData();
|
||||
|
||||
if (!this.status.active) {
|
||||
|
@ -630,8 +631,116 @@ class AxoManager {
|
|||
});
|
||||
|
||||
this.disableGatewaySelection();
|
||||
await this.lookupCustomerByEmail();
|
||||
this.enableGatewaySelection();
|
||||
|
||||
const submitButton = document.querySelector('.email-submit-button');
|
||||
const spinner = submitButton.querySelector('.loader');
|
||||
if (submitButton && spinner) {
|
||||
// Show the spinner and disable the button
|
||||
spinner.style.display = 'inline-block';
|
||||
submitButton.classList.add('show-spinner');
|
||||
submitButton.disabled = true;
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
console.log("Delayed for 1 milisecond.");
|
||||
await this.lookupCustomerByEmail();
|
||||
|
||||
// Hide the spinner and re-enable the button after the lookup is complete
|
||||
if (submitButton && spinner) {
|
||||
spinner.style.display = 'none';
|
||||
submitButton.classList.remove('show-spinner');
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
|
||||
this.enableGatewaySelection();
|
||||
}, 1);
|
||||
}
|
||||
|
||||
|
||||
watchEmail() {
|
||||
if (this.useEmailWidget()) {
|
||||
// TODO
|
||||
} else {
|
||||
this.emailInput.addEventListener('change', async () => {
|
||||
log(`Change event attempt - emailInput: ${this.emailInput.value}`);
|
||||
log(`this.lastEmailCheckedIdentity: ${this.lastEmailCheckedIdentity}`);
|
||||
if (this.emailInput && this.lastEmailCheckedIdentity !== this.emailInput.value) {
|
||||
this.onChangeEmail();
|
||||
}
|
||||
});
|
||||
|
||||
log(`Last, this.emailInput.value attempt - emailInput: ${this.emailInput.value}`);
|
||||
log(`this.lastEmailCheckedIdentity: ${this.lastEmailCheckedIdentity}`);
|
||||
if (this.emailInput.value) {
|
||||
this.onChangeEmail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async onChangeEmail() {
|
||||
this.clearData();
|
||||
|
||||
if (!this.status.active) {
|
||||
log('Email checking skipped, AXO not active.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.emailInput) {
|
||||
log('Email field not initialized.');
|
||||
return;
|
||||
}
|
||||
|
||||
log(`Email changed: ${this.emailInput ? this.emailInput.value : '<empty>'}`);
|
||||
|
||||
this.$(this.el.paymentContainer.selector + '-detail').html('');
|
||||
this.$(this.el.paymentContainer.selector + '-form').html('');
|
||||
|
||||
this.setStatus('validEmail', false);
|
||||
this.setStatus('hasProfile', false);
|
||||
|
||||
this.hideGatewaySelection = false;
|
||||
|
||||
this.lastEmailCheckedIdentity = this.emailInput.value;
|
||||
|
||||
if (!this.emailInput.value || !this.emailInput.checkValidity()) {
|
||||
log('The email address is not valid.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.data.email = this.emailInput.value;
|
||||
this.billingView.setData(this.data);
|
||||
|
||||
if (!this.fastlane.identity) {
|
||||
log('Not initialized.');
|
||||
return;
|
||||
}
|
||||
|
||||
PayPalInsights.trackSubmitCheckoutEmail({
|
||||
page_type: 'checkout'
|
||||
});
|
||||
|
||||
this.disableGatewaySelection();
|
||||
|
||||
const submitButton = document.querySelector('.email-submit-button');
|
||||
const spinner = submitButton.querySelector('.loader');
|
||||
if (submitButton && spinner) {
|
||||
// Show the spinner and disable the button
|
||||
spinner.style.display = 'inline-block';
|
||||
submitButton.disabled = true;
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
console.log("Delayed for 1 milisecond.");
|
||||
await this.lookupCustomerByEmail();
|
||||
|
||||
// Hide the spinner and re-enable the button after the lookup is complete
|
||||
if (submitButton && spinner) {
|
||||
spinner.style.display = 'none';
|
||||
submitButton.disabled = false;
|
||||
}
|
||||
|
||||
this.enableGatewaySelection();
|
||||
}, 1);
|
||||
}
|
||||
|
||||
async lookupCustomerByEmail() {
|
||||
|
@ -670,7 +779,7 @@ class AxoManager {
|
|||
address: cardBillingAddress,
|
||||
};
|
||||
const phoneNumber = authResponse.profileData?.shippingAddress?.phoneNumber?.nationalNumber ?? '';
|
||||
if(phoneNumber) {
|
||||
if (phoneNumber) {
|
||||
billingData.phoneNumber = phoneNumber
|
||||
}
|
||||
|
||||
|
@ -766,7 +875,7 @@ class AxoManager {
|
|||
|
||||
this.ensureBillingPhoneNumber(data);
|
||||
|
||||
log(`Ryan flow - submitted nonce: ${this.data.card.id}` )
|
||||
log(`Ryan flow - submitted nonce: ${this.data.card.id}`)
|
||||
|
||||
this.submit(this.data.card.id, data);
|
||||
|
||||
|
@ -777,7 +886,7 @@ class AxoManager {
|
|||
this.cardComponent.getPaymentToken(
|
||||
this.tokenizeData()
|
||||
).then((response) => {
|
||||
log(`Gary flow - submitted nonce: ${response.id}` )
|
||||
log(`Gary flow - submitted nonce: ${response.id}`)
|
||||
this.submit(response.id);
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -833,7 +942,6 @@ class AxoManager {
|
|||
});
|
||||
|
||||
if (data) {
|
||||
|
||||
// Ryan flow.
|
||||
const form = document.querySelector('form.woocommerce-checkout');
|
||||
const formData = new FormData(form);
|
||||
|
@ -902,13 +1010,13 @@ class AxoManager {
|
|||
}
|
||||
|
||||
deleteKeysWithEmptyString = (obj) => {
|
||||
for(let key of Object.keys(obj)){
|
||||
if (obj[key] === ''){
|
||||
for (let key of Object.keys(obj)) {
|
||||
if (obj[key] === '') {
|
||||
delete obj[key];
|
||||
}
|
||||
else if (typeof obj[key] === 'object'){
|
||||
else if (typeof obj[key] === 'object') {
|
||||
obj[key] = this.deleteKeysWithEmptyString(obj[key]);
|
||||
if (Object.keys(obj[key]).length === 0 ) delete obj[key];
|
||||
if (Object.keys(obj[key]).length === 0) delete obj[key];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,15 @@ class DomElementCollection {
|
|||
selector: '#billing_email_field'
|
||||
});
|
||||
|
||||
this.billingEmailSubmitButton = new DomElement({
|
||||
selector: '#ppcp-axo-billing-email-submit-button',
|
||||
});
|
||||
|
||||
this.billingEmailSubmitButtonSpinner = new DomElement({
|
||||
selector: '#ppcp-axo-billing-email-submit-spinner',
|
||||
className: 'loader ppcp-axo-overlay'
|
||||
});
|
||||
|
||||
this.submitButtonContainer = new DomElement({
|
||||
selector: '#ppcp-axo-submit-button-container',
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue