1

I want the form to still show and allow input if a failed validation occurs but if all succeeds then I want the success message to show and the form to disappear. This code hides the form whether success or validation errors occur.

$(document).ready(function(){
        $( "#send" ).click(function(e){
            e.preventDefault();
            $( "#send" ).prop( "disabled", true );
            $( ".hideloader" ).show();
            $( "#send" ).html( "Sending <img src='img/ajax-loader.gif'>" );
            var form_data = $( "#contact-form" ).serialize();
            $.ajax({
                type: 'POST',
                url: 'contact-submit.php',
                data: form_data
            }).done(function(response) {
                $( "#server-results" ).hide().html(response).fadeIn("slow");
                $( "#send" ).prop("disabled", false);
                $( "#send" ).html( "Send Enquiry" );
                $( "#contact-form" ).hide();
        });
    });
});

My php code just using an email field as an example looks like this:

if ($_SERVER["REQUEST_METHOD"] === "POST") {

$message = "";

if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) === false) {

    $message .= "Invalid email address. <br/>";
}

if($message) {

    echo "<div class='red-error'><b>There were errors in your form:</b> <br/>" . $message . "</div>";

    } else {

    echo "<div class='green-success'>Thank you. We will respond to your enquiry as soon as possible.</div>";

    }
}
Iggy's Pop
  • 589
  • 1
  • 6
  • 24

1 Answers1

0

Assuming you are validating your form in back-end and returning a response object containing a property named validated with value of 1 when validated (and 0 when the validation failed), your ajax should look like this:

$.ajax({
   type: 'POST',
   url: 'contact-submit.php',
   data: form_data,
}).done(function(response) {
   if (response.validated) {
     // logic for when response has validated == 1
     $( "#contact-form" ).hide();
     $( "#send" ).prop("disabled", false);
     $( "#send" ).html( "Send Enquiry" );
   } 
   // we display the response html in both cases (validated or not)
   $( "#server-results" ).hide().html(response.html).fadeIn("slow");
});

And, in php, you'd need something similar to this (adjust to your logic):

$response = [];
if ($some_condition) {
  $response['validated'] = 1;
  $response['html'] = '<div class='green-success'>Some success message</div>';
} else {
  $response['validated'] = 0;
  $response['html'] = '<div class='red-error'>Some error message</div>';
}
echo json.encode($response);
tao
  • 82,996
  • 16
  • 114
  • 150
  • I have edited my original question to show the php. If there are validation errors server side then it should show the error with red background, if no validation errors and form submits, then message with green background should show and I can then send email, hide the form etc. – Iggy's Pop Apr 17 '17 at 18:52
  • I edited my answer to make the distinction between server errors and your custom logic errors. Server errors will call the `error` function of `$.ajax()`. Successful calls, including all possible custom logic results, will all call your `success` function, and that's where you have to parse the `response`. – tao Apr 17 '17 at 18:54
  • Thanks for your responses. I still don't understand this. Sorry, I am used to only using php and not jQuery/AJAX. How do I get this: `if (response.validated) { // validated, hide your form` to show the green background with success message and the else statement to show the red background with server side validation errors as per the php? – Iggy's Pop Apr 17 '17 at 19:02
  • In php construct an object with 2 props: message (html) and status. Than `echo json.encode($object)`. In `ajax.success` do `console.log(response)` and you'll figure it out. – tao Apr 17 '17 at 19:06
  • Okay, I am going to have to try think about this. I only know procedural php code, not OOP and I am not familiar with json. – Iggy's Pop Apr 17 '17 at 19:11
  • It doesn't have to be an object, it can be an array. Just encode it and echo. Search an example. It's all about organizing data sent/received into one single structure. – tao Apr 17 '17 at 20:01
  • That's not true, @mplungjan. I keep hearing `success` is being deprecated, but haven't found anything official. I'd appreciate any official source. AFAIK, `success` is an [Ajax Event](http://api.jquery.com/Ajax_Events/). `.done()` is a [deferred object](https://api.jquery.com/category/deferred-object/). I completely understand the advantage of using deferred objects (chaining, handling progress of multiple calls, returning promises) but that doesn't mean I need to use them in all cases. If an ajax is deferred, `.done()` runs after `.success()`. They are not the same. – tao Apr 18 '17 at 07:23
  • 1
    http://stackoverflow.com/questions/10931836/should-i-use-done-and-fail-for-new-jquery-ajax-code-instead-of-success-and : _Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks will be deprecated in jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead._ is the source of confusion – mplungjan Apr 18 '17 at 07:43
  • @mplungjan, that's not official (has no link), however, I found something that is: find the "Deprecation notice" [here](http://api.jquery.com/jquery.ajax/#jqXHR). Thank you. I'll edit this answer. – tao Apr 18 '17 at 07:50
  • I posted the SO post since it had more interesting comments about whether or not success was ACTUALLY gone . – mplungjan Apr 18 '17 at 07:52
  • @Jonathan, see my updated answer. I've also added a simple example of how to return a json response for your call. You'll need to adapt it to your needs and logic, of course. – tao Apr 18 '17 at 08:05
  • @mplungjan Read in [**async**](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings): As of `1.8`, you can't use `async:false` with `$.deferred`. You need to use `success()`, `error()` and `complete()`. I really do not understand how this works with the [deprecation notice](http://api.jquery.com/jquery.ajax/#jqXHR) of the three above in `3.0`. It's confusing, to say the least. They're both on the same page and they seem conflicting. What happens to `async:false` in `3.0`? Oh, it actually makes sense. `async:false` can't be deferred, right? It's a new page load. :) – tao Apr 18 '17 at 08:20
  • Thank you, I will try that out a bit later when in front of my pc – Iggy's Pop Apr 18 '17 at 08:23