How to create a mail counter for Contact Form 7

Here’s an easy way to set up a counter for your contact form using Contact Form 7 and Contact Form 7 Dynamic Text Extension. Basically, we’re setting up an action that will increment a counter each time an email is sent. We’re grabbing that count and placing it in the email using CF7 DTX.

Add the functional code

First, here’s the code to add (anywhere, but functions.php works well. It’ll be added to CF7 DTX some time down the road hopefully).

//Define the key to store in the database
define( 'CF7_COUNTER', 'cf7-counter' );

//Create the shortcode which will set the value for the DTX field
function cf7dtx_counter(){
    $val = get_option( CF7_COUNTER, 0) + 1;  //Increment the current count
    return $val;
}
add_shortcode('CF7_counter', 'cf7dtx_counter');

//Action performed when the mail is actually sent by CF7
function cf7dtx_increment_mail_counter(){
    $val = get_option( CF7_COUNTER, 0) + 1; //Increment the current count
    update_option(CF7_COUNTER, $val); //Update the settings with the new count
}
add_action('wpcf7_mail_sent', 'cf7dtx_increment_mail_counter');

Configure the Contact Form

Next, we set up our contact form. We’re going to add a new hidden dynamic field to it using CF7 DTX and the new shortcode we just wrote. Here’s what that code would look like in the Contact Form 7 Form Settings:

[dynamichidden cf7-counter "CF7_counter"]

Finally, we want to include the count in the message we receive, so we’ll add it to the CF7 Message Body field:

Count: [cf7-counter]

Some Notes

  • The counter only increments when the mail is actually sent. Form loads and failed sends won’t trigger the count to increase.
  • If two contact forms are submitted without reloading the page, the count will be incremented properly, but it won’t be reflected in the email. This is because the count that is sent in the email is only updated when the page loads. To update it without a page load, you’d need to write some JS that hooks into CF7’s send callbacks.

That’s about it – enjoy! Let me know in the comments if you find this useful (or run into any trouble).

