+91 9952732367

Custom AJAX contact form without plugin in wordpress

In this tutorial i have explained how to create and use custom AJAX contact form inside your theme.

Why Custom contact form?

 Today lot of plugins available to develop dynamic contact forms, sometimes that plugins not support for our client customization. That time our own contact form will help us do all customization’s.


  Take one example that you have custom post type products, contact form needed for particular product enquiry(Enquiry details to be sent admin email(s))

Create Custom Post type Product:

To create custom post type product we have to add this code inside functions.php

$labels = array(
 'name' => __( 'Products', 'Product' ),
 'singular_name' => __( 'Products', 'Product' ),
 'all_items' => __( 'All Products', 'Product' ),
 'add_new' => __( 'Add New Product', 'Product' ),
 'add_new_item' => __( 'Add New Product', 'Product' ),
 'edit_item' => __( 'Edit Product', 'Product' ),
 'new_item' => __( 'New Product', 'Product' ),
 'view_item' => __( 'View Product', 'Product' ),
 'search_items' => __( 'Search Product', 'Product' ),
 'not_found' => __( 'No Products found', 'Product' ),
 'not_found_in_trash' => __( 'No Products found in Trash', 'Product' ),
 'parent_item_colon' => ''

 $args = array(
 'labels' => $labels3,
 'public' => true,
 'publicly_queryable' => true,
 '_builtin' => false,
 'show_ui' => true,
 'query_var' => true,
 'rewrite' => array( "slug" => "products" ),
 'capability_type' => 'post',
 'hierarchical' => false,
 'menu_position' => 21,
 'supports' => array( 'title','editor','thumbnail'),
 'taxonomies' => array(),
 'has_archive' => true,
 'show_in_nav_menus' => false

register_post_type( 'products', $args );
register_taxonomy('product-category', 'products', array('hierarchical' => true, 'label' => 'Product Category', 'query_var' => true, 'rewrite' => true ));


Custom Post Type Templates

  • archive-{post_type}.php
  • single-{post_type}.php
If your custom post type were ‘products’, and/or query_var = “products”, WordPress would look for archive-products.php to display the archive of posts.
If your custom post type were ‘product’, and/or query_var = “product”, WordPress would look for single-products.php to display the single or permalink of the post.

If these files are not available in your Theme’s directory WordPress will look for archive.php and single.php, respectively. If even these files are not present it will default to index.php.

In our case we have to include contact form inside single-products.php

Single-products.php sample

<?php get_header(); ?>
 <div id="content">

 <?php while ( have_posts() ) : the_post(); ?>


<div class="category"><i class="icon-tag icon-large orange"></i>&nbsp;&nbsp;Category: <?php
$terms = wp_get_post_terms( $post->ID, 'product-category');
foreach ($terms as $term) {
echo ", ";
 echo '<a href="'.get_term_link($term->slug, 'product-category').'">'.$term->name.'</a>';
echo '';

<div id="enquiryform">

<form id="eform" name="eform" method="POST" action="" >
<input type="hidden" name="product_title" value="<?php the_title(); ?>" />
<input type="hidden" name="product_link" value="<?php the_permalink(); ?>" />
<p class="comment-form-author">
<label for="contactName">Name <span class="required">*</span></label> <input id="contactName" name="contactName" value="" size="30" aria-required="true" type="text">
<p class="comment-form-email">
<label for="email">Email <span class="required">*</span></label> <input id="email" name="email" value="" size="30" aria-required="true" type="text">
<p class="comment-form-url">
<label for="contactno">Contact no </label><input id="contactno" name="contactno" value="" size="30" type="text">
<p class="comment-form-comment">
<label for="comments">Comments <span class="required">*</span></label><textarea id="comments" name="comments" cols="45" rows="8" aria-required="true"></textarea>
<input name="submit" type="submit" id="submit" tabindex="5" value="<?php _e('Send Enquiry', 's3learn'); ?>" />
<div id="ajaxoutput"></div>
<input type="hidden" name="action" value="sendmail"/>
<input type="hidden" name="submitted" id="submitted" value="true" />
<?php endwhile; // end of the loop. ?>

<script type="text/javascript">

 var rsjqu = jQuery.noConflict();
 function ajaxSubmit()
 var newCustomerForm = jQuery(this).serialize();

 url: "<?php echo site_url(); ?>/wp-admin/admin-ajax.php",
 data: newCustomerForm,


 error: function(errorThrown){
return false;


<?php get_footer(); ?>

Write ajax functions inside your functions.php

add_action('wp_ajax_sendmail', 's3_sendmail');
add_action('wp_ajax_nopriv_sendmail', 's3_sendmail');

function s3_sendmail()
if(isset($_POST['submitted'])) {
 if(trim($_POST['contactName']) === '') {
 $nameError = 'Please enter your name.';
 $hasError = true;
 } else {
 $name = trim($_POST['contactName']);

 if(trim($_POST['email']) === '') {
 $emailError = 'Please enter your email address.';
 $hasError = true;
 } else if (!preg_match("/^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+.[a-z]{2,4}$/i", trim($_POST['email']))) {
 $emailError = 'You entered an invalid email address.';
 $hasError = true;
 } else {
 $email = trim($_POST['email']);

 if(trim($_POST['comments']) === '') {
 $commentError = 'Please enter a message.';
 $hasError = true;
 } else {
 if(function_exists('stripslashes')) {
 $comments = stripslashes(trim($_POST['comments']));
 } else {
 $comments = trim($_POST['comments']);

 if(!isset($hasError)) {
 //$emailTo = "easyselva@gmail.com";
 if (!isset($emailTo) || ($emailTo == '') ){
 $emailTo = get_option('admin_email');


 $subject = 'Enquiry From '.$name;
 $body = "Name: $name nnEmail: $email nnProduct: $product_title nnProduct Link: $product_link nnComments: $comments";
 $headers = "Reply-To: "$name" <$email>rn";
 if(wp_mail($emailTo, $subject, $body,$headers)){

 echo "<div class='success'>Enquiry has been sent successfully</div>";
echo "<div class='error'>Mail function Error!</div>";
 $error="<div class='error'><ul>";

 echo $error;

$error="<div class='error'>Error!</div>";

In this way you can use this for any kind of posts or anywhere in the form with your custom set of fields.

Any questions?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

About the Author:

Selvakumar Sankaravel
Hai I am Software and web developer. I studied B.Sc(Maths) in Ayya Nadar Janaki Ammal College,India and I studied MCA in Kalasalingam University,India. Now I am working as a Developer cum Project Leader at Kalasalingam University and I am doing freelancer works too.
Copyright © s3learn.com