user3504783 user3504783 - 24 days ago 8
jQuery Question

ajax, jquery contact form with reCAPTCHA v2 - clears form if invalid

So I finally managed to get my jquery/ajax contact form with the Google reCAPTCHA v2 to work, but if the reCAPTCHA isn't entered or invalid, the form is cleared, so the user would have to enter everything again. The also reCAPTCHA takes extremely long to load, so maybe it can be overlooked easily. How can I prevent it from clearing the form?

I found some solutions that place some php code in the value of the input fields, and something about htmlentities that I didn't quite understand, but I would like the page with the form to remain a .html file. Is it still possible to prevent it from clearing the form, or do I need to make my .html file a .php file?

Here is my form:

<div class="row">
<form id="ajax-contact" class="contact-form" role="form" method="post" action="mailer.php">
<div class="col-sm-4 col-sm-offset-2">
<div class="form-group">
<label for="name">Name *</label>
<input type="text" name="name" id="name" class="form-control" placeholder="Name" required/>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label for="email">Email *</label>
<input name="email" id="email" class="form-control" placeholder="Email" required/>
</div>
</div>

<div class="row contact-wrap mymessage2">
<div class="col-sm-8 col-sm-offset-2">
<div class="form-group">
<label>Message *</label>
<textarea name="message" id="message" class="form-control" rows="8" placeholder="Type your message here." required></textarea>
</div>
<div class="form-group">
<div class="g-recaptcha" data-sitekey="6LeehAsUAAAAAILDfzizJ23GHH7yPGxWBFP_3tE7"></div>
</div>
<div class="form-group">
<p>
<button type="submit" name="submit" class="btn btn-primary btn-lg">Submit Message</button>
</p>
</div>
</div>
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-messages"></div>
</div>
</div>
</form>


And here is the mailer.php that is called by the form:

<?php
// If the form was submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {

// If the Google Recaptcha box was clicked
if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])){
$captcha=$_POST['g-recaptcha-response'];
$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=MYKEY&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
$obj = json_decode($response);

// If the Google Recaptcha check was successful
if($obj->success == true) {
$name = strip_tags(trim($_POST["name"]));
$name = str_replace(array("\r","\n"),array(" "," "),$name);
$email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$message = trim($_POST["message"]);
if ( empty($name) OR empty($message) OR !filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo "Oops! There was a problem with your submission. Please complete the form and try again.";
exit;
}
$recipient = "I-removed-this@for-now.com";
$subject = "New message from $name";
$email_content = "Name: $name\n";
$email_content .= "Email: $email\n\n";
$email_content .= "Message:\n$message\n";
$email_headers = "From: $name <$email>";
if (mail($recipient, $subject, $email_content, $email_headers)) {
http_response_code(200);
echo "Thank You! Your message has been sent.";
}

else {
http_response_code(500);
echo "Oops! Something went wrong, and we couldn't send your message. Check your email address.";
}

}

// If the Google Recaptcha check was not successful
else {
echo "Robot verification failed. Please try again.";
}

}

// If the Google Recaptcha box was not clicked
else {
echo "Please click the reCAPTCHA box.";
}

}

// If the form was not submitted
// Not a POST request, set a 403 (forbidden) response code.
else {
http_response_code(403);
echo "There was a problem with your submission, please try again.";
}
?>


And here is the app.js that goes with the form:

$(function() {

// Get the form.
var form = $('#ajax-contact');

// Get the messages div.
var formMessages = $('#form-messages');

// Set up an event listener for the contact form.
$(form).submit(function(e) {
// Stop the browser from submitting the form.
e.preventDefault();

// Serialize the form data.
var formData = $(form).serialize();

// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
})
.done(function(response) {
// Make sure that the formMessages div has the 'success' class.
$(formMessages).removeClass('error');
$(formMessages).addClass('success');

// Set the message text.
$(formMessages).text(response);

// Clear the form.
$('#name').val('');
$('#email').val('');
$('#message').val('');
})
.fail(function(data) {
// Make sure that the formMessages div has the 'error' class.
$(formMessages).removeClass('success');
$(formMessages).addClass('error');

// Set the message text.
if (data.responseText !== '') {
$(formMessages).text(data.responseText);
} else {
$(formMessages).text('Oops! An error occured, and your message could not be sent.');
}
});

});

});


I would really appreciate your help!

Answer

Your reCaptcha cases in PHP are working fine and returning success responses. That's the reason its calling .done() method on $.ajax()

else {
   echo "Robot verification failed. Please try again.";
}

And

else {
   echo "Robot verification failed. Please try again.";
}

Try adding some error headers like http_response_code(400); to both of them

Comments