Question

Ok guys and gals, I'm losing my mind here...

I am looking to append the content and a custom field of a post to a div on page. The ID of the content and custom field is defined by a data attribute on a link to be selected by the user.

Issue is the output of the function called by ajax is not being populated - instead the entire html of the current page is being duplicated instead.

This is the html of the selectors and output div on the page...

<p><a class="funnel-direction" data-funnel-id="123" href="#">Option One</a> <a class="funnel-direction" data-funnel-id="456" href="#">Option Two</a></p>

<div id="result"></div> <!-- whole page gets duplicated in here - wtf? -->

This is enqueuing my script for the ajax call

add_action( 'wp_enqueue_scripts', 'add_ajax_scripts' );

function add_ajax_scripts() {

   wp_enqueue_script( 'funnel-ajax', DNA_FU . 'js/funnel-ajax.js', array(), '1.0.0', true ); // working fine

   wp_localize_script( 'funnel-ajax', 'funnel_ajax', array(
    'ajaxurl'   => admin_url( 'admin-ajax.php' ),
    'ajaxnonce' => wp_create_nonce( 'ajax_post_validation' )
  ));

}

This is the function being called by ajax - it is this content I want to populate in <div id="result"></div>.

add_action ( 'wp_ajax_nopriv_dna_add_funnel_part', 'dna_add_funnel_part' );
add_action ( 'wp_ajax_dna_add_funnel_part', 'dna_add_funnel_part' );

function dna_add_funnel_part() {

  $id       = $_POST['postid'];
  $meta     = get_post_meta($id, 'dna_funnel_info', true);

  $content  = apply_filters('the_content', get_post_field('post_content', $id));
  $data     = !empty($meta) ?  '<p>' . $meta . '</p>' : '';
  
  echo $content . $data;

  wp_die();

}

finally, here is my ajax .js

jQuery(document).ready(function($) {

  $('a.funnel-direction').on( 'click', function(e) {
  
    e.preventDefault();

    var postid = $(this).attr('data-funnel-id');

    console.log(postid); // working

    $.ajax({
      type: 'POST',
      url: funnel_ajax.ajax_url,
      data: {
        action: 'dna_add_funnel_part',
        postid: postid,
      },
      success: function(data) {

        // console.log(data);

        $('#result').html(data); // This populates the entire html of the current
                                 // page - it should only popualte the output of 
                                 // the dna_add_funnel_part() wordpress function
      },
      fail: {
        // to do ...
      }
    });

    return false; 

  });

});

Have looked over and over this can can't spot anything hope fully y'all can spot it!

Thanks in advance

Was it helpful?

Solution

First, you made a really, really silly typo:

'ajaxurl'   => admin_url( 'admin-ajax.php' ),
.....
url: funnel_ajax.ajax_url,

ajaxurl != ajax_url. So your Admin AJAX request is not returning a full HTML page. You're not even hitting the AJAX file!

However, this is still completely the wrong way to go about this


I was going to suggest that you instead use the REST API which is much easier and foolproof, and to write a custom endpoint using register_rest_route to give you a pretty URL such as example.com/wp-json/richerimage/v1/dnafunnel, but you don't need to.

In fact, you don't even need an AJAX handler or an endpoint. Just use the one that core gives you.

First, register the post meta so it appears in the REST API responses:

PHP:

$args = array(
    'type' => 'string',
    'description' => 'DNA Funnel Info thing',
    'single' => true,
    'show_in_rest' => true,
);
register_post_meta( 'post', 'dna_funnel_info', $args );

Then retrieve the desired post, e.g. example.com/wp-json/wp/v2/post/123 where 123 is the ID of the post you wanted. The JSON response will contain the content in its fully rendered form, title, taxonomies, etc, including a meta section with all the meta keys you registered.

If your post ID is for a CPT, make sure show_in_rest is set to true when it's registered, and replace /post/ with the relevant endpoint for that CPT

Or better yet, use PHP:

add_filter( 'the_content', function( $content ) {
    // append post 123's content to the end
    return $content . get_the_content( '', '', 123 );
} );
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top