Load custom field value into div with AJAX

Firstly, a POST request is the wrong type of request to send. As stated here, POST:

Submits data to be processed to a specified resource

You should be using GET, which

Requests data from a specified resource

The next problem is that in your callback function you are checking for $_POST["pid"], but you are not sending pid in your data:

data: { 
    action: 'call_meta', 
},

So your callback function has no idea which URL to load, or from which post. You need to include this information in the data you are sending.

Also, in your callback, you have this structure:

if () {

} 
else {

}
else {

}

This doesn’t make any sense. The 2nd else will cause a fatal error because you can only have one else in an if statement. If you have multiple conditions you need to use elseif or a switch statement.

So the solution to these issues is to include the post ID in the request and pass the specific meta key you are looking for in the request. I would also consider changing the links to the more semantically appropriate <button> element.

So your HTML should look like this:

<ul>
    <li><button class="play_next" data-meta-key="url-1">Video 1</button>
    <li><button class="play_next" data-meta-key="url-2">Video 2</button>
    <li><button class="play_next" data-meta-key="url-3">Video 3</button>
</li>

Note that I have attached the relevant meta key to the button with a data attribute. We’ll use this in the JavaScript to send the right request.

So then your script will look like this:

jQuery( document ).ready( function( $ ) {
    $( '.play_next' ).on('click', function( event ) {
        event.preventDefault();

        var meta_key = $( this ).data( 'meta-key' );

        $.ajax( {
            url: ajaxobject.ajaxurl,
            type: 'get',
            dataType: 'html',
            data: { 
                action: 'wpse_296903_call_meta',
                post_id: 1,
                meta_key: meta_key,
            },
            success: function( result) {
                $( '#output' ).append( result );
            }
        } );
    } );
} );

Note that I have:

  • Retrieved the meta key from the button with $.data(). See that link for the documentation that explains why meta-key is used in the HTML but metaKey is used in jQuery. EDIT: Sorry, that was only accurate for jQuery 3+, but WordPress uses jQuery 1.
  • Included the post ID as post_id in the request data. I wasn’t clear from the question whether this was supposed to be the current post, or a specific post, so I’ve just hardcoded an ID. Provide clarification on this and I’ll update the answer.
  • Specified dataType as 'html' so that the jQuery knows reliably that the response will be some HTML.
  • Prefixed the action name. It’s a good idea to prefix functions and hooks in your code with something unique to your project to avoid conflicts.

Now in your callback function (which I’ve renamed, see note on prefixing above) you use the post_id and meta_key sent in the request to return the appropriate value:

function wpse_296903_call_meta() {
    // Make sure we have both a post ID and a meta key.
    if( isset( $_POST['post_id'] ) && isset( $_POST['meta_key'] ) {
        $post_id = $_POST['post_id'];
        $meta_key = $_POST['meta_key'];

        // Only proceed if meta key requested is in a whitelist.
        if ( in_array( $meta_key, ['url-1', 'url-2', 'url-3'] ) ) {
            // Echo meta value.
            echo get_post_meta( $post_id, $meta_key, true );
        }
    }

    wp_die();
}
add_action( 'wp_ajax_wpse_296903_call_meta', 'wpse_296903_call_meta' );
add_action( 'wp_ajax_nopriv_wpse_296903_call_meta', 'wpse_296903_call_meta' );

One thing to make note of is that for a bit of security, to prevent anyone exploiting this AJAX action to return arbitrary meta, we check the meta key sent in the request against a whitelist of meta keys we want to return values for. I’m not 100% sure how necessary this is, but it won’t hurt.

Leave a Comment