15

I'm trying to create a WordPress sample plugin based in AJAX. I read a tutorial and did a plugin, but it's not working. I am new to AJAX. Here is the code I tried:

<?php
class ajaxtest {

    function ajaxcontact() {
        ?>
        <div id="feedback"></div>
        <form name="myform" id="myform">
            <li>
                <label for fname>First Name</label><input type="text" id="fname" name="fname" value=""/>
            </li>
            <li>
                <label for lname>Last Name</label><input type="text" id="lname" name="lname" value=""/>
            </li>
            <input type="submit" value="Submit" id="submit" name="submit"/>
        </form>
        <script type="text/javascript">
            jQuery('#submit').submit(ajaxSubmit);

            function ajaxSubmit() {

                var newcontact = jQuery(this).serialize();

                jQuery.ajax({
                    type: "POST",
                    url: "/wp-admin/admin-ajax.php",
                    data: newcontact,
                    success: function(data) {
                        jQuery("#feedback").html(data);
                    }
                });

                return false;
            }
        </script>
        <?php
    }

    function addcontact() {
        $fname = $_POST['fname'];
        if ($fname != "") {
            echo "Your Data is" . $fname;
        } else {
            echo "Data you Entered is wrong";
        }

        die();
    }

}

function jquery_add_to_contact() {
    wp_enqueue_script('jquery');  // Enqueue jQuery that's already built into WordPress
}

add_action('wp_enqueue_scripts', 'jquery_add_to_contact');
add_action('wp_ajax_addcontact', array('ajaxtest', 'addcontact'));
add_action('wp_ajax_nopriv_addcontact', array('ajaxtest', 'addcontact')); // not really needed
add_shortcode('cform', array('ajaxtest', 'ajaxcontact'));

I used this as a shortcode, but I didn't get an output. What's the mistake?

brasofilo
  • 25,496
  • 15
  • 91
  • 179
Vignesh Pichamani
  • 7,950
  • 22
  • 77
  • 115

2 Answers2

42

WordPress environment

First of all, in order to achieve this task, it's recommended to register then enqueue a jQuery script that will push the request to the server. These operations will be hooked in wp_enqueue_scripts action hook. In the same hook you should put wp_localize_script that it's used to include arbitrary JavaScript. By this way there will be a JS object available in front end. This object carries on the correct url to be used by the jQuery handle.

Please take a look to:

  1. wp_register_script(); function
  2. wp_enqueue_scripts hook
  3. wp_enqueue_script(); function
  4. wp_localize_script(); function

In main plugin file, add these.

add_action( 'wp_enqueue_scripts', 'so_enqueue_scripts' );
function so_enqueue_scripts(){
  wp_register_script( 
    'ajaxHandle', 
    plugins_url('PATH TO YOUR SCRIPT FILE/jquery.ajax.js', __FILE__), 
    array(), 
    false, 
    true 
  );
  wp_enqueue_script( 'ajaxHandle' );
  wp_localize_script( 
    'ajaxHandle', 
    'ajax_object', 
    array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) 
  );
}

File: jquery.ajax.js

This file makes the AJAX call.

jQuery(document).ready( function($){
  // Some event will trigger the ajax call, you can push whatever data to the server, 
  // simply passing it to the "data" object in ajax call
  $.ajax({
    url: ajax_object.ajaxurl, // this is the object instantiated in wp_localize_script function
    type: 'POST',
    data:{ 
      action: 'myaction', // this is the function in your functions.php that will be triggered
      name: 'John',
      age: '38'
    },
    success: function( data ){
      //Do something with the result from server
      console.log( data );
    }
  });
});

Also add below codes to plugin main file.

Finally, on your functions.php file, there should be the function triggered by your AJAX call. Remember the suffixes:

  1. wp_ajax ( allow the function only for registered users or admin panel operations )
  2. wp_ajax_nopriv ( allow the function for no privilege users )

These suffixes plus the action compose the name of your action:

wp_ajax_myaction or wp_ajax_nopriv_myaction

add_action( "wp_ajax_myaction", "so_wp_ajax_function" );
add_action( "wp_ajax_nopriv_myaction", "so_wp_ajax_function" );
function so_wp_ajax_function(){
  //DO whatever you want with data posted
  //To send back a response you have to echo the result!
  echo $_POST['name'];
  echo $_POST['age'];
  wp_die(); // ajax call must die to avoid trailing 0 in your response
}
alo Malbarez
  • 358
  • 2
  • 6
  • 16
rams0610
  • 1,041
  • 10
  • 8
  • 2
    Much more complete Answer, IMHO, should be the accepted (c/c @Fresher). There's a handy function, `wp_send_json_success`, that contains both `echo` and `wp_die`. – brasofilo Mar 18 '14 at 16:48
  • 2
    Note - there is one big glaring error in the above. 'action' is data point so should be part of the data array and NOT a separate param... and yes this is a better explanation and right way to do it! – wutang Apr 09 '14 at 00:57
  • This didn't work for me at first but wutang pointed out the issue, though i didn't understand what he meant. To clarify the above will always return 0 (which means function not found) unless you move the "action" which above is "myaction" in the ajax call into the data payload. So your data should look like this: data:{ action: 'myaction', name: 'John', age: '38' }, Aside from that this answer nails it. – RAC Jan 06 '16 at 02:33
  • Please note there is a typo: admin_url( 'admin-ajax.php' ) Not admin_url( 'admin_ajax.php' ) - not _ Pretty annoying... spent a while trying to work out why that didn't work! –  Feb 29 '16 at 12:32
  • You mean the ```functions.php``` file? Isn't it advised against to mess with core theme files? What's the alternative if I want to keep everything strictly in my plugin files? – Pamela Sillah Feb 14 '21 at 12:02
5

You need to add an 'action' to your AJAX call.

jQuery.ajax({
  type: "POST",
  url: "/wp-admin/admin-ajax.php",
  data: newcontact,
  action: 'addcontact',
  success: function(data) {
    jQuery("#feedback").html(data);
  }
});

The value should be the same as the add_action hook to wp_ajax. e.g.

add_action( wp_action_{action_value}, 'myfunc' );

This allows WordPress to know which function to run when the AJAX call is made.

This Codex page has some useful info and this article describes how to better refine the code you have.

Mark
  • 3,005
  • 1
  • 21
  • 30