0

I have written a small plugin to create a wizard. Each wizard step is a form and on click of "next" button I want to submit the form. I use AJAX for submitting the form and I want to wait for AJAX to complete before going to next step (if AJAX is successful) or stay on the same step (if AJAX fails). So I use async and await to achieve this and this works fine.

The issue arises because I want to validate the form before submitting: if validation fails then I return false and prevent ajax submission. Without async and await I have the normal behaviour and return false makes the wizard stay on the same page. With async and await it will not.

My code is the following:

            beforeNextStep: async function (currentStep) {
                if($('#smartcheckin' + currentStep).valid()){ //form compilato correttamente
                    if ($('#documento_caricato' + currentStep).val() == '') { //documento non caricato
                        swal.fire('SmartCheckin', 'Devi caricare un documento per proseguire', 'warning');
                        $('#smartcheckin' + currentStep).submit(function () {
                            return false; //non sottometto il form
                        });
                        return false; //non avanzo allo step dopo
                    }else{
                        $('#smartcheckin' + currentStep).submit(function () {
                            return false; //non sottometto il form
                        });
                        data=$('#smartcheckin'+ currentStep).serialize();
                        //AJAX PER INVIARE IL FORM
                        return await $.ajax({
                            type: 'POST',
                            dataType:'JSON',
                            url: 'endpoints/checkin.php',
                            data: data,
                        })
                        .done(function(data){
                            if(data.status==200){
                                //le cose sono andate bene
                                Toast.fire({icon: 'success',title: 'Checkin effettuato correttamente'});
                                if(currentStep<allSteps){
                                    return true;
                                }else{
                                    location.href="thankyou.html?token="+token;
                                }
                            }else{
                                $.ajax({
                                    "url": "/mantisbt/api/rest/issues",
                                    "method": "POST",
                                    "timeout": 0,
                                    "headers": {
                                        "Authorization": "3O4DtX_cwU9d57FRGdVhi6qCagUNFU1E",
                                        "Content-Type": "application/json"
                                    },
                                    "data": JSON.stringify({
                                        "summary": data.message.summary,
                                        "description": data.message.description,
                                        "additional_information": data.message.additional_information,
                                        "project": { "id": 1, "name": "smartreservation"},
                                        "category": {"id": 5, "name": "bugtracker"},
                                        "handler": {"name": "lelio"},
                                        "view_state": {"id": 10,"name": "public"},
                                        "priority": {"name": "normal"},
                                        "severity": {"name": "crash"},
                                        "reproducibility": {"name": "sometimes"},
                                        "sticky": false,
                                        /* "custom_fields": [],
                                        "tags": [] */
                                    })
                                }).done(function(data){
                                    Toast.fire({
                                        icon: 'error',
                                        title: 'Problemi a effettuare il checkin. Una segnalazione è stata aperta al nostro reparto tecnico'
                                    });
                                });
                                return false; //non avanzo allo step dopo
                            }       
                        });
                    }
                }else{
                    console.log('false returned');
                    return false; //form non valido non vado oltre
                }
            },

Look just at the first if: when the validation returns false the wizard returns false. Without async and await I never see the message false returned from the console

How to fix this? EDIT: note that the async await part per se works fine. So if the form validation is fine await gives me the expected behavior

The plugin code for this is just:

        beforeNextStep: function (t) {
            return !0
        },

so that i can fully customize it on the client side each time I run it. Should I make also this an async function?

Edit 2: the plugin initiation where I define this function:

    $("#mydiv").accWizard({
            mode: displayMode,
            //mode: 'wizard',
            //autoButtons: true,
            start: stepToDisplay, //lo step da cui partire
            autoButtonsNextClass: 'btn btn-primary float-right',
            autoButtonsPrevClass: 'btn btn-light',
            stepNumberClass: 'badge badge-pill badge-primary mr-1',
            beforeNextStep: async function (currentStep) {
                if($('#smartcheckin' + currentStep).valid()){
                    ... rest of my code here
Lelio Faieta
  • 6,457
  • 7
  • 40
  • 74

1 Answers1

0

For your use case, replace return false with throwing an error and simply handle this like

try {
  await beforeNextStep()
} catch {
  // Fire error toast
}

// continue execution as if everything is okay

or if you want to have the same false logic then do it like this

const result = await beforeNextStep()

if (!result) { // check if false is returned
  // Fire error toast
  return // exit the function to stop further code execution
}

// continue execution as if everything is okay
Mario Nikolaus
  • 2,346
  • 1
  • 21
  • 28