Running a custom function if Contact Form 7 returns an invalid field on AJAX submit

I’m using the WordPress plugin Contact Form 7 and I need to manipulate some data if there is an error on a specific field, not sure if this can be done with hooks or anything as I need to run some JavaScript code and not PHP, so I’m assuming I would need to attach a onclick event when the user attempts to submit the form?

If it can be done with a hook someway I assume it would be done with this one.

Read More

If it can be done with a hook, what is the best way to achieve this? If not, I guess it would be easy enough to attach an onclick event to the button, but I’m unsure how I can get it to run only if there is a validation error and after the CF7 JS code has already run?

The HTML of the form:

<div role="form" class="wpcf7" id="wpcf7-f1304-p10-o1" lang="en-US" dir="ltr">
    <div class="screen-reader-response"></div>
    <form name="" action="/freetrademarksearch/#wpcf7-f1304-p10-o1" method="post" class="wpcf7-form" enctype="multipart/form-data" novalidate="novalidate">
        <div style="display: none;">
            <input type="hidden" name="_wpcf7" value="1304" />
            <input type="hidden" name="_wpcf7_version" value="4.1.2" />
            <input type="hidden" name="_wpcf7_locale" value="en_US" />
            <input type="hidden" name="_wpcf7_unit_tag" value="wpcf7-f1304-p10-o1" />
            <input type="hidden" name="_wpnonce" value="a2009d4694" />
        </div>
        <div class="field_wrapper">
            <p class="title">Trademark to be searched</p>
            <div class="field">
                <span class="wpcf7-form-control-wrap trademark"><input type="text" name="trademark" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control" aria-required="true" aria-invalid="false" /></span>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">Upload Logo <span class="optional">(optional)</span></p>
            <div class="field">
                <div class="btn browse_btn">
                    <span class="wpcf7-form-control-wrap logo"><input type="file" name="logo" value="1" size="40" class="wpcf7-form-control wpcf7-file" aria-invalid="false" /></span>
                </div>
                <div class="wp_is_annoying">
                    <span id="upload_filename" class="file_chosen">No file selected</span>
                </div>
                </p>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">Goods/Services the trademark is, or will be, used to identify</p>
            <div class="field">
                <span class="wpcf7-form-control-wrap identify"><input type="text" name="identify" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control" aria-required="true" aria-invalid="false" /></span>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">If you already promote this in Australia, what was the first date of promotion?</p>
            <div class="field">
                <span class="wpcf7-form-control-wrap date-promoted"><input type="text" name="date-promoted" value="" size="40" class="wpcf7-form-control wpcf7-text form-control" aria-invalid="false" /></span>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">Has promotion been continuous since the above date?</p>
            <div class="field radio_btns">
                <div class="holder">
                    <span class="wpcf7-form-control-wrap continuous_promotion"><span class="wpcf7-form-control wpcf7-radio" id="yes_continuous_promotion"><span class="wpcf7-list-item first last"><label><input type="radio" name="continuous_promotion" value="Yes" />&nbsp;<span class="wpcf7-list-item-label">Yes</span></label></span></span></span>
                </div>
                <div class="holder">
                    <span class="wpcf7-form-control-wrap continuous_promotion"><span class="wpcf7-form-control wpcf7-radio" id="no_continuous_promotion"><span class="wpcf7-list-item first last"><label><input type="radio" name="continuous_promotion" value="No" />&nbsp;<span class="wpcf7-list-item-label">No</span></label></span></span></span>
                </div>
                </p>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">Full Name</p>
            <div class="field half">
                <span class="wpcf7-form-control-wrap first-name"><input type="text" name="first-name" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required first form-control" aria-required="true" aria-invalid="false" placeholder="First Name" /></span><span class="wpcf7-form-control-wrap last-name"><input type="text" name="last-name" value="" size="40" class="wpcf7-form-control wpcf7-text form-control" aria-invalid="false" placeholder="Last Name" /></span>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">Email Address:</p>
            <div class="field">
                <span class="wpcf7-form-control-wrap email"><input type="email" name="email" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-email wpcf7-validates-as-required wpcf7-validates-as-email form-control" aria-required="true" aria-invalid="false" /></span>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">Phone Number:</p>
            <div class="field">
                <span class="wpcf7-form-control-wrap phone"><input type="text" name="phone" value="" size="40" class="wpcf7-form-control wpcf7-text form-control" aria-invalid="false" /></span>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">Comment: <span class="optional">(optional)</span></p>
            <div class="field">
                <span class="wpcf7-form-control-wrap comments"><textarea name="comments" cols="40" rows="10" class="wpcf7-form-control wpcf7-textarea form-control" aria-invalid="false"></textarea></span><br />
                <span class="wpcf7-form-control-wrap hello-wrap" style="display:none !important;visibility:hidden !important;"><input class="wpcf7-form-control wpcf7-text"  type="text" name="hello" value="" size="40" tabindex="-1" /><br><small>Please leave this field empty.</small></span>
            </div>
        </div>
        <div class="field_wrapper">
            <p class="title">How did you find us? <span class="optional">(optional)</span></p>
            <div class="field">
                <span class="wpcf7-form-control-wrap find-us"><input type="text" name="find-us" value="" size="40" class="wpcf7-form-control wpcf7-text form-control" aria-invalid="false" /></span>
            </div>
        </div>
        <div class="field_wrapper subscribe">
            <div class="field">
                <div class="td">
                    <span class="wpcf7-form-control-wrap newsletter"><span class="wpcf7-form-control wpcf7-checkbox" id="newsletter"><span class="wpcf7-list-item first last"><input type="checkbox" name="newsletter[]" value="yes" />&nbsp;<span class="wpcf7-list-item-label">yes</span></span></span></span>
                </div>
                <div class="td">
                    <label for="newsletter">I would like to receive newsletters from time to time.</label>
                </div>
                </p>
            </div>
        </div>
        <div class="field_wrapper submit">
            <div class="field">
                <input type="submit" value="Send" class="wpcf7-form-control wpcf7-submit btn" />
            </div>
        </div>
        <div class="wpcf7-response-output wpcf7-display-none"></div>
    </form>
