• Resolved pmoignard

    (@pmoignard)


    I’ve been trying for several days now to get an Ajax call working on my site. I’ve developed it as a plugin using a shortcode to output the I’ve been through these forums and other support sites extensively, and as far as I can see, I’ve done everything right, but still get a “Failed to load resource: the server responded with a status of 400 ()” error from admin-ajax.php, upon form submission, no matter what I do. What am I missing?

    The shortcode and script enqueuing in my plugin file:

     //localize and enqueue listing resources
       function mediator_filter_search_resources() {
           wp_enqueue_style( 'mediator_listing', plugin_dir_url( __FILE__ ). 'includes/mediator_filter_search_style.css', false, '1.0', 'all' );
           wp_enqueue_script( 'mediator_listing', plugin_dir_url( __FILE__ ). 'includes/mediator_filter_search_script.js', array(), '1.0', true );
           wp_localize_script( 'mediator_listing', 'wpAjax', array('ajaxUrl' => admin_url('admin-ajax.php')) );
       }
    
    // Define listing shortcode
       function mediator_listing_shortcode() {
          
          mediator_filter_search_resources();
          
          ob_start(); // Start output buffering
          include 'includes/mediator-listing.php'; // Include the external file
          return ob_get_clean(); // Return the buffered content
          
          
       }
       // Register listing shortcode
       add_shortcode('mediator_listing', 'mediator_listing_shortcode');

    My HTML/PHP form (in ‘mediator-listing.php’), which is pulling values from user meta fields:

    <form id="mediator-search-form" data-js-form="filter">
    	 
    	 <div id="mediator_main_search">
    		<label for="mediator_search">Keyword Search</label>
    	   <div id="mediator_search_box">
    		 <input type="text" name="mediator_search" id="mediator_search" placeholder="Search Professional Mediators...">
    		 <input type="submit" id="submit" name="submit" value="Search">
    	   </div>
    	 </div>
    	 
    	 <label for="designation">Designation</label>
    	  <?php 
    	  $selection = isset($_POST['designations']);
    	  $field_key = "field_664517d942b6e"; // <-- Find this by turning on Field Keys under Screen Options in admin interface
    	  $field = get_field_object($field_key);
    	  if( $field ) {
    		echo '<select name="designation" id="designation" autocomplete="off"><option value="">All</option>';
    		foreach( $field['choices'] as $k => $v ) {
    		  echo '<option value="' . $k . '"';
    		  if ( $k == $selection ) {
    			echo ' selected';
    		  }
    		  echo '>' . $v . '</option>';
    		}
    		echo '</select>';
    	  }
    	  ?>
    	  
    	  <label for="region">Region</label>
    		<?php 
    		$selection = isset($_POST['region']);
    		$field_key = "field_664514c742b6b"; // <-- Find this by turning on Field Keys under Screen Options in admin interface
    		$field = get_field_object($field_key);
    		if( $field ) {
    		  echo '<select name="region" id="region" autocomplete="off"><option value="">All</option>';
    		  foreach( $field['choices'] as $k => $v ) {
    			echo '<option value="' . $k . '"';
    			if ( $k == $selection ) {
    			  echo ' selected';
    			}
    			echo '>' . $v . '</option>';
    		  }
    		  echo '</select>';
    		}
    		?>
    		
    		<label for="language">Language</label>
    		<?php 
    		$selection = isset($_POST['languages']);
    		$field_key = "field_6645162042b6c"; // <-- Find this by turning on Field Keys under Screen Options in admin interface
    		$field = get_field_object($field_key);
    		if( $field ) {
    		  echo '<select name="language" id="language" autocomplete="off"><option value="">All</option>';
    		  foreach( $field['choices'] as $k => $v ) {
    			echo '<option value="' . $k . '"';
    			if ( $k == $selection ) {
    			  echo ' selected';
    			}
    			echo '>' . $v . '</option>';
    		  }
    		  echo '</select>';
    		}
    		?>
     </form>

    My jQuery Ajax call (in ‘mediator_filter_search_script.js’):

    //Handle searches  
      jQuery(document).ready(function() {
    	  
    	jQuery(document).on('submit', '[data-js-form=filter]', function(e) {
    	  e.preventDefault();
    	  var filter_data = jQuery(this).serialize();
    	  jQuery(this).find('#submit').val('Loading').addClass('loading');
    	  console.log(filter_data);
    	  
    	  jQuery.ajax({
    		url: wpAjax.ajaxUrl,
    		data: {
    			action: 'mediator_filter',
    			data: filter_data,
    		},
    		type: 'post',
    		dataType: 'json',
    		success: function(result) {
    		  console.log('Ajax Success');
    		  console.log(result);
    		  jQuery('[data-js-form=filter]').find('#submit').removeClass('loading').val('Search');
    		},
    		error: function(result) {
    		  console.log(result);
    		  console.log('Ajax Not Sent');
    		  jQuery('[data-js-form=filter]').find('#submit').removeClass('loading').val('Search');
    		}
    	  });
    	});
    	
    	//Submit form when filters are chosen
    	jQuery('#mediator-search-form select').change(function(){
    		 jQuery('#mediator-search-form').submit();
    	});
    	
    	
      });

    My call back function (also in ‘mediator-listing.php’). For now, I’m just trying to receive and output the values I’m trying to pass from the form:

    <?php
    
    add_action( 'wp_ajax_nopriv_mediator_filter', 'mediator_filter' );
    add_action( 'wp_ajax_mediator_filter', 'mediator_filter' );
    
    function mediator_filter() {
      
      $mediator_search = $_POST['mediator_search'];
      $url_designation = $_POST['designation'];
      $url_region = $_POST['region'];
      $url_language = $_POST['language'];
      
      echo $mediator_search;
      echo $url_designation;
      echo $url_region;
      echo $url_language;
      
    wp_die();
    }
    ?>

    Any insight anyone could give would be super helpful… I’m going crazy over this! Lol.

    • This topic was modified 6 months ago by pmoignard.
