3

I've created a plugin to handle featured images for categories (well, for custom taxonomy actually, but it doesn't matter). Everything is working fine, except the featured image is not cleared after adding new term. All standard fields are being reset, but the custom image isn't.

The problem is, taxonomy terms are being added via ajax, without page reload (like posts or pages). So I need to intercept ajax success event.

Tried $(document).ajaxSuccess - not working. Google has no helpful results.

Any ideas?

Here's the screenshot to illustrate the problem.

Term image

Here's javascript code I use:

/**
 * Callback function for the 'click' event of the 'Set featured image' anchor in its meta box.
 * Displays the media uploader for selecting an image.
 */
function renderMediaUploader() {
    'use strict';

    var file_frame, image_data;

    /**
     * If an instance of file_frame already exists, then we can open it
     * rather than creating a new instance.
     */
    if (undefined !== file_frame) {
        file_frame.open();
        return;
    }

    /**
     * If we're this far, then an instance does not exist, so we need to
     * create our own.
     *
     * Here, use the wp.media library to define the settings of the Media
     * Uploader. We're opting to use the 'post' frame which is a template
     * defined in WordPress core and are initializing the file frame
     * with the 'insert' state.
     *
     * We're also not allowing the user to select more than one image.
     */
    file_frame = wp.media.frames.file_frame = wp.media({
        frame: 'post',
        state: 'insert',
        multiple: false
    });

    /**
     * Setup an event handler for what to do when an image has been selected.
     *
     * Since we're using the 'view' state when initializing
     * the file_frame, we need to make sure that the handler is attached
     * to the insert event.
     */
    file_frame.on('insert', function () {

        var json, image;
        // Read the JSON data returned from the Media Uploader
        json = file_frame.state().get('selection').first().toJSON();
        image = json.url;

        // First, make sure that we have the URL of an image to display
        if (0 > image.length) {
            return;
        }

        // After that, set the properties of the image and display it
        jQuery('#taxonomy-image-container')
            .children('img')
            .attr('src', json.url)
            .attr('alt', json.caption)
            .attr('title', json.title)
            .show()
            .parent()
            .removeClass('hidden');

        // Next, hide the anchor responsible for allowing the user to select an image
        jQuery('#taxonomy-image-container')
            .prev()
            .hide();

        // Display the anchor for the removing the featured image
        jQuery('#taxonomy-image-container')
            .next()
            .show();

        // Add image url to hidden form field
        jQuery('#taxonomy-image-src').val(json.url);

    });

    // Now display the actual file_frame
    file_frame.open();

}

/**
 * Callback function for the 'click' event of the 'Remove Featured Image' anchor in its meta box.
 * Resets the meta box by hiding the image and by hiding the 'Remove Featured Image' container.
 */
function resetUploadForm($) {
    'use strict';

    // First, we'll hide the image
    $('#taxonomy-image-container')
        .children('img')
        .hide();

    // Then display the previous container
    $('#taxonomy-image-container')
        .prev()
        .show();

    // Finally, we add the 'hidden' class back to this anchor's parent
    $('#taxonomy-image-container')
        .next()
        .hide()
        .addClass('hidden');

    // Finally, we reset the hidden form field
    $('#taxonomy-image-src')
        .val('');

}

/**
 * Checks to see if the input field for the thumbnail source has a value.
 * If so, then the image and the 'Remove featured image' anchor are displayed.
 * Otherwise, the standard anchor is rendered.
 */
function renderFeaturedImage($) {

    /* If a thumbnail URL has been associated with this image
     * Then we need to display the image and the reset link.
     */
    if ('' !== $.trim($('#taxonomy-image-src').val())) {

        $('#taxonomy-image-container').removeClass('hidden');

        $('#set-taxonomy-image')
            .parent()
            .hide();

        $('#remove-taxonomy-image')
            .parent()
            .removeClass('hidden');

    }

}

(function ($) {
    'use strict';

    $(function () {

        $('#set-taxonomy-image').on('click', function (evt) {

            // Stop the anchor's default behavior
            evt.preventDefault();

            // Display the media uploader
            renderMediaUploader();

        });

        $('#remove-taxonomy-image').on('click', function (evt) {

            // Stop the anchor's default behavior
            evt.preventDefault();

            // Remove the image, toggle the anchors
            resetUploadForm($);

        });

        renderFeaturedImage($);

        /**
         * Now we need to remove the image and toggle the anchors
         * after we successfully added new term
         */
        $(document).ajaxComplete(function( event, xhr, settings ){
            /**
             * We should somehow intercept the correct event among lots of them fired by WordPress
             * and just call: resetUploadForm($);
             */
            console.log( event );
            console.log( xhr );
            console.log( settings );

        });

    });

})(jQuery);
8
  • 2
    You should edit your question and add some example code that allows replicating your issue. Currently everyone would have to either guess an answer or try to repeat your setup, which could take hours. Thanks.
    – kaiser
    Commented Jan 6, 2016 at 17:38
  • 1
    I don't think you should wait a success call. Just reset it when the user press the button regardless if it is a success or a failure. What about $(document).ajaxComplete ?
    – Laxmana
    Commented Jan 6, 2016 at 21:39
  • @kaiser I don't think it will help, my code is fine. I need to intercept the event from the code executed by WordPress core. However, I'm adding the code just in case it helps. Commented Jan 7, 2016 at 14:33
  • @Laxmana thanks, ajaxComplete() works. But it fires multiple times - there's a lot of different ajax calls. When we click 'Set featured image' it opens standard WP media library popup which has many ajax calls. Can't figure out how to distinguish between them, how to filter only that call I need. See updated question. Commented Jan 7, 2016 at 14:36
  • @Ihor-paspar2.com The problem is not that or if your code works fine. The problem is that it is impossible to replicate your problem without example code. Please add some PHP code (Closures are enough) to add those additional data to some post type and register the script. Just add a minimum plugin header on top so we can throw that in a plain vanilla install and help you efficiently. +1 for your current efforts.
    – kaiser
    Commented Jan 7, 2016 at 15:43

1 Answer 1

5

Recently, I just have the same problem and got the solution.

  1. use ajaxSuccess event since we need to reset input when ajax is completed.
  2. filter the settings data for specific action and screen.

Code:

$(document).ajaxSuccess(function(e, request, settings){
        var object = $.deparam(settings.data);
        if(object.action === 'add-tag' && object.screen === 'edit-category' && object.taxonomy === 'category'){
            //DO RESET Your Input Here
        }
    });

I've use the jquery-deparam plugin to parse the settings.data string.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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