I am following an example on AJAX in Plugins on Wordpress website. It's very simple example, and I am trying to modify the example as I intend.

What I am trying to achieve is simple:

  • When a new option is selected in select/option dropdown, detect the selected value
  • Pass the selected value to PHP function via AJAX

However, the selected value doesn't seem to be passed via AJAX. The result I am getting is: whatever = 1234 | whatever2 =

How do I properly pass my variable to AJAX?

My code:

// Select/Option Dropdown

<select id="_type" name="_type">
  <option value="AAA"> AAA </option>
  <option value="BBB"> BBB </option>
  <option value="CCC"> CCC </option>

// Detect change and call and AJAX

<script type="text/javascript">
jQuery('#_type'.change(function($) {
  var val = jQuery('#_type').val(); <-- Here I am properly getting val as it changes.
  console.log( '_type is changed to ' + val );

  var data = {
    'action': 'my_action',
    'type': 'post',
    'whatever': 1234,
    'whatever2': val <-- But here val becomes empty.  

  jQuery.post(ajaxurl, data, function(response) {
    alert( 'Got this from the server: ' + response );

// PHP function 'my_action'

add_action( 'wp_ajax_my_action', 'my_action' );
function my_action() {
  global $wpdb;
  $whatever = $_POST['whatever'];
  $whatever2 = $_POST['whatever2'];
  echo 'whatever = ' . $whatever . ' | whatever2 = ' . $whatever2;
  • the code seems outdated but ok. Use the network monitoring tools in your browser developer tools to see what is exactly being sent and received. Apr 7, 2017 at 11:53
  • I would recommend instead using the WP REST API instead of the older WP Admin AJAX system, it's a lot more explicit and as a result easier to work with, and handles a lot of stuff for you such as access levels and authentication, things that are difficult to get right with Admin AJAX
    – Tom J Nowell
    Apr 7, 2017 at 12:29

3 Answers 3


The simple answer: Don't bother with the Admin AJAX API, use the REST API!

Tell WordPress about your endpoint:

add_action( 'rest_api_init', function () { // register dongsan/v1/whatever
        register_rest_route( 'dongsan/v1', '/whatever/', array(
                'methods' => 'POST', // use POST to call it
                'callback' => 'dongsan_whatever' // call this function
        ) );
} );

Now we have an endpoint at example.com/wp-json/dongsan/v1/whatever!

We told WordPress to run dongsan_whatever when it gets called, so lets do that:

function dongsan_whatever( \WP_REST_Request $request ) {
    $name = $request['name'];
    return 'hello '.$name;

Note that we used $request['name'] to get a name parameter!

So we have a URL:


And we can send a POST request with a name to it and get some JSON back that says Hello 'name'! So how do we do that?

Simples, it's a standard jQuery post request:

    { 'name': 'Dongsan' }
).done( function( data ) {
    Console.log( data ); // most likely "Hello Dongsan"
} );

Further reading:

  • I really like this Rest API approach. WP is heading to this direction, so should we. +1 for the different approach.
    – Fayaz
    Apr 7, 2017 at 16:47
  • I followed your example, but it's yield 404 (Not Found) error, even though I copied and pasted your code. I checked the Wordpress codex page for this custom endpoint but I don't see anything wrong with your code. Still...I'm getting 404...perhaps because I am on Multisite?
    – Dongsan
    Apr 8, 2017 at 12:29
  • After an hour of frustration, I found that it should be jQuery.post( '/blog_name/dongsan/v1/whatever' since I am on multisite environment. Now I need to figure out how to deliver this blog_name to jQuery.post...'
    – Dongsan
    Apr 8, 2017 at 12:58
  • @Dongsan that's actually a good question! You should ask it as a separate question, it seems like something that'd get a lot of attention
    – Tom J Nowell
    Apr 8, 2017 at 13:10
  • I made the URL absolute so it's obvious it needs changing rather than using /, that should prevent others having the same problem
    – Tom J Nowell
    Apr 8, 2017 at 13:11

Just tested your code and it seems to be working fine. Just make sure to add a bracket to the change function jQuery('#_type').change(function($)

Also, you need to add no_priv action if you are using the ajax on frontend

add_action( 'wp_ajax_nopriv_my_action', 'my_action' );

Check and let me know if this works for you.


Try adding type : 'post', inside data = {...} Also, I'm missing 'security' inside your ajax function.

Could you add this and show us the results:

.success( function( results ) {
                   console.log( val );
                } )
  • I added 'type' : 'post' and it's still not working. By 'security' what do you mean? The AJAX code is almost the same as the example in Wordpress AJAX in Plugin page.
    – Dongsan
    Apr 7, 2017 at 11:29
  • 1
    Security is needed because of the check_ajax_referer function. check_ajax_referer. It's not something that will fix your current issue, but it's to keep your ajax call safe.
    – kiarashi
    Apr 7, 2017 at 11:40
  • console.log( val ) inside 'success' echoes the value properly. Very confusing.
    – Dongsan
    Apr 7, 2017 at 11:43
  • ah, I see the problem; it's related to my_action. Hold on for a bit as I completely alter your code.
    – kiarashi
    Apr 7, 2017 at 11:48
  • Dang...shame on me. I was totally wrong. The variable 'val' has values ONLY WHEN the select/option value changes. I was only looking at the first alert, which of course has val as NULL. Sorry, and thanks.
    – Dongsan
    Apr 7, 2017 at 11:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.