Hi @imconfused4sure
Thank you for reaching out!
The issue doesn’t seem to be something related to the WooCommerce Square plugin, and posting the issue on the support section of the Order Delivery Date for WooCommerce plugin was the right move. I hope the plugin author will be happy to assist you with the issue.
I am marking this thread as resolved, but please let us know if any additional issues arise! π
Hi @nawaz0705
That of course is the easy solution, however it is also possible that it is refreshing fast enough that one of your scripts is loading it twice. If the page loads slower it does not happen. For some reason there is a double iframe. I don’t know how the other plugin would do this. This is what the HTML looks like:
<div id="wc-square-credit-card-container">
<div id="single-card-wrapper-09ad3e1c-9ebc-211a-9340-3626eb7f71b9"
class="sq-card-wrapper">
<div class="sq-card-iframe-container"
style="height: 48px;"><iframe name="single-card-09ad3e1c-9ebc-211a-9340-3626eb7f71b9"
scrolling="no"
src="https://sandbox.web.squarecdn.com/1.32.0/single-card-element-iframe.html"
class="sq-card-component"
width="100%"
height="48px"
frameborder="0"></iframe></div><span class="sq-card-message"></span>
</div>
<div id="single-card-wrapper-887a1ad3-7174-fceb-2386-b8102856a7b8"
class="sq-card-wrapper">
<div class="sq-card-iframe-container"
style="height: 48px;"><iframe name="single-card-887a1ad3-7174-fceb-2386-b8102856a7b8"
scrolling="no"
src="https://sandbox.web.squarecdn.com/1.32.0/single-card-element-iframe.html"
class="sq-card-component"
width="100%"
height="48px"
frameborder="0"></iframe></div><span class="sq-card-message"></span>
</div>
</div>
I did some tracing. There Square form is created by a listener in wc-square.min.js. When the event is triggered twice in a short time it is able to create a second input. Because there is no existing this.payment_form it does not trigger the destroy. Here is the logging trace of events between wc-square.min.js and the square resource.
wc-square.min.js: handle_checkout_page
wc-square.min.js: updated_checkout Listener
wc-square.min.js: set_payment_fields
wc-square.min.js: this.payment_form: undefined
square.js: card
wc-square.min.js: updated_checkout Listener
wc-square.min.js: set_payment_fields
wc-square.min.js: this.payment_form: undefined
square.js: card
square.js: attach
square.js: buildElementOnIframe
square.js: buildCardElement
square.js: attach
square.js: buildElementOnIframe
square.js: buildCardElement
When the listener is called once the form is already loaded it only displays once.
wc-square.min.js: updated_checkout Listener
wc-square.min.js: set_payment_fields
wc-square.min.js: this.payment_form: [object Object]
square.js: card
square.js: attach
square.js: buildElementOnIframe
square.js: buildCardElement
wc-square.min.js listener:
handle_checkout_page() {
console.log("wc-square.min.js: handle_checkout_page");
$(document.body).on("updated_checkout", e => {
console.log("wc-square.min.js: updated_checkout Listener");
this.set_payment_fields();
});
$(document.body).on("updated_checkout", () => this.handle_saved_payment_methods());
this.form.on("checkout_place_order_".concat(this.id), () => this.validate_payment_data());
}
@nawaz0705
In case someone else runs into this issue, here is a script to remove it.
function removeExtraSquareInputOnCheckoutPage() {
const squareWrapper = document.querySelector(<code>#payment</code>);
const observer = new MutationObserver(async () => {
let numberOfInputs = 0;
let numberOfSelectorQueries = 0;
do {
await delay(1000);
const squareInputs = document.querySelectorAll(<code>.sq-card-wrapper</code>);
numberOfSelectorQueries++;
numberOfInputs = squareInputs.length;
if (numberOfInputs > 1) {
let i = 0;
squareInputs.forEach(input => {
if (i > 0) {
console.log(<code>Deleted duplicate Square Input</code>);
input.remove();
}
i++;
});
}
} while (numberOfInputs < 1 && numberOfSelectorQueries < 10);
});
observer.observe(squareWrapper, {childList: true});
}
async function delay(delayTime) {
return new Promise(resolve => setTimeout(resolve, delayTime));
}
Hi @imconfused4sure,
Thank you for this! We will leave this here in the event someone else does run into this issue.
Cheers!
Hello, I am also having this issue. Would you be able to tell me where to place the script?
Thank you for any help you can provide, I appreciate it! Mike
Hi there @mtm100 π
Hello, I am also having this issue. Would you be able to tell me where to place the script?
Feel free to use a plugin like Code Snippets.
Furthermore, since this thread is closed and technically resolved, for anything else that you might need regarding this, please open a new topic here: https://wordpress.org/support/plugin/woocommerce/#new-topic-0.
Thanks!
I am facing this issue please help me with how can I solve this.
Hi there @aqsa30 π
I am facing this issue please help me with how can I solve this.
Thanks for reaching out. Happy to help you with this!
Feel free to enter the script mentioned in the thread response here, using a plugin like Code Snippets. There are videos about how to use the plugin, on the plugin’s page itself.
I hope that helps, otherwise let us know!
Just a small update to the script that carl provided. When I used it as he gave it it would not work as it ran before the #payment node was loaded. Updated it to check if the #payment node exists, if it does not wait 50ms and try again.
<script>
function removeExtraSquareInputOnCheckoutPage() {
const squareWrapper = document.querySelector("#payment");
if(!squareWrapper) {
//The node we need does not exist yet.
//Wait 50ms and try again
window.setTimeout(removeExtraSquareInputOnCheckoutPage,50);
return;
}
const observer = new MutationObserver(async () => {
let numberOfInputs = 0;
let numberOfSelectorQueries = 0;
do {
await delay(1000);
const squareInputs = document.querySelectorAll(".sq-card-wrapper");
numberOfSelectorQueries++;
numberOfInputs = squareInputs.length;
if (numberOfInputs > 1) {
let i = 0;
squareInputs.forEach(input => {
if (i > 0) {
console.log("Deleted duplicate Square Input");
input.remove();
}
i++;
});
}
} while (numberOfInputs < 1 && numberOfSelectorQueries < 10);
});
observer.observe(squareWrapper, {childList: true});
}
async function delay(delayTime) {
return new Promise(resolve => setTimeout(resolve, delayTime));
}
removeExtraSquareInputOnCheckoutPage();// JavaScript Document
</script>