Following a redesign of the site, and after upgrading a plugin or two, I noticed a Javascript error with the newest version of Contact Form 7. After some Googling, I realised I wasn’t alone.
It seems mainly to be a problem if you’re using AJAX or a javascript library like smoothState.js on your site. You can run in to trouble when submitting forms or navigating between pages containing Contact Form 7 forms.
The problem is that the wpcf7.initForm method is called before it is available to us. This is because it is a function expression and function expressions are only available at or after the point that they are declared in the code.
Fixing Contact Form 7
Fortunately, the fix is pretty simple, but it involves editing the plugin’s scripts.js file, so you’ll need to switch that out whenever WPCF7 receives an update or at least until the plugin author accepts this change as a pull request.
On line 14 of the plugins/contact-form-7/includes/scripts.js, we have the following code:
$(function() {
wpcf7.supportHtml5 = ( function() {
var features = {};
var input = document.createElement( 'input' );
features.placeholder = 'placeholder' in input;
var inputTypes = [ 'email', 'url', 'tel', 'number', 'range', 'date' ];
$.each( inputTypes, function( index, value ) {
input.setAttribute( 'type', value );
features[ value ] = input.type !== 'text';
} );
return features;
})();
$( 'div.wpcf7 > form' ).each( function() {
var $form = $( this );
wpcf7.initForm( $form ); // here's the problem
if ( wpcf7.cached ) {
wpcf7.refill( $form );
}
} );
});
This whole code block needs to move to the bottom of the document.ready function, after the wpcf7.apiSettings.getRoute method that ends on line 507. Like this:
// code above
wpcf7.apiSettings.getRoute = function( path ) {
var url = wpcf7.apiSettings.root;
url = url.replace(
wpcf7.apiSettings.namespace,
wpcf7.apiSettings.namespace + path );
return url;
}; // line 507
// our original code block, now at the bottom
$(function() {
wpcf7.supportHtml5 = ( function() {
var features = {};
var input = document.createElement( 'input' );
features.placeholder = 'placeholder' in input;
var inputTypes = [ 'email', 'url', 'tel', 'number', 'range', 'date' ];
$.each( inputTypes, function( index, value ) {
input.setAttribute( 'type', value );
features[ value ] = input.type !== 'text';
} );
return features;
})();
$( 'div.wpcf7 > form' ).each( function() {
var $form = $( this );
wpcf7.initForm( $form );
if ( wpcf7.cached ) {
wpcf7.refill( $form );
}
} );
});
} )( jQuery ); // end of document.ready function
Contact Form 7 will now work as expected on your AJAX-powered site without throwing the wpcf7.initForm is not a function error.