46 thoughts on “How to create a mail counter for Contact Form 7

  1. Hello there!
    First of all, amazing! Thanks for the post! It is just what I’d been looking for!

    The problem I got is that I’m very newbie with this wordpress and php so I struggle a bit with the instructions you posted, hope you can help me better understand the next:

    1. When you said to include the code in the functions.php is it on the plugin of the theme functions?
    2. Is it just to paste the code or do I need to add something else? Something as at the end or if and endif or something else?
    3. What about the code that goes into the form? I’ve just paste it as it is and it appear at the form as part of the text.

    I’m very sorry if my questions are to basic or with obvious answers… I’m really trying to learn fast.

    Thanks in advance for your answer!

    • Hi Avi,

      1. You can put the PHP anywhere, really. As CF7 DTX doesnโ€™t have a functions.php, the tutorial is referring to your theme. But putting it in the main DTX plugin file would work fine as well.

      2. Just paste that code at the end of the file. Make sure itโ€™s inside the

  2. Is it possible to post the counter results to a ticker on my site itself?

    Here’s what I’m trying to do:
    I’m having people submit a form telling me their pledges for a volunteer campaign. When they submit their volunteer project your counter will count the number of volunteers based on how many form submissions there are. Instead of/in addition to the number being posted only in the submitted form I’d like to have a counter at the top of my site that says, “__ Volunteers!”.

    Any ideas? Thanks!

    • Yup, that’d be easy. The value is already stored in the DB. So you’d just do this:

      Volunteers!

      You could also use the shortcode

      [CF7_counter]

      but it’ll be off by 1 in its current state (1 extra).

      Hope that helps,

      Chris

  3. Hey Chris,

    Probably a dumb problem but the counter isn’t working. In the email the form sends it just says “Count: CF7_counter ” and doesn’t reflect that an email has been submitted and therefore the number should be at least 1.

    I also followed your directions about posting it on my site as well and it just says 0 Volunteers. any ideas?

    Thanks!

  4. Sorry Chris, somehow the code got deleted from my functions.php file. I knew it was probably my fault.

    Is there any way to use this code with a counter image like a flip counter instead of a text counter?

    Thanks!

    • Yup, that’s what I was going to suggest – when the shortcode’s name is printed rather than the value, it indicates that the shortcoded isn’t registered (i.e. the code is missing).

      As for using an image, the code above provides the value, so I would just wrap it in a div and style that div. For an easy solution, grab an image like this one, set it as the background image, and then style the font appropriately. Or you could use some CSS3 styles to make the div look like a flip counter so that the width would be dynamic.

      Chris

  5. hmm. I guess I”m not very php savvy ๐Ÿ™

    I had everything working fine but I then WordPress started giving me an error every time I tried to update or save something from the admin. Then I realized that the message started after I put the code in the functions.php file. I thought I must have placed it somewhere funny and it was causing the error so I took it out and re-ftped my functions.php file.

    Didn’t help, I’m still getting this error: “Warning: Cannot modify header information – headers already sent by (output started at /homepages/43/d334710590/htdocs/wp-content/themes/Glider/functions.php:33) in /homepages/43/d334710590/htdocs/wp-includes/pluggable.php on line 934”

    Any ideas what I should do to get rid of the error and also how I can place the code so I don’t cause errors??

    Thanks for all your help.

    • It sounds like you may have pasted the PHP code outside the PHP tags (looks like you might’ve put it before the opener). I think the best place for it is at the end of the file, but before the closing ?> tag.

  6. I placed it where you suggested and I’m getting the error again. Is there any other file I can put it in?

    Here’s my code by the way:

     
            
    		<li id="comment-"> - 
    	
    • Without seeing the issue firsthand Iโ€™m just taking shots in the dark here. If the error is identical (line number) after moving the code, then that code is not the issue. If the code is added properly to the functions.php file, it doesnโ€™t produce errors.

      Your error indicates that something is being printed before the headers are being sent. That means you either have some PHP code outside the PHP tags, or a function is echoing code too early, or an error is occurring and outputting error text. Note that the code above does not print anything.

      The code you pasted above didnโ€™t come through. You may want to use pastebin.

    • I think your issue is just the line break and space at the end of the file (these are considered printed characters).

      Your simplest solution is just to delete the ?> at the end of the file. Hopefully that’ll do it ๐Ÿ™‚

  7. Hi, Just used your counter code and it works perfectly. Only one question how/where do you reset the counter number or set some kind of a offset. I would like it to start counting from 1000 but currently it is counting from 20 and onwards.

    /Usman

    • Looks like you’ve already figured this out, but you’d just want to adjust the count manually in the wp_options table by changing the cf7-counter to 1000, then it’ll count up from there.

  8. Hi,

    first of all thanks for the code it works perfect. i have only one questions. It seems like that when you have filled out the form first time the counter counts but if you again fill out the form without refreshing the page the counter does not count. I can see the new entry in the db and the email is also sent but counter stays on the same number. Can this be fixed somehow? right now you have to refresh og browse the page again before it counts again…

    • Yes, I’m aware of this and it is noted in the original post under “Some Notes”:

      If two contact forms are submitted without reloading the page, the count will be incremented properly, but it wonโ€™t be reflected in the email. This is because the count that is sent in the email is only updated when the page loads. To update it without a page load, youโ€™d need to write some JS that hooks into CF7โ€ฒs send callbacks.

      I don’t see it as a very common scenario, but that’s what you’d need to do if it was important to your functionality.

      Chris

  9. Hi Chris,

    Hmmm i am not so good at wirting code. i have installed a cf7 db plugin and can see that the count number is also not increased here. But somehow it sill counts becuase when you then reload the page then it shows the correct number for that specific mail. isnt it possible to somehow just reload the page when you press the submit button??

    /Usman

    • Well, Contact Form 7 uses an AJAX contact form, so there is no page reload. I believe if you remove the javascript that it’ll fall back to a normal submission form (with page reload), but I don’t know of a graceful way to do that.

      Otherwise, you’d need to have a script that updates the counter. I’m not sure if there is a CF7 event that you can attach it to, however. The function itself would just increment the counter field in the form.

  10. Hi! Thanks for your code, its works like charm!!

    I just wondering if there is a way to set different counters for 2 or more different contact forms.

    Thanks!!

    • Hi Vincent,

      Glad it helped you out!

      To use two counters, you’d need to store two different options in the DB. What you’d want to do would be to set up the shortcode to accept a variable which you could append to the option ID to create multiple options. Off the top of my head, something like:


      //Define the key to store in the database
      define( 'CF7_COUNTER', 'cf7-counter' );

      //Create the shortcode which will set the value for the DTX field
      function cf7dtx_counter($atts){
      extract( shortcode_atts( array(
      'counter_id' => '',
      ), $atts ) );
      $val = get_option( CF7_COUNTER . $counter_id, 0) + 1; //Increment the current count
      return $val;
      }
      add_shortcode('CF7_counter', 'cf7dtx_counter');

      And the tag would look like:


      [dynamichidden cf7-counter "CF7_counter counter_id='1' "]

      However, then you’d need to also include a hidden field in the form with the counter ID, and adjust the mail_sent action to update the appropriate counter ID, which would require a bit more complexity.

      Hope that helps ๐Ÿ™‚

      Chris

  11. THAT IS AMAZING!
    Thanks for your help!
    But I am a newbie in php…
    at the ‘mail_sent action’
    can I adjust like this:

    function cf7dtx_increment_mail_counter($atts){
    $val = get_option( CF7_COUNTER . $counter_id, 0) + 1; //Increment the current count
    update_option(CF7_COUNTER . $counter_id, $val); //Update the settings with the new count
    }
    add_action(‘wpcf7_mail_sent’, ‘cf7dtx_increment_mail_counter’);


    is this the right way..?

    2. I wondering if i can set a table name(or a form name) like ‘ABC’ in different contact form and get the name to put infront of every counter . The result might be like ” ABC1, ABC2,ABC3″….

    I think this function could be fixed if I learn some PHP, but I’ve try very hard and test again and again…comes out lots of different problems….drive me crazy…

    Thanks for your help!

  12. i got this to work sweet. what i really want is a text counter that is displayed on the form page and counts down every time a submission is made.

    Ie: people are registering for a sample and with each submission the amount of sample left decreases so that the next person know there are only 95 left.

    I am using wordpress and contact form 7 and DTX

    • I think you could accomplish that by setting the ‘0’ to your initial amount (+1) and subtracting instead of adding (in both functions). Basically:

      $val = get_option( CF7_COUNTER, 95) - 1;

      Hope that helps!

  13. Hi, your plugin is amazing.

    im using it to develop an online booking system for a domestic appliance company, it is my final year project at uni. I need to use the counter to develop id numbers for customer along with using a second counter to devlop booking ids,
    how ever i cant seem to get the first counter to strt back from 0 and also if the second counter form is submitted the first counter adds on 1 2, my code is shown below. please help me as i am struggling to fix this and havnt got much time before my deadline at uni ๐Ÿ™

    my code is this atm:

    //Define the key to store in the database
    define( ‘CF7_COUNTER’, ‘cf7-counter’ );

    //Create the shortcode which will set the value for the DTX field
    function cf7dtx_counter(){
    $val = get_option( CF7_COUNTER, 000) + 1; //Increment the current count
    return $val;
    }
    add_shortcode(‘booking_ID’, ‘cf7dtx_counter’);

    //Action performed when the mail is actually sent by CF7
    function cf7dtx_increment_mail_counter(){
    $val = get_option( CF7_COUNTER, 0) + 1; //Increment the current count
    update_option(CF7_COUNTER, $val); //Update the settings with the new count
    }
    add_action(‘wpcf7_mail_sent’, ‘cf7dtx_increment_mail_counter’);

    //Define the key to store in the database
    define( ‘CF7_COUNTER’, ‘cf7-counter’ );

    //Create the shortcode which will set the value for the DTX field
    function cf7dtx1_counter($atts){
    extract( shortcode_atts( array(
    ‘counter_id’ => ‘1’,
    ), $atts ) );
    $val = get_option( CF7_COUNTER . $counter_id, 100) + 1; //Increment the current count
    return $val;
    }
    add_shortcode(‘CF7_counter’, ‘cf7dtx1_counter’);

    • Hi Mohammed,

      I think the issue is that you have defined the same counter/key twice. the second time should be something like

      define( โ€˜CF7_COUNTER_1โ€™, โ€˜cf7-counter-1โ€™ );

      And then use that CF7_COUNTER_1 appropriately within your functions.

      Hope that helps, good luck with your project! ๐Ÿ™‚

      Chris

  14. Hi Chris

    Thanks for your response,
    I did as you said and ive still got the same problem the first counter is still counting however now the second conunter isnt increasing just staying at 1. my code now in functions.php looks lioke this:

    //Define the key to store in the database
    define( ‘CF7_COUNTER’, ‘cf7-counter’ );

    //Create the shortcode which will set the value for the DTX field
    function cf7dtx_counter(){
    $val = get_option( CF7_COUNTER, 000) + 1; //Increment the current count
    return $val;
    }
    add_shortcode(‘booking_ID’, ‘cf7dtx_counter’);

    //Action performed when the mail is actually sent by CF7
    function cf7dtx_increment_mail_counter(){
    $val = get_option( CF7_COUNTER, 0) + 1; //Increment the current count
    update_option(CF7_COUNTER, $val); //Update the settings with the new count
    }
    add_action(‘wpcf7_mail_sent’, ‘cf7dtx_increment_mail_counter’);

    //Define the key to store in the database
    define( ‘CF7_COUNTER_1’, ‘cf7-counter-1’ );

    //Create the shortcode which will set the value for the DTX field
    function cf7dtx1_counter($atts){
    extract( shortcode_atts( array(
    ‘counter_id’ => ‘1’,
    ), $atts ) );
    $val = get_option( CF7_COUNTER_1 . $counter_id, 0) + 1; //Increment the current count
    return $val;
    }
    add_shortcode(‘CF7_counter_1’, ‘cf7dtx1_counter’);

    //Action performed when the mail is actually sent by CF7
    function cf7dtx1_increment_mail_counter(){
    $val = get_option( CF7_COUNTER_1, 0) + 1; //Increment the current count
    update_option(CF7_COUNTER_1, $val); //Update the settings with the new count
    }
    add_action(‘wpcf7_mail_sent’, ‘cf7dtx1_increment_mail_counter’);

    please can you help me resolve this issue as im very behind ๐Ÿ™ im really sorry for all the questions
    also i need to start the first counter back from 1. how do i do that?
    thank you so much

    • You’re appending $counter_id to the constant in cf7dtx1_counter, but not setting that anywhere else. I’m not really clear what you’re trying to accomplish. I’m sorry, but I myself am extremely busy and unfortunately I can’t help you out with this right now.

      You might try posting on the wordpress.org forums, or on the WordPress stack exchange.

      Best of luck with your project,

      Chris

  15. what i was tryin to accomplish was have to counters, for two seprate forms, but when i use the method of two counters when one form is submitted the counter increases on both :s im sorry i know u said ur busy but noone has got bak to me on the wordpress forum and im really struggling im really sorry.

    • This issue is going to be that both actions are fired on every form submit. You’ll need a way to test for which form is submitted and update the appropriate counter.

      Sorry, unfortunately right now I don’t have any time to go into more detail than that.

      Best of luck,

      Chris

  16. Great tutorial, and I managed to get it working too. Thank you, however, if you get a chance would you be able to put together another tutorial on how to have multiple counters for multiple forms? I am currently running a site which has 52 forms, and would really like a counter of each form submission. I too have posted in the wordpress support forum, but have not had any response. Would really appreciate it.

    Kind Regards,

    Dan

    • Hi Dan,

      Thanks ๐Ÿ™‚ The issue you’re going to run into is that all functions added to the wpcf7_mail_sent action will fire on every form submission. So there’ll have to be a way to distinguish which form is being submitted to increment the proper counter. Probably the best solution would be to submit the counter’s database option key as a hidden field within that form, which would then be incremented in a catch-all incrementation function attached to the wpcf7_mail_sent action.

      Hope that helps! If I get some time I’ll try to write that up in more detail.

      Best,

      Chris

  17. Hi Everyone,

    Just thought I would let you know that I have found a way to add an individual counter for multiple forms. Download and install ‘Contact Form 7 to Database Extension’ plugin. This plugin submits each form entry to the database (allowing you to view all of the submissions in the Admin dashboard), and also has many built in shotcodes. The one for adding a counter to a form is [cfdb-count form=”Form Name Here”].

    Hope this helps.

    Cheers,

    Dan

  18. hi Buddy,

    i am also a newbie with these things….i am trying to put “i am interested” tabs in every coupon on my coupon site, on hitting which would ask for a contact detail form and when the form is filled up(including telephone number, email id, and name) after the contact form submission i need the counter to increment value by 1, and as i said there will be multiple coupons and “i am interested” tabs for every coupon….please tell me if this code can be used for this purpose…….your patience and help is highly regarded and respected.

    • Hi rishabh,

      Yes, but the counter is global. You’d have to make some customizations if you wanted to save a separate count for each coupon.

      Best,

      Chris

  19. Hi there,
    First of all thanks for your code. I’m using cf7 ajax form. As you said i’m updating the counter value using a js when the form is submitted which was added to the cf7 hook,
    on_sent_ok: “update_counter();”
    Everything was working perfect, but some times the value duplicates like
    64, 65, 65, 66, 67 …
    Here you can see 65 appears twice. Do you have any idea why this happens?

  20. Thanks for a nice plugin(TFANP), Dynamic Text Extension.
    How can I set the counter to start e.g on the number 1000 instead of 0?
    /LJ

  21. hi! I am looking for solution to my requirement that I want to count submissions via Contact form 7. I want total number of submissions (with custom wordings – such as “Your customer Number is –counted number e.g. 101”) on the page that would display after submission.
    I want this counting number to be sent to my email also along with form information. Like: Name: email: etc. + Customer number (Counted Number e.g. 101).
    Help me in this regard.

Comments are closed.