WordPress

submitting a form in wordpress using ajax

l am trying to send a form using ajax in my wordpress theme but struggling abit. Was hoping if anyone would be of any help.

    jQuery('#form').ajaxForm({
    data: {
        action: 'panacea_ajax_submission'
    },
    dataType: 'json',
    success : function(responseText, statusText, xhr, $form) {
        $('#form').html('Your form has been submitted successfully');
    }
});

However l get a page with 0 and the network in my developer tools confirm that the site is been send with a 200k response. l have trying to figure out why l don't get the success to display after a successful submission. any idea how l can handle this please? Zac Gordon

1 Answer

Andrew Shook
Andrew Shook
31,707 Points

When submitting information to WordPress via AJAX you need to perform 3 steps. First, you need to create a callback function for WP's Admin-Ajax.php, the file in WP that handles AJAX request, to use to process the request. You do this by adding an action in this format: wp_ajax_A_UNIQUE_NAME_FOR_YOUR_AJAX. So, if your plugin is called panacea you could call it wp_ajax_panacea_form. The PHP would look something like this:

<?php

function panacea_form_process() {
    // do whatever you need in order to process the form.
}
add_action("wp_ajax_panacea_form", "panacea_form_process");

//use this version for if you want the callback to work for users who are not logged in
add_action("wp_ajax_nopriv_panacea_form", "panacea_form_process");

Next, you need pass the url for the Admin-Ajax.php, along with any other information, form PHP to javascript so that it is available to the ajax call you make. You should do this inside the same wp_enqueue_scripts call you used to add the javascript file that contains the ajax function.

<?php
function your_enqueue_scripts_function() {
    //add this below what you currently have in your enqueue scripts function.
    wp_localize_script( "the_unique_name_for_your_js",
        'theUniqueNameForYourJSObject',
        array(
            'ajaxUrl' => admin_url( 'admin-ajax.php' ), //url for php file that process ajax request to WP
            'nonce' => wp_create_nonce( "unique_id_nonce" ),// this is a unique token to prevent form hijacking
            'someData' => 'extra data you want  available to JS'
        )
    );
}}

Finally, once you have handle all of this you will need to update you current JS to point to the correct url and add the nonce. I looked over the documentation for the ajaxForm plugin, so the JS here should work, but double check just to be sure.

var options = { 
        url: theUniqueNameForYourJSObject.ajaxUrl,  // this is part of the JS object you pass in from wp_localize_scripts.
        type: 'post',        // 'get' or 'post', override for form's 'method' attribute 
        dataType:  json ,       // 'xml', 'script', or 'json' (expected server response type) 
        dataType: 'json',
        success : function(responseText, statusText, xhr, $form) {
            $('#form').html('Your form has been submitted successfully');
        },
        // use beforeSubmit to add your nonce to the form data before submitting.
        beforeSubmit : function(arr, $form, options){
            arr.push( { "name" : "nonce", "value" : theUniqueNameForYourJSObject.nonce });
        },

    }; 

    // you should probably use an id more unique than "form"
    $('#form').ajaxForm(options); 

Thanks for the response. I suppose. it's the same idea surrounding submitting forms in a theme as you mentioned plugins in your answer. I have already written a function in my functions.php probably would be worth posting that aswell. Thanks

it dont seem to work for me. Is there soemthing that l am doing wrong.

      <form id="form" action="/wp-admin/admin-ajax.php" method="post">

          <div class="form-row row">
          <span class="small-12 large-12 columns">
            <input class="basic-slide" id="cname" type="text" name="name" placeholder="Enter your Name"/><label for="name">Name</label>

          </span>
          <span class="small-12 large-12 columns">
            <input class="basic-slide" id="cemail" type="text" name="email" placeholder="Enter your Email"/><label for="email">Email</label>
          </span>
          <span class="small-12 large-12 columns">
            <input class="basic-slide" id="phone" type="text" name="cphone"  placeholder="Enter your Telephone number"/><label for="phone">Phone</label>
          </span>
          <span class="small-12 large-12 columns">
            <input class="basic-slide" id="ccompany" type="text" name="company"  placeholder="Enter your Company name"/><label for="company">Company</label>
          </span>
          <span class="small-12 large-12 columns">
            <textarea placeholder="Please enter your enquiry here" type="text" name="message" ></textarea>
          </span>
          <br>
          <span class="small-12 large-12 columns">
            <button type="submit" class="submit custom-button-class right" value="submit">Submit Enquiry</button>
          </span>
          <input type="hidden" name="action" value="wp_ajax_panacea_ajax_submission"/>
        </div>
      </form>

the code to process the form is a function in my functions.php as below

add_action('wp_ajax_panacea_ajax_submission','panacea_ajax_handler');
function panacea_ajax_handler(){

    $name = ($_POST['name']);
    $email = ($_POST['email']);
    $phone =($_POST['phone']);
    $company = ($_POST['company']);
    $message = ($_POST['message']);



    $email_title = $name . " has filled in a form on Panacea";

    $email_message .= "Name: ".$name."\n";
    $email_message .= "Email: ".$email."\n";
    $email_message .= "Phone Number: ".$phone."\n";
    $email_message .= "Company: ".$company ."\n";
    $email_message .= "Message: ".$message."\n";


    require("_postmark.php");

    $postmark = new Postmark( "49b406ff-4c47-4d08-955e-e032cc9318e3", "kelvin@bluestone98.com","kelvin@bluestone98.com"  );

    $result = $postmark->to('kelvin@bluestone98.com')
    ->subject($email_title)
    ->plain_message($email_message)
    ->send();

    if($result):
    echo json_encode( array('success' => true) );
    else:

    $headers = 'From: '.$email_from."\r\n".
    'Reply-To: '.$email_from."\r\n" .
    'X-Mailer: PHP/' . phpversion();

    @mail("kelvin@bluestone98.com", "Problem Sending Email With Postmark", $email_message, $headers);
endif;
}

and the javascript in footer is as below

    $("#form").validate({
      errorElement:'span',
      submitHandler:function(form){
        $("#form").find('.submit').val('Working');
        var _data ={ 'action' : 'panacea_ajax_submission'}
        $(form).ajaxSubmit({
          dataType: 'json',
          data: _data,
          success: function(resp){
            $("#form").fadeOut('ease',function(){
              $("#form").html('<p>Enquiry submitted we would be in touch soon.</p>');
              $("#form").fadeIn('ease');
            });
          }
        });
      }
    });

but l end up with the same thing l get a black screen with 0 upon submission. Just to mention as well l am using postmark. any mistakes that you can see guys? Zac Gordon Andrew Shook

Andrew Shook
Andrew Shook
31,707 Points

My guess would be that you need to change :

<?php
    add_action('wp_ajax_panacea_ajax_submission','panacea_ajax_handler');

to:

<?php
    add_action('wp_ajax_nopriv_panacea_ajax_submission','panacea_ajax_handler');

The nopriv allows the ajax request to be preformed by none logged in users.