Viewing 6 replies - 1 through 6 (of 6 total)
  • It looks like you’re adding wp_ajax_nopriv_mediator_filter and wp_ajax_mediator_filter within the template that is being rendered via the shortcode.

    Two problems with that.

    One, you’re making these hooks dependent on the shortcode being rendered, and the shortcode is not rendered when you make a new request to WordPress via admin-ajax.php, which means those hooks don’t exist.

    Two, adding those wp_ajax hooks within the shortcode may actually be too late for those hooks to effectively be registered, even if the shortcode was executed.

    Move your wp_ajax hooks out from mediator-listing.php and put them in the same file as your add_shortcode() and see if that solves your problem.

    For example:

    add_shortcode( 'mediator_listing', 'mediator_listing_shortcode' );
    add_action( 'wp_ajax_nopriv_mediator_filter', 'mediator_filter' );
    add_action( 'wp_ajax_mediator_filter', 'mediator_filter' );
    Thread Starter pmoignard

    (@pmoignard)

    Thanks Ryan, moving the actions and the callback function into the shortcode file resolved the 400 error from admin-ajax.php; thanks!

    However, my Ajax still isn’t sending the data. I’m getting my error message in the Console. Am I perhaps enqueuing my jQuery in the wrong place as well?

    What’s the error message in the console? I’m assuming jQuery is working, otherwise you wouldn’t get any error related to it when submitting the form.

    Have you tried echoing out a valid JSON string in mediator_filter()? If you just echo out those four variables, I could see that being considered a failure, as it’s not in the expected JSON data format as specified in the dataType property.

    Thread Starter pmoignard

    (@pmoignard)

    The error message is simply the output from the “error” part of my Ajax call. I get my “Ajax Not Sent” message. So the code is working, but the data isn’t being received.

    To your note, I changed the dataType to ‘html’, and got a successful send. So it was that.

    Only thing that is happening now is that my callback function isn’t actually grabbing the sent data from the Ajax post? Should I be doing something other that serializing the data from the form?

    My jQuery is returning the data as a string as a result of being serialized like this:
    mediator_search=value&designation=value&region=value&language=value

    I don’t think the issue was with the send, but rather with the response format. You were not outputting the expected JSON string, likely causing the response to fail.

    Considering that you’re dealing with structured data, using JSON would be better than using HTML, unless you’re expecting HTML markup to be returned, with the intention of injecting that somewhere into the page.

    You can throw an error_log() call into callback to confirm that it’s being fired, and maybe even include a value for one of the fields, just to confirm that you’re getting data. Be sure to enable WP_DEBUG and WP_DEBUG_LOG so you can review debug.log in your wp-content folder (unless you already have a method for reading the error log).

    What you do from there with the response is really up to you and what your goal is.

    Also, one other thing to consider is using a nonce to validate your request. I didn’t see that anywhere in your example, but before you go live with this code, I highly recommend reviewing this: https://developer.www.ads-software.com/apis/security/nonces/

    Last, since the original issue (ajax call failing error 400) appears to be resolved, it might be helpful to create a fresh post, with updated code, and a detailed description of the new error, so that the emphasis is on the new problem you’re facing, which then also makes it easier for new eyes to jump in to help.

    Thread Starter pmoignard

    (@pmoignard)

    Thanks Ryan. I’ll try those things and see if I can resolve this “data acquirement” problem, and make another post focussed more on that if I continue to experience issues.

    It is my intention to include a nonce, just wanted to get the data sending first. Thanks for mentioning that!

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Ajax Call Failing – Error 400’ is closed to new replies.