I'm using HAML, Semantic UI and jQuery to generate my static site, and have a set of forms on a page which use reCAPTCHA v2. My web implementer ran out of time on the project so I've picked up the slack, but only know a little Javascript/Semantic/jQuery.
_header partial yields:
<script src="https://www.google.com/recaptcha/api.js"></script>
my layout yields the form data:
<form action='https://liveformhq.com/form/<form uuid>' class='ui large form' id='formGeneral' method='POST'>
<snip>
<label>Message *</label>
<textarea name='message' placeholder='Say hello'></textarea>
</div>
<div class='field'>
<div class='g-recaptcha' data-callback='reCaptcha_general' data-sitekey='<my site key>'></div>
<input class='hiddenRecaptcha' id='gen_hiddenRecaptcha' name='gen_hiddenRecaptcha' type='hidden'>
<button class='ui primary large button' type='submit'>Send</button>
<a class='item' href='#top' rel='scrolltoanchor'>⬆</a>
</div>
<div class='ui error message'></div>
</form>
_footer partial yields the jQuery which I comment on as we step through:
I don't know why he used $('form').form({
instead of $('form').validate({
- Is this more recent jQuery? It picks up the 'empty' reCAPTCHA box though.
// form validation
//
$('form').form({
on: 'blur',
fields: {
<snip>
message: {
identifier: 'message',
rules: [{
type: 'empty',
prompt: 'Please enter your message'
}]
},
gen_hiddenRecaptcha: {
identifier: 'gen_hiddenRecaptcha',
rules: [{
gen_hiddenRecaptcha: { required: true },
type: 'empty',
prompt: 'Please check the reCAPTCHA check box'
}]
},
}
});
This appears to be getting the response (I can alert and see the response come out) and this correctly affects the semantic warning which goes away when the field is no longer empty.
var reCaptcha_general = function(response) {
$("#gen_hiddenRecaptcha").val(response);
};
And so below I think is the problem. With all fields completed, the submit button doesn't work. I may have confused two different approaches before and tried to solve the problem with both at the same time.
When the submit is clicked, this function is called, but nothing happens.
$('#formGeneral').submit(function(event) {
if (!grecaptcha.getResponse()) {
event.preventDefault(); //prevent form submit
grecaptcha.execute();
}
});
UPDATE: I have just this edited in place as I have not had any answers yet.
UPDATE2: In order not to skew the comments below (and bearing in mind at this time of writing no answers to the below questions are submitted), I updated the code and wanted to share this in case someone else gets tangled up in the same way.
Revising the google docs after seeing other questions warning of ensuring you validate the response token separately, the form element id is renamed to be clearer that it carries the response token payload:
<div class="g-recaptcha" data-callback="reCaptcha_general" data-sitekey="<site-key>">
<input class="hiddenRecaptcha" id="gen_recaptchaResponseToken" name="gen_recaptchaResponseToken" type="hidden">
and in the footer, and this javascript to output warnings if the message box or reCAPTCHA are empty:
$('form').form({
on: 'blur',
fields: {
message: {
identifier: 'message',
rules: [{
type: 'empty',
prompt: 'Please enter your message'
}]
},
gen_recaptchaResponseToken: {
identifier: 'gen_recaptchaResponseToken',
rules: [{
gen_recaptchaResponseToken: { required: true },
type: 'empty',
prompt: 'Please check the reCAPTCHA check box'
}]
},
}
});
I thus updated the call back function with the new HTML form element ID:
var reCaptcha_general = function(response) {
$("#gen_recaptchaResponseToken").val(response);
};
and finally removed the grecaptcha.getResponse() call completely as per suggestion:
$('#formGeneral').submit(function(event) {
});
and the form functions correctly. I think the reason why it does is because my form validation service (the very excellent liveform) have the secret I got when I signed up to the reCAPTCHA service with google. I've not heard back from them as yet confirming what they technically do on the backend, but as the form action POSTs to a liveformhq.com URL, at the least, I expect them to be hitting Google's siteverify API to confirm the reCAPTCHA response token is valid.
Questions:
Am I right in thinking that with the above, I'm using jQuery form validation to prevent the form from being submitted by parsing the empty-ness of the response from the reCAPTCHA, rather than relying on
grecaptcha.getResponse()
?If so, do I even need the
grecaptcha.getResponse()
call?Although, am I right thinking that it is more secure to rely on
grecaptcha.getResponse()
and just make the jQuery form processing for that form elementrequired: true
just to get the warning prompt for the user?