AJAX Implementation

The question:

Am try to implement data from database using AJAX based on a drop down list in WordPress. The codes returning 400 bad request in the console. I am hosted the page as localhost.

Here is my theme’s functions.php //I changed the Code

  function my_enqueue_scripts() {
   wp_enqueue_script('jquery');
}
add_action('wp_enqueue_scripts', 'my_enqueue_scripts');

function fetchData(){
    global $wpdb;

    // this can be improved
    $catId = isset($_REQUEST['catId']);
    if($catId){
        $result_data = $wpdb->get_results("SELECT * FROM  sub_category where categor_id = '".$catId."'");
        foreach ($result_data as $data) {
            echo "<option value='".$data->id."'>'".$data->sub_category_name."'</option>";
        } 
    }
    die();
}

// add your ajax action to authenticated users only
add_action('wp_ajax_fetch_data','fetchData');

Am also adding the jQuery part here:

<script type="text/javascript">

jQuery(document).ready( function(){

  jQuery('#category').on('change',function (){
      console.log("start1");
      var catId = document.getElementById('category').value;
      console.log(catId);
      jQuery.ajax({
        type: 'POST',
        url: "<?php echo admin_url( 'admin-ajax.php' ); ?>",
        data: {
            'key':catId,
            'action': "fetch_data" // very important
        },
        success : function (data) {
                 jQuery('#sub_cat').html(data);
                }
      });
  });
});

</script>
<form  method="post" name="myform" id="myform">
<table width="200" border="0" cellpadding="10">
  <tr>
    <th scope="col">&nbsp;</th>
    <th scope="col">&nbsp;</th>
    <th scope="col">&nbsp;</th>
  </tr>
  <tr>
    <td><label>Category</label></td>
    <td><select name="category" id="category" >
          <option value="">Select the category</option>
           <?php
                global $wpdb;
                $result_fromDB = $wpdb->get_results("SELECT * FROM `category`");
                foreach ($result_fromDB as $cat) {
                       echo "<option value='".$cat->id."' selected>".$cat->name."</option>";
                }
           ?>
        </select>
    </td>
    <td></td>
  </tr>
  <tr>
    <td><label>Sub Category</label></td>
    <td>&nbsp;
        <div id="fetch_data"><select name="sub_cat" id="sub_cat">
        <option value=""> Select Sub category</option>  <!--Here I want to return the data-->
    </select></div>
    </td>
  </tr>
</table>

</form>

Remembering that I am using internal scripts, Please give a solution.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

First, enqueue your script correctly, in functions.php:

function my_enqueue_scripts() {
   wp_enqueue_script('jquery');
}
add_action('wp_enqueue_scripts', 'my_enqueue_scripts');

Then, Authenticated users only (see https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_nopriv_(action))
(can also be in functions.php):

function fetchData(){

    // Not needed anymore, as you manage the case through the `add_action` method
    // if ( ! is_user_logged_in()  ) {
    //    return;
    // }

    // this can be improved
    $catId = isset($_REQUEST['catId']) ? $_REQUEST['catId'] : '';
    echo "<option>$catId</option>"; // there was a typo here: `<optio>`

    die();
}

// add your ajax action to authenticated users only
add_action('wp_ajax_fetch_data','fetchData');

// no need for the `nopriv_` action, this one is for anonymous users
// add_action('wp_ajax_nopriv_fetch_data','fetchData');?>

And finally, your JS script. You must add the action parameter, otherwise WordPress does not know which action to fire in the backend (the one used in wp_ajax_fetch_data -> fetch_data).
Also, for the url, try to use admin_url( 'admin-ajax.php' ); instead:

<script type="text/javascript">

jQuery(document).ready( function(){

  jQuery('#category').on('change',function (){
      console.log("start1");
      var catId = document.getElementById('category').value;
      console.log(catId);
      jQuery.ajax({
        type: 'POST',
        url: "<?php echo admin_url( 'admin-ajax.php' ); ?>",
        data: {
            'key':catId,
            'action': "fetch_data" // very important
        },
        cache: false,
        success : function (data) {
                 jQuery('#sub_cat').html(data); 
                    console.log(data);
                }
      });
  });
});

</script>

Method 2

You get 400 error, because there is no callback registered for your AJAX request.

Here’s how you do the request:

jQuery.ajax({
    type: 'POST',
    url: "/mudratcr/wp-admin/admin-ajax.php",
    data: {'key':catId},
    cache: false,
    success : function (data) {
        jQuery('#sub_cat').html(data); 
        console.log(data);
    }
});

So there is no action param in your request.

And because you register your callback like below:

add_action( 'wp_ajax_data', 'fetchData' );
add_action( 'wp_ajax_nopriv_data', 'fetchData' );

you should pass “data” as action in your request:

jQuery.ajax({
    type: 'POST',
    url: "/mudratcr/wp-admin/admin-ajax.php",
    data: {key: catId, action: 'data'},
    cache: false,
    success : function (data) {
        jQuery('#sub_cat').html(data); 
        console.log(data);
    }
});

PS. I wouldn’t use hardcoded URL to admin-ajax.php file in your JS. It would be much better if you localized your JS file and passed real admin-ajax.php file URL in there.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment