Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

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,709 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,709 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.