Recently, we came across an issue where we were using the Mail (2) setting to send an automated email to a user who submits the form with an attachment. The issue was that this attachment was a 2MB file, so before you see the success message, you have to wait for the attachment to be sent which can take a bit of time. Because of this, users end up submitting the forms various times causing multiple submits and emails send to both parties (Especially when using a 3rd party SMTP host like SendGrid or MailGun).
Here is the method we used to prevent this sort of action which can simply be added to your functions.php file to be called on each page.
<?php
// Prevent Multi Submit on all WPCF7 forms
add_action( 'wp_footer', 'prevent_cf7_multiple_emails' );
function prevent_cf7_multiple_emails() {
?>
<script type="text/javascript">
var disableSubmit = false;
jQuery('input.wpcf7-submit[type="submit"]').click(function() {
jQuery(':input[type="submit"]').attr('value',"Sending...");
if (disableSubmit == true) {
return false;
}
disableSubmit = true;
return true;
})
var wpcf7Elm = document.querySelector( '.wpcf7' );
wpcf7Elm.addEventListener( 'wpcf7_before_send_mail', function( event ) {
jQuery(':input[type="submit"]').attr('value',"Sent");
disableSubmit = false;
}, false );
wpcf7Elm.addEventListener( 'wpcf7invalid', function( event ) {
jQuery(':input[type="submit"]').attr('value',"Submit")
disableSubmit = false;
}, false );
</script>
<?php
} ?>
What the above will do is change the text of the forms submit button to ‘Sending…’ and disable any further clicks until the message is delivered. Once the message is delivered, the submit button will change to ‘Sent’.
In addition to this, if there are any errors in the form, we can use the wpcf7invalid
DOM Event which we can use to change the value of the submit button back to the original value; in our case, we changed it back to ‘Submit’.
In our case, we had pages with multiple forms and only needed this to be added to one of the forms on the website. To do this, you can view the page source and get the ID attribute for the form (e.g. #wpcf7-f4-o1), and simply add this before each of the selectors, like so; jQuery('#wpcf7-f4-o1 :input[type="submit"]')
There are other ways of doing this such as using a preloader on submit but our particular client was pretty happy with the solution we provided him with.
Feel free to leave a comment below if this has helped or if you have another preferred method of performing such a task.
hi, thanks for the script. Unfortunately it doesn’t work perfectly on desktop. But on mobile it doesn’t work. If I try to send a form with wrong fields, the key remains on “SENDING …” and it does not give the possibility to resend the form. How can I fix it?
Hi Livio,
Okay to do that, simply add the following code at the end above the
</script>
tag:Just change the value
Submit
to what you want the button text to be if there are validation errors.We use the
wpcf7invalid
DOM event which only triggers if there is validation errors.Hope that helps!
Hi! When I add your code to my funcions.php file the whole site crashes.
Can you share the error you are getting please?
Thank you a lot! I will test it!!!
but is it possible to completely hide the button while the form is being submitted?
Hi Livio,
Yes, that was my mistake, you can simply change the hook for this to fix this issue.
Instead of using
wpcf7submit
, please change this towpcf7_before_send_mail
– This will resolve the issue since this will only be triggered when the mail is successfully delivered as opposed to it being triggered on click without validation.I will update the article now, thanks!
I’m using Material Design forms and it doesn’t seem to work with that. Any ideas?
It’s difficult to say, do you have a link or any console errors?
Ciao, grazie per lo script. Utilizzato in uno dei miei siti e funziona correttamente!
Glad it worked! Forza Italia in the EURO 2020 amico!
Thank you so much, I’ve been searching for this for weeks. It works!
Although, after sending the mail, the button continues to say ‘Sending’. Shouldn’t it revert back to being ‘Submit’, or something similar?
I added the code you suggested to the other reviewer and somehow it doesn’t do anything. 😀
But, I’ll continue to use the code. It’s infinitely better than the default CF7.
// Prevent Multi Submit on all WPCF7 forms
add_action( ‘wp_footer’, ‘prevent_cf7_multiple_emails’ );
function prevent_cf7_multiple_emails() {
?>
var disableSubmit = false;
jQuery(‘input.wpcf7-submit[type=”submit”]’).click(function() {
jQuery(‘:input[type=”submit”]’).attr(‘value’,”Sending…”);
if (disableSubmit == true) {
return false;
}
disableSubmit = true;
return true;
})
var wpcf7Elm = document.querySelector( ‘.wpcf7’ );
wpcf7Elm.addEventListener( ‘wpcf7_before_send_mail’, function( event ) {
jQuery(‘:input[type=”submit”]’).attr(‘value’,”Sent”);
disableSubmit = false;
}, false );
wpcf7Elm.addEventListener( ‘wpcf7invalid’, function( event ) {
jQuery(‘:input[type=”submit”]’).attr(‘value’,”Submit”)
disableSubmit = false;
}, false );
wpcf7Elm.addEventListener( ‘wpcf7invalid’, function( event ) {
jQuery(‘#wpcf7-f549-o1 :input[type=”submit”]’).attr(‘value’,”Submit”)
disableSubmit = false;
}, false );
Hmmm, it should revert back, are you still having issues, I can have a look into this for you.
Couldn’t get it to work on my site, but I noticed that the DOMs didn’t match the DOM events on the Contact Forms website https://contactform7.com/dom-events/
Changed the addEventListener to listen to the other DOMs and it worked. Here’s the changes:
var disableSubmit = false;
jQuery(‘input.wpcf7-submit[type=”submit”]’).click(function() {
jQuery(‘:input[type=”submit”]’).attr(‘value’,”Sending…”);
if (disableSubmit == true) {
return false;
}
disableSubmit = true;
return true;
})
var wpcf7Elm = document.querySelector( ‘.wpcf7’ );
wpcf7Elm.addEventListener( ‘wpcf7mailsent’, function( event ) {
jQuery(‘:input[type=”submit”]’).attr(‘value’,”Sent”);
disableSubmit = false;
}, false );
wpcf7Elm.addEventListener( ‘wpcf7mailfailed’, function( event ) {
jQuery(‘:input[type=”submit”]’).attr(‘value’,”Submit”)
disableSubmit = false;
}, false );
All examples on this page are not working with latest contact form 7 version.
Anyone can provide a working example ?
Thank you!
Have this issue too, keep as sending message after succesfull submit…
if you want to revert back to submit after sending the mail, then you can add the following code to implement it
wpcf7Elm.addEventListener( ‘wpcf7submit’, function( event ) {
let res = event.detail;
if(“mail_sent” === res.status)
{
jQuery(‘:input[type=”submit”]’).attr(‘value’,”Submit”)
disableSubmit = false;
}
}, false );
Hi,
Thanks for your code, it really works!
Greetings from Russia…
if we get two submission count of contact from 7 then can we hide contact form7?
I’m not following you here, can you elaborate, please.
I’ve tried implementing this on a website, but it is not working at all. I think it may be because the CF7 instance is in a popup, not on the page that loads. At guatemaladental.com, there is a popup that loads after 8 seconds. After clicking on ‘learn more’ a second popup appears with the form. After clicking the submit button (‘request info’) the button is not disabled, the text doesn’t change; nothing happens. This leads to site visitors clicking a second or even third time and thus sending 2 or 3 submissions. Any help would be appreciated.