JFL
JFL

Reputation: 25

submit form with ajax validation jquery / standard javascript

I'll start with an apology - I'm a .NET coder with little (no) front-end experience.

When the user clicks on Submit, the form needs to call a REST service, if the service returns true then the user is presented with a warning that a duplicate exists and are asked whether they want to continue. Appreciate any help.

I have the Submit button ONCLICK wired up to Approve()

When the checkForDuplicateInvoice() gets called, it passes the control back to the calling function right away before the ajax call has a chance to get the result. The effect is that the Validate() function finishes without taking into account whether or not a duplicate invoice exists.

I need help in modifying the form so that when the user clicks on the submit button, the form validates (including the ajax call to the db) before finally submitting.

I've modified the code based on Jasen's feedback.

I'm including https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js in my header.

The error I get now is "Object doesn't support property or method 'button'"

What I have now for my form submission/validation is:

 $(document).ready(function () {
        $("#process").button().click( function () {
            if (ValidateFields()) { // internal validation
                var companyCode = document.getElementById("_1_1_21_1").value;
                var invoiceNo = document.getElementById("_1_1_25_1").value;
                var vendorNo = document.getElementById("_1_1_24_1").value;

                if (vendorNo == "undefined" || invoiceNo == "undefined" || companyCode == "undefined") {
                    return false;
                }
                $.ajax({ // external validation
                    type: "GET",
                    contentType: "application/json;charset=utf-8",
                    //context: $form,
                    async: false,
                    dataType: "jsonp",
                    crossDomain: true,
                    cache: true,
                    url: "http://cdmstage.domain.com/services/rest/restservice.svc/CheckDuplicateInvoice?InvoiceNumber=" + invoiceNo + "&VendorNumber=" + vendorNo + "&CompanyCode=" + companyCode,
                    success: function (data) {
                        var result = data;
                        var exists = result.CheckForInvoiceDuplicateResult.InvoiceExists;
                        var valid = false;
                        if (exists) {
                            if (confirm('Duplicate Invoice Found! Click OK to override or Cancel to return to the form.')) {
                                valid = true;
                            }
                        }
                        else {
                            valid = true; // no duplicate found - form is valid
                        }

                        if (valid) {
                            document.getElementById("_1_1_20_1").value = "Approve";

                            doFormSubmit(document.myForm);
                        }
                    },
                    error: function (xhr) {
                        alert(xhr.responseText);
                    }
                });
            }
        });
    });

Upvotes: 1

Views: 684

Answers (1)

Jasen
Jasen

Reputation: 14250

First review How do I return the response from an asynchronous call? Understand why you can't return a value from the ajax callback functions.

Next, disassociate the submit button from the form to prevent it from performing default submission. Test it to see it does nothing.

<form>
    ...
    <button type="button" id="process" />
</form>

Then wire it up to make your validation request

$("#process").on("click", function() {
    if (valid()) {
      $(this).prop("disabled", true);  // disable the button to prevent extra user clicks

      // make ajax server-side validation request
    }
});

Then you can make your AJAX request truly asynchronous.

$.ajax({
    async: true,
    ...,
    success: function(result) {
        if (exists) {
            // return true; // returning a value is futile
            // make ajax AddInvoice call
        }
    }
});

Pseudo-code for this process

if (client-side is valid) {

    server-side validation: {
        on response: if (server-side is valid) {
            AddInvoice: {
                on response: if (successful) {
                    form.submit()
                }
            }
        }
    }

}
  1. In the callback for the server-side validation you make the AddInvoice request.
  2. In the callback for AddInvoice you call your form.submit().

In this way you nest ajax calls and wait for each response. If any fail, make the appropriate UI prompt and re-enable the button. Otherwise, you don't automatically submit the form until both ajax calls succeed and you call submit() programmatically.

Upvotes: 1

Related Questions