Last active
June 7, 2019 14:50
-
-
Save Convincible/aade715f852be7d61915e3d9d3cab7c1 to your computer and use it in GitHub Desktop.
Multiple reCAPTCHAs (v2 Invisible) that run after validation, then send form data over AJAX, using jQuery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<head> | |
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaLoad&render=explicit" async defer></script> | |
</head> | |
<body> | |
<form action="?" method="POST" class="form form-ajax"> | |
<label for="form-1-field-message">Message</label> | |
<textarea name="form-1-field-message" id="form-1-field-message" placeholder="How can we help?" required="required" autocomplete="off" minlength="20" rows="5"></textarea> | |
<button type="submit" id="form-1-submit" class="form-submit">Send</button> | |
<p class="form-info">Fill out the form to send us an email.</p> | |
<div class="g-recaptcha"> | |
Loading reCAPTCHA... | |
</div> | |
</form> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$('form.form').each(function(i, el) { | |
// Run over all forms on the page, and set some data on them to retrieve later | |
var form = $(el); | |
var info = $('.form-info', form).first()[0]; | |
var submit = $('.form-submit', form).last()[0]; | |
form.data('id', i); | |
form.data('info', info); | |
form.data('submit', submit); | |
}); | |
// Bind our logic to each form's submit function | |
// This will only actually run if HTML5 validation passes first | |
$('from.form').submit(function(e) { | |
e.preventDefault(); // Don't submit immediately | |
var form = $(this); | |
widget = form.data('grecaptcha-widget'); // This is set by the recaptchaLoad function below | |
formMessage(form, 'Checking you\'re not a robot...', 0); | |
grecaptcha.execute(widget); // Now execute this specific CAPTCHA – recaptchaResponse will be called | |
}); | |
// Called once the external JS from reCAPTCHA has loaded | |
function recaptchaLoad() { | |
console.log('Loading reCAPTCHAs...'); | |
// Form each form | |
$('form.form').each(function(i, el) { | |
var form = $(el); | |
// Find the (first – there should be only 1 per form anyway) captcha div | |
var captcha = form.find('.g-recaptcha').first()[0]; | |
var id = form.data('id'); | |
// Render the recaptcha but do not bind it to anything – at this point it won't actually run | |
widget = grecaptcha.render(captcha, { | |
'sitekey': '***************************************', | |
'callback': function(token) { | |
recaptchaResponse(form[0], token); // Essential to be able to identify the specific form/widget | |
}, | |
'badge': 'inline', | |
'size': 'invisible' | |
}); | |
// Save the id of this reCAPTCHA widget against the form itself | |
form.data('grecaptcha-widget', widget); | |
console.log('Form ' + id + ': Loaded'); | |
}); | |
} | |
// Called after the reCAPTCHA has been executed | |
function recaptchaResponse(form, token) { | |
// Get the widget id from the form that executed this captcha | |
widget = $(form).data('grecaptcha-widget'); | |
response = grecaptcha.getResponse(widget); | |
if (response) { | |
formMessage(form, 'Thanks for confirming you\'re human.', 1); | |
// CAPTCHA has passed – now send the form data | |
formSendAjax(form); | |
} else { | |
formMessage(form, 'Please complete the reCAPTCHA in order to submit the form.', -1); | |
} | |
// Reset the widget in any case so it's ready for a further submission | |
grecaptcha.reset(widget); | |
} | |
// Send data to the action defined in the form, over AJAX | |
function formSendAjax(form) { | |
form = $(form); | |
formMessage(form, 'Sending...', 0); | |
$.ajax({ | |
type: form.attr('method'), | |
url: form.attr('action'), | |
dataType: 'json', | |
data: form.serialize(), | |
success: function(data) { | |
formMessage(form, 'Thanks, your message has been sent. We\'ll respond ASAP.', 1); | |
form.trigger('reset'); | |
}, | |
error: function(data) { | |
formMessage(form, 'Sorry, something went wrong. Please email us manually instead.', -1); | |
} | |
}); | |
} | |
// Just a helpful info message that is updated as the form goes through different stages | |
function formMessage(form, msg, state = 0) { | |
form = $(form); | |
id = form.data('id'); | |
info = $(form.data('info')); | |
console.log('Form ' + id + ': ' + msg); | |
info.text(msg); | |
switch (state) { | |
case 1: | |
info.addClass('form-info-success'); | |
info.removeClass('form-info-error'); | |
info.removeClass('form-info-fyi'); | |
break; | |
case -1: | |
info.addClass('form-info-error'); | |
info.removeClass('form-info-success'); | |
info.removeClass('form-info-fyi'); | |
break; | |
default: | |
info.addClass('form-info-fyi'); | |
info.removeClass('form-info-success'); | |
info.removeClass('form-info-error'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment