WooCommerce - Attivare la Validazione del Modulo di Checkout
Ho cercato ovunque una risposta ma non ho trovato nulla.
Sto creando un gateway di pagamento in un iframe
che viene caricato all'interno della pagina di checkout. Il mio obiettivo è che, una volta che il cliente clicca su un determinato pulsante, venga attivata la funzione che verifica se ha compilato tutti i campi obbligatori. Se la funzione restituisce true
, l'iframe viene caricato.
Altrimenti, viene attivato l'avviso della funzione di validazione.
Ho trovato la funzione come metodo chiamato update_checkout_action
all'interno della classe wc_checkout_form
.
Spero che le informazioni siano sufficienti, se servisse altro, fatemelo sapere e vi fornirò ulteriori dettagli.
Grazie.

Mi sono imbattuto in questo problema diverse volte, ma non ho ancora trovato un metodo diretto per gestirlo. Ecco cosa ho fatto in passato.
Puoi attivare facilmente la validazione del checkout forzando un clic sul pulsante di invio.
$('#myButton').on('click', function(){
$('#place_order').click();
});
Tuttavia, questo non è molto utile perché invierà semplicemente l'ordine se non ci sono errori.
C'è anche il callback checkout_error, ma viene attivato solo se c'è un errore.
$(document.body).on('checkout_error', function () {
// C'era un errore di validazione
});
Ecco cosa dobbiamo fare.
- Rilevare quando viene cliccato il pulsante di invio
- Controllare la presenza di errori
- Se ci sono errori, lasciare che Woo li gestisca normalmente
- Se non ci sono errori, impedire il completamento dell'ordine
- Mostrare il tuo iframe
- ... Rivalidare / Reinviare l'Ordine
Non appena viene cliccato il pulsante di invio, possiamo aggiungere un campo nascosto e impostare il valore a 1. Possiamo rilevare l'evento di invio utilizzando checkout_place_order. Questo dovrebbe essere inserito nel tuo file JS.
var checkout_form = $('form.woocommerce-checkout');
checkout_form.on('checkout_place_order', function () {
if ($('#confirm-order-flag').length == 0) {
checkout_form.append('<input type="hidden" id="confirm-order-flag" name="confirm-order-flag" value="1">');
}
return true;
});
Ora, aggiungi una funzione a functions.php che controllerà quell'input nascosto e bloccherà l'ordine se il valore == 1. Blocca l'ordine aggiungendo un errore.
function add_fake_error($posted) {
if ($_POST['confirm-order-flag'] == "1") {
wc_add_notice( __( "custom_notice", 'fake_error' ), 'error');
}
}
add_action('woocommerce_after_checkout_validation', 'add_fake_error');
Tornando al nostro file JS, possiamo usare il callback checkout_error. Se c'è 1 errore, sappiamo che è l'errore fittizio che abbiamo creato, quindi possiamo mostrare l'iframe. Se ci sono più di 1 errore, significa che ci sono altri errori reali nella pagina.
$(document.body).on('checkout_error', function () {
var error_count = $('.woocommerce-error li').length;
if (error_count == 1) { // Validazione Superata (Solo l'Errore Fittizio Esiste)
// Mostra iFrame
}else{ // Validazione Fallita (Esistono Errori Reali, Rimuovi Quello Fittizio)
$('.woocommerce-error li').each(function(){
var error_text = $(this).text();
if (error_text == 'custom_notice'){
$(this).css('display', 'none');
}
});
}
});
Nella sezione commentata, // Mostra iFrame, probabilmente lo aprirei in un lightbox. Ad un certo punto avrai bisogno di un altro pulsante di invio che attivi l'invio del form e imposti l'input nascosto.
$('#confirm-order-button').click(function () {
$('#confirm-order-flag').val('');
$('#place_order').trigger('click');
});

Ho trovato una soluzione rapida e semplice in JS per questo caso (c'erano i moduli di WooCommerce e Stripe). Si basa sulla prevenzione dell'invio del pulsante di checkout, ma esegue comunque le verifiche dei moduli.
// creo l'evento click sul wrapper per un elemento dinamico
$('body').on('click', 'button#place_order_wrap', function(event) {
// intervallo principale dove avverranno tutte le operazioni
var validatoins = setInterval(function(){
// controllo degli errori
if(no_errors==0){
// utilizzo la funzione setTimeout() con un tempo limitato a 200ms
// per limitare la funzione di checkout alla sola verifica
setTimeout(function(){
// attivo il pulsante originale
$('button#place_order').click();
// se ci sono errori, interrompo l'intervallo e restituisco false
if(($('element').find('ul.woocommerce_error').length!==0)||($('element').find('.woocommerce-invalid-required-field').length!==0)){
clearInterval(validatoins);
return false;
}else{
no_errors=1;
}
}, 200);
}
if(no_errors==1){
// stesso controllo degli errori
if($('#step5').find('ul.woocommerce_error').length!=0||($('#step5').find('.woocommerce-invalid-required-field').length!==0)){
// se ci sono errori, interrompo l'intervallo e restituisco false
clearInterval(validatoins);
return false;
}
setTimeout(function(){
// se non ci sono errori
if(($('#step5').find('ul.woocommerce_error').length==0)&&($('#step5').find('.woocommerce-invalid-required-field').length==0)){
// eseguo azioni, segnalo che è completato
return false;
}
}, 1000);
// se qualcosa è completato
if() {
setTimeout(function(){
// attivo il click originale del checkout
$('button#place_order').click();
clearInterval(validatoins);
}, 1000);
}
}
}, 1000);
}
