Reputation: 791
I'm using Google reCAPTCHA and have been able to add the CAPTCHA component to my page inside a form. But when I submit the form there's no validation taking place to check if the CAPTCHA has been solved.
How do I validate that the CAPTCHA component has been solved when submitting my form? Or, in other words, how do I make my CAPTCHA component required?
Upvotes: 62
Views: 98927
Reputation: 949
if you want to use the native html5 popups, than here is the solution
JavaScript:
window.addEventListener('load', () => {
const $recaptcha = document.querySelector('#g-recaptcha-response');
if ($recaptcha) {
$recaptcha.setAttribute('required', 'required');
}
})
CSS:
#g-recaptcha-response {
display: block !important;
position: absolute;
margin: -78px 0 0 0 !important;
width: 302px !important;
height: 76px !important;
z-index: -999999;
opacity: 0;
}
Upvotes: 104
Reputation: 10846
Working solution in 2022
Personally, I was not able to get any of the above solutions to work with my captcha. So I figured I would share my current working solution for those facing the same issue.
The accepted answer doesn't have a validation technique for when the captcha expires, the below solution addresses that.
My notes in the .js
should explain the solution thoroughly.
JavaScript
// By default do not allow form submission.
var allow_submit = false
function captcha_filled () {
/*
* This is called when Google get's the recaptcha response and approves it.
* Setting allow_submit = true will let the form POST as normal.
* */
allow_submit = true
}
function captcha_expired () {
/*
* This is called when Google determines too much time has passed and expires the approval.
* Setting allow_submit = false will prevent the form from being submitted.
* */
allow_submit = false
}
function check_captcha_filled (e) {
console.log('captcha-verified')
/*
* This will be called when the form is submitted.
* If Google determines the captcha is OK, it will have
* called captcha_filled which sets allow_submit = true
* If the captcha has not been filled out, allow_submit
* will still be false.
* We check allow_submit and prevent the form from being submitted
* if the value of allow_submit is false.
* */
// If captcha_filled has not been called, allow_submit will be false.
// In this case, we want to prevent the form from being submitted.
if (!allow_submit) {
// This call prevents the form submission.
// e.preventDefault()
// This alert is temporary - you should replace it with whatever you want
// to do if the captcha has not been filled out.
alert('ERROR: Please verify you are human by filling out the captcha')
return false
}
captcha_expired()
return true
}
HTML
<form action="post" onsubmit="return check_captcha_filled()">
<!-- form items -->
<div class="g-recaptcha"
data-callback="captcha_filled"
data-expired-callback="captcha_expired"
data-sitekey="your site key">
</div>
</form>
Upvotes: 5
Reputation: 31
If you want a more friendly and descriptive message, you can add a required checkbox. This will ensure the html5 popup shows something like: "Please check this box if you want to proceed"
<div class="captcha">
<div class="g-recaptcha" data-sitekey="Your Site Key" data-callback="removeFakeCaptcha"></div>
<input type="checkbox" class="captcha-fake-field" tabindex="-1" required>
</div>
Add the code to remove the fake captcha once completed
window.removeFakeCaptcha = function() {
document.querySelector('.captcha-fake-field').remove();
}
Then on the css you hide the checkbox and position it to the captcha box:
.captcha {
position: relative;
}
.captcha-fake-field {
background: transparent;
bottom: 0;
border: none;
display: block;
height: 1px;
left: 12px;
width: 1px;
position: absolute;
z-index: -1;
}
Upvotes: 2
Reputation: 31
I find this very helpful:
<div class="g-recaptcha myPopover" data-sitekey="Your Key"
data-callback="recaptchaCallback">
You add a function to data-callback="recaptchaCallback" with this code:
var recaptchachecked=false;
function recaptchaCallback() {
recaptchachecked = true;
}
and a function were you return the value to use it in a other html-tag like this:
<form method="post" onsubmit="return isreCaptchaChecked()">
function isreCaptchaChecked()
{
return recaptchachecked;
}
I hope this helps you.
Upvotes: 0
Reputation: 5292
I checked for existance of #g-recaptcha-response:
function checkRecaptcha() {
res = $('#g-recaptcha-response').val();
if (res == "" || res == undefined || res.length == 0)
return false;
else
return true;
}
//...
$('#frm-signup').submit(function(e) {
if(!checkRecaptcha()) {
$( "#frm-result" ).text("Please validate your reCAPTCHA.");
return false;
}
//...
});
This really should be part of the docs...
Upvotes: 12
Reputation: 4387
I had the same problem as yours and solved it this way:
First declare a variable that stores 1
or 0
depending or whether the user filled the capcha correctly.
var allowSubmit = false;
Then you need a function which gets executed when the user fills the reCapcha correctly:
function capcha_filled () {
allowSubmit = true;
}
... and a function that gets executed when the reCapcha session expires:
function capcha_expired () {
allowSubmit = false;
}
To tell reCapcha about your functions (callbacks), set those data-
attributes in your html:
<div class="g-recaptcha"
data-callback="capcha_filled"
data-expired-callback="capcha_expired"
data-sitekey="your site key"></div>
Or if you use explicit load:
var onloadCallback = function() {
grecaptcha.render('your_div_id', {
'sitekey' : 'your_site_key',
'callback': capcha_filled,
'expired-callback': capcha_expired,
});
};
You need also a callback for the form submission:
function check_if_capcha_is_filled (e) {
if(allowSubmit) return true;
e.preventDefault();
alert('Fill in the capcha!');
}
Finally add in the form the onsubmit
attribute:
<form action="..." onsubmit="check_if_capcha_is_filled">
Note: as mentioned in the comments, a server validation is still needed. The code prevents accidentally submitting the form unless the capcha is filled and is only for user's convenience.
Upvotes: 20
Reputation: 191
I found this to be a quick & easy way to do it. Add this to your headers:
<script>
window.onload = function() {
var recaptcha = document.forms["myForm"]["g-recaptcha-response"];
recaptcha.required = true;
recaptcha.oninvalid = function(e) {
// do something
alert("Please complete the captcha");
}
}
</script>
This only works in HTML5, and is (or should be) supported by these browsers: http://caniuse.com/#feat=form-validation
(The JS console in Chrome shows this error message: "Invalid form control" only in Google Chrome , and I haven't been able to work around this. Hopefully someone else will improve this response.)
Upvotes: 17
Reputation: 667
Not sure if you already solved this, but you could use an addon to validate the Google recaptcha: http://formvalidation.io/addons/recaptcha2/
Upvotes: 0