</div>

Related posts

3 comments

  1. Possibly the easiest way to achieve this is to enqueue your scripts after Contact Form 7’s (via functions.php or your custom plugin), add a new function and bind it to DOMSubtreeModified, and check the form for errors.

    When validation fails, Contact Form 7’s AJAX function adds a span element with a class of wpcf7-not-valid-tip (as seen in the source).

    You can target this for your specific field, by doing something similar to the following:

    Example JS:

    (function($){
        $('div.wpcf7 > form').submit(function(){
            // The name of a single field you're interested in targeting 
            var fieldName = 'some-field-name';
    
            $(this).find('span.' + fieldName).bind('DOMSubtreeModified', function(event) {
                // If an error has been appended to this input's parent span, do something
                if ( $(this).children('.wpcf7-not-valid-tip').length ) {
                    // RUN YOUR FUNCTION HERE
    
                    // Prevent this function from running multiple times
                    $(this).off(event);
                }
            });
        });
    })(jQuery);
    

    Enqueue your scripts with, wpcf7_enqueue_scripts, to enqueue them after the default Contact Form 7 scripts (your path will likely be different):

    /**
     * Enqueue Scripts with CF7 Dependencies
     */
    function so30727367_enqueue_scripts() {
        wp_enqueue_script( 'stackoverflow-scripts', plugin_dir_url(__FILE__) . 'scripts.js', array('jquery'), null, true );
    }
    add_action( 'wpcf7_enqueue_scripts', 'so30727367_enqueue_scripts' );
    
  2. you can make use of form submition event:

    //attach handler on form submit
    var formID = "myForm";
    $('form#' + formID).submit(catchSubmit);
    

    then you will need stop form submission and you will post it yourself, file upload case as well included in this hook, as well response from server can be catch in JavaScript and handled:

    //custom handler for form submit
                        function catchSubmit(event) {
                            var uploadFileType = $('form#' + formID).attr('enctype') != undefined ? $('form#' + formID).attr('enctype').indexOf('multipart/form-data') != -1 ? true : false : false; //test if form has upload file functionality
                            event.preventDefault(); //stop html form post
                            if (uploadFileType) {
                                //ajax call for model + file upload
                                $.ajax({
                                    url: $(this).attr("action"),
                                    type: 'POST',
                                    data: new FormData(this),
                                    success: postSuccessHandler,
                                    processData: false,
                                    contentType: false
                                });
                                return;
                            }
                            else {
                                // ajax call for simple model/inputs
                                $.post($(this).attr("action"),
                                   $(this).serialize(),
                                   postSuccessHandler
                                   );
                            }
                        }
    

    and a post success handler where you can interpret your response for server:

    function postSuccessHandler(data) {
    //do something with returned html, json whatever
    }
    
  3. Here’s some code to get you started:

    $(function () {
        // Optional nice scroll function
        function scrollTop(myTop){
            var myTop = (typeof myTop==='undefined'||myTop === null) ? 150 : myTop;
            $("html, body").animate({
            scrollTop: myTop
            }, 300);
        }
        $('.wpcf7-form').submit(function(event){
            var valid = true;
            $('[aria-required]').each(function(i,ele){
                if(ele.value == ''){
                    $(this).parent().parent().addClass('alert');
                    console.log('Required field empty: '+ ele.name);
                    valid = false;
                }
            });
    
            // Handle additional validation here, set valid too false if it does not pass
    
            if (!valid){
                event.preventDefault();
                scrollTop();
                return false;
            }
            return true;
        });
    });
    

    EDIT:

    Or the on_sent_ok: “doFunction();” Link

    Or you could just see if the form has an error on page load:

    $(function () {
        function checkErrors(){
            var invalid = $('.wpcf7-form').hasClass('invalid');
            var error = $('.wpcf7-form').hasClass('error');
            if (!invalid && !error) {
                return true;
            }
            return false;
        }
        checkErrors();
    });
    

Comments are closed.