I'm trying to validate Google Captcha and my form, which currently does work. I'm using JQuery Forms and Validate Unobstructive. The problem is after submission, you can still submit the form as many times as you click.
Is there a way to ensure this only happens once?
I have tried using the following (commented in the code), but then you can't submit the form again to recheck the captcha:
if ($form.data('submitted') === true) { } else { }
JS:
$(document).ready(function () {
//Intercept Submit button in order to make ajax call instead of a postback
$('#contactForm').preventDoubleSubmission();
});
// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function () {
$("button").click('submit', function (e) {
e.preventDefault();
var $form = $("#contactForm");
$($form).bind("invalid-form.validate", function() {
if( $("invalid-form.validate") ) {
formErrors();
}
})
// if ($form.data('submitted') === true) {
// // Previously submitted - don't submit again
// } else {
if ($form.valid()) {
// Mark it so that the next submit can be ignored
$form.data('submitted', true);
if ( captchaCheck() == false) {
captchaCheck();
} else {
// Make ajax call form submission
$.ajax({
url: $form.attr('action'),
type: 'POST',
cache: false,
data: $form.serialize(),
success: function (result) {
success();
}
});
}
}
// }
});
// keep chainability
return this;
};
function hover() {
$(".contour-button").on("mouseenter", function() {
return $(this).addClass("hover");
});
}
function hoverOff() {
$(".contour-button").on("mouseleave", function() {
return $(this).removeClass("hover");
});
}
function success() {
$(".contour-button").addClass("success");
var formFields = $(".contactForm input, .contactForm textarea, .contactForm button");
$(formFields).attr('disabled', 'disabled');
$(formFields).animate({'opacity':'0.5'});
$(".contour-btn-arrow").addClass("contour-btn-success");
$(".contour-button .submit").html("Thank you for your enquiry");
}
function formErrors() {
$(".contour-button").addClass("form-errors").delay(3500).queue(function(){
$(this).removeClass("form-errors").dequeue();
});
$(".contour-btn-arrow").addClass("contour-btn-error").delay(3500).queue(function(){
$(this).removeClass("contour-btn-error").dequeue();
});
$(".contour-button .submit").html("There are errors on the form").delay(3500).queue(function(){
$(this).html("Submit").dequeue();
});
}
function captchaCheck() {
var captchaResponse = grecaptcha.getResponse();
if(captchaResponse.length == 0) {
// html for the captcha error message
var captchaMsgHtml = '<img src="/images/form-error-icon.png" /> Please check the captcha and try again';
$("#captchaMsg").html(captchaMsgHtml).slideDown(500);
$(".g-recaptcha div div").addClass("recaptchaHighlight");
return false;
} else {
$(".g-recaptcha div div").removeClass("recaptchaHighlight")
$("#captchaMsg").hide();
return true;
}
}
hover();
hoverOff();
I managed to solve this in a similar way to MonkeyZeus's suggestion by wrapping the AJAX call in a condition, using a bool (true/false).
var ajaxRunning = false;
$("button").click('submit', function (e) {
e.preventDefault();
var $form = $("#contactForm");
$($form).bind("invalid-form.validate", function() {
if( $("invalid-form.validate") ) {
formErrors();
}
})
if ($form.valid()) {
if ( captchaCheck() === false) {
captchaCheck();
formErrors();
} else {
if(!ajaxRunning){
ajaxRunning = true;
$.ajax({
url: $form.attr('action'),
type: 'POST',
cache: false,
data: $form.serialize(),
success: function (result) {
success();
},
error: function (result) {
captchaCheck();
formErrors();
}
});
}
}
}
});
function hover() {
$(".contour-button").on("mouseenter", function() {
return $(this).addClass("hover");
});
}
function hoverOff() {
$(".contour-button").on("mouseleave", function() {
return $(this).removeClass("hover");
});
}
function success() {
var disabledElements = "#formFooter button, .contourField input, .contourField textarea";
var opacityElements = ".contourField input, .contourField textarea";
// disable button & inputs once submitted
$(disabledElements).attr('disabled', 'disabled');
// change opacity of elements
$(opacityElements).animate({ 'opacity' : '0.5' });
$(".contour-button").addClass("success");
$(".contour-btn-arrow").addClass("contour-btn-success");
$(".contour-button .submit").html("Thank you for your enquiry");
}
function formErrors() {
$(".contour-button").addClass("form-errors").delay(3500).queue(function(){
$(this).removeClass("form-errors").dequeue();
});
$(".contour-btn-arrow").addClass("contour-btn-error").delay(3500).queue(function(){
$(this).removeClass("contour-btn-error").dequeue();
});
$(".contour-button .submit").html("There are errors on the form").delay(3500).queue(function(){
$(this).html("Submit").dequeue();
});
}
function captchaCheck() {
var captchaResponse = grecaptcha.getResponse();
if(captchaResponse.length == 0) {
// html for the captcha error message
var captchaMsgHtml = '<img src="/images/form-error-icon.png" /> Please check the captcha and try again';
$("#captchaMsg").html(captchaMsgHtml).slideDown(500);
$(".g-recaptcha div div").addClass("recaptchaHighlight");
return false;
} else {
$(".g-recaptcha div div").removeClass("recaptchaHighlight")
$("#captchaMsg").hide();
return true;
}
}
hover();
hoverOff();