So, here’s what I’ve figured out…
The only real way to get the duplicate submissions from posting to the DB is to just replace the submit button with a loading image before running the AJAX request. I ended up ditching jqueryForm as after a little bit of reading (credit to High Intensity Design for the initial js the rest is based on). The stock jQuery $.ajax function does everything with a pretty clear syntax, and has truncated functions like $.load, $.post, etc. depending on how much complexity you want/need. Anyway, here’s my code:
$(function(){
$('#feedback').submit(function(event) {
/* stop the contact form from submitting normally */
event.preventDefault();
/* replace the submit button with a loading image to prevent multiple clicks and indicate the form is being processed */
$("#feedback input[type='submit']").replaceWith("/images/interface/colorbox/loading.gif");
/* send the form data using post and check the results for any errors*/
$.ajax({
url: "/contact/",
type: "post",
dataType: "html",
data: $(this).serialize(),
/* If there was some kind of an AJAX error, display an appropriate message or take some other action of your choice */
error: function(jqXHR, textStatus, errorThrown) {
displayAjaxMessage("Sorry, there was an error submitting your form. Please contact the Salon by phone for further assistance.");
},
/* parse the HTML returned by EE to see if they forgot to enter an email address or a message.
If so, the HTML will contain a specific error string we can match, and then we can display our own message */
success: function(data) {
if (data.match(/<title>Error<\/title>/)) {
//grab the error message
var error = $(data).find('ul li:first').text();
$("#output").empty();
$("#output").removeClass().addClass("error").html(error);
/* since the form has identified an error, we need the submit button back so the visitor can address the fields with errors and re-submit */
$("img.loading").replaceWith("<input type='submit' value='submit' />");
} else {
/* clear any error messages still showing in the output area and prep with success message */
$("#output").empty().hide();
$("#output").removeClass().addClass("success").text('Thank you! We have received your submission.');
/* clear fields now that the form has been successfully completed */
$("#feedback #contact_name, #feedback #contact_from, #feedback textarea, input[name='captcha']").val('');
/* now that we're done, and the fields have been cleared, return the submit button to the form */
$("img.loading").replaceWith("<input type='submit' value='submit' />");
/* display our success message */
$("#output").fadeIn("slow").delay(6000).fadeOut("slow", function() {
$(this).removeClass().html('');
});
}
}
});
});
});
Now this still doesn’t address what to do if someone tries to bypass the JS maliciously (or inject their own) to produce DB spam. There still needs to be some server-side mechanism for identifying duplicate entries. Ideally it would be a safecracker parameter which you could identify a field to use as a check; i.e. in the case of a contact form, you could check [contact_body] as that field should be unique from submission to submission.
I guess that makes this a feature request at this point. Perhaps we can migrate it there.
Hopefully the script above is helpful to anyone else trying to safely AJAX a form.