Your form is displaying twice because you are handling your AJAX wrong, and using the template that shows the form as the response too. You need to wrap the form code in an if else statement that checks if there is an AJAX request currently in operation.
But more obviously, you’re going about AJAX completely the wrong way. WordPress has a nice pretty documented API that will let you take all that code out of your template and put it somewhere else ( and reduce the amount of code ).
See here for how: http://www.garyc40.com/2010/03/5-tips-for-using-ajax-in-wordpress/
e.g.
// embed the javascript file that makes the AJAX request
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js', array( 'jquery' ) );
// declare the URL to the file that handles the AJAX request (wp-admin/admin-ajax.php)
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
// if both logged in and not logged in users can send this AJAX request,
// add both of these actions, otherwise add only the appropriate one
add_action( 'wp_ajax_nopriv_myajax-submit', 'myajax_submit' );
add_action( 'wp_ajax_myajax-submit', 'myajax_submit' );
function myajax_submit() {
// get the submitted parameters
$postID = $_POST['postID'];
// generate the response
$response = json_encode( array( 'message' => 'why hello there javascript, Im doing fine thankyou' ) );
// response output
header( "Content-Type: application/json" );
echo $response;
// IMPORTANT: don't forget to "exit"
exit;
}
javascript:
jQuery.post(
// see tip #1 for how we declare global javascript variables
MyAjax.ajaxurl,
{
// here we declare the parameters to send along with the request
// this means the following action hooks will be fired:
// wp_ajax_nopriv_myajax-submit and wp_ajax_myajax-submit
action : 'myajax-submit',
// other parameters can be added along with "action"
message : 'hello wordpress this is javascript, how are you?'
},
function( response ) {
alert( response );
}
);
Doing it this way separates your form code from your AJAX registration logic, making the issue you described near impossible.
Also look at the mention of jquery-form in that article I linked to, which simplifies things even further.
For brownie points, when using the WordPress AJAX API, WordPress defines the constant DOING_AJAX
to let you know that you’re in the middle of an AJAX call. Use this to skip things and add other things in that may be important
if(defined('DOING_AJAX')){
// AJAX only stuff...