1

Playing with WordPress customization I created a meta box with several others that report back details of the post. One meta box evaluates the featured image but I am having trouble figuring out how to fire the AJAX in the content of the meta box. At first I thought I would need to look into admin-ajax.php so I followed Using AJAX With PHP on Your WordPress Site Without a Plugin but after looking into it I need to check if the post has a thumbnail loaded in the meta box content. I searched under the tag and tag and what I found was Trigger JS when featured image upload window is opened in admin which led me to search for wp.media.featuredImage but how can I build my function with AJAX to run when the featured image is loaded but if it isn't then do not.

I can get it to work by using:

function foobar_metabox_callback( $post ) {
    wp_nonce_field( basename( __FILE__ ), 'metabox_meta_nonce' );
    $metabox_stored_meta = get_post_meta( $post->ID );
    if ( has_post_thumbnail() ) { ?>
    <p>
        <!-- show results -->
    </p>
    <?php } else { ?>
        <p>No Featured Image not loaded</p>
    <?php
    }

    // test the meta content
    $getPostCustom=get_post_custom();
    var_dump($getPostCustom);
}

but that is only if I refresh after the featured image has been loaded to the post. How can I get the function foobar_metabox_callback() to run without refreshing using admin-ajax.php if possible?

Further reference:

  • Why not look at the featured image metabox and when the image is added there then continue your actions? $('#postimagediv .inside img') .. – Samuel Elh May 30 '16 at 21:10
  • Eww.. that is an idea. Didnt think about it that way. – DᴀʀᴛʜVᴀᴅᴇʀ May 30 '16 at 21:11
  • I did notice wp adds two classes to the thumbnail. It might work if i write a conditional for the class but ill still have to figure out how to work the AJAX. – DᴀʀᴛʜVᴀᴅᴇʀ May 30 '16 at 21:14
  • 3
    Why not make it an answer so i can rep you? Add all what you have in the comment to explain so it makes since after i nuke my comments. – DᴀʀᴛʜVᴀᴅᴇʀ May 30 '16 at 21:51
  • 2
    @SamuelElh what was your issue with posting an answer? – Rarst May 31 '16 at 17:19
1

I couldn't find any WP specific event to hook in to. What you can do is set up an observer with a callback to respond to DOM changes using MutationObserver and check if the your featured image has been added in the callback.

There's no support in IE < 11 though, which may be a deal breaker for you, or maybe not.

I've done minimal testing on this, but it works for me:

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {

    // Fires every time a mutation occurs...

    // forEach all mutations
    mutations.forEach(function(mutation) {

        // Loop through added nodes
        for (var i = 0; i < mutation.addedNodes.length; ++i) {

            // any images added?
            if ( mutation.addedNodes[i].getElementsByTagName('img').length > 0) {
                alert('Featured Image Added');

                // Your featured image now exists
                console.log( $('#postimagediv img') );

                // Do some AJAX...
            }
        }
    });
});

// define what element should be observed (#postimagediv is the container for the featured image)
// and what types of mutations trigger the callback
var $element = $('#postimagediv');
var config = { subtree: true, childList: true, characterData: true };

observer.observe( $element[0], config );

There's probably a better way to check for the featured image than just checking for an img element. You may want to have a var to keep track of the featured image so you can easily check for it being removed too (or just check removedNodes in the observer callback).

This won't run on page load so you should check if a featured image exists there first.

Further reading on the Mutation Observers:

2

Very broad solution.

There are two problems you are facing

  1. there are different HTML generated by the server based on if there is a featured image

  2. Meta box are just a UI artifact of post editing and are not easily manipulated via AJAX (even in AJAX it is easier to handle full objects rather then their individual properties, even if only for keeping everything in sync)

The solution is by removing point 1 and keeping everything in the client. Add all the HTML as if there is a featured image, just hide it with display:none or similar.

Now all you have to do is to monitor when a feature image is inserted, probably via DOM mutation event or whatever you can do with jQuery (there might even be an event raised by WP JS that associates the image). Once you detect that the image is there you can update whatever values you have in the metabox and remove the display:none.

You are unlikely to get the same exact behavior as when the html is rendered with the featured image already there, depending on the complexity of what you do, but you should be able to get something that is good enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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