1

In a Wordpress plugin that I am working on, I am using the built-in Wordpress media uploader function ( wp.media ) to add photos. I am using the selection option to pre-select images in the media library once the modal opens. I thought it would be a cool idea to attach a new CSS class to these items and style them differently from other new images the user selects.

I am running into an issue with passing jQuery into the modal and I cannot seem to get the events right. The problem is that the images in the media uploader are dynamically generated once the modal is opened. I have tried adding my script to the on event (when the modal is opened), but this seems to be too early. Adding them to the select or close events is obviously too late.

The goal is to have a custom CSS class added to all the images that are pre-selected once the modal opens. Does anyone have any experience with passing jQuery into the media uploader modal?

Here is the jQuery I am using:

//Image Uploader function                  
odp_slideshowImageUpload = {

    // Call this from the upload button to initiate the upload frame.
    uploader : function() {
        var frame = wp.media({
            title : 'Choose or Upload an Image(s)',
            multiple : true,
            library : { type : 'image' }, //only can upload images
            button : { text : 'Insert Image(s)' }
        });

        frame.on( 'open', function() {
            var selection = frame.state().get('selection');

            // Get the id of all the images already in the slideshow
            var ids = $( '#odp_slider_container li[id]' ).map(function() { return this.id; }).get();
            // When our modal opens, make all of the images "selected"
            ids.forEach( function(id) {
                attachment = wp.media.attachment(id);
                attachment.fetch();
                selection.add( attachment ? [ attachment ] : [] );
            });


            $('.media-modal-content li.selected').addClass('testing'); //does not work

        });

        // Handle results from media manager
        frame.on( 'select', function() {
            var selection = frame.state().get( 'selection' );
            selection.map( function( attachment ) {
                attachment = attachment.toJSON();
                $( '#odp_slider_container' ).append( function() {
                    var output = '';

                    output += '<li id="' + attachment.id + '" class="odp-slideshow-item" >';
                    output += '<div class="slide-container"><image  src="' + attachment.sizes.thumbnail.url + '" alt="' + attachment.alt + '" /></div>';
                    output += '<input type="text" class="slide-id odp-force-hidden" name="slide_id[]" value="' + attachment.id + '" />';
                    output += '<input type="text" class="slide-image odp-force-hidden" name="slide_image[]" value="' + attachment.url + '" />';
                    output += '<input type="text" class="slide-title odp-force-hidden" name="slide_title[]" value="' + attachment.title + '" />';
                    output += '<input type="text" class="slide-alt odp-force-hidden" name="slide_alt[]" value="' + attachment.alt + '" />';
                    output += '<input type="text" class="slide-caption odp-force-hidden" name="slide_caption[]" value="' + attachment.caption + '" />';
                    output += '<div class="details-container"><a class="details" href="#">Details</a><a class="remove" href="#">Remove</a></div>';
                    output += '</li>';

                    return output;
                });
            });
        });

        frame.open();
        return false;

    },

};

I understand this is a complicated question, so let me know if I could be more clear in certain areas.

  • Have you tried using the explicit "jQuery" instead of the shortened "$"? Just thinking that it might be a noConflict issue unless you explicitly defined $ somewhere. – Otto Sep 18 '14 at 19:22
  • Hi @Otto thanks for the suggestion, but yes, I wrap the whole thing in a no-conflict wrapper: jQuery(document).ready(function($){. This is a tricky one I think. I have done quite a bit of "Googling" on the topic with no luck. – ndiego Sep 18 '14 at 22:13
0

As you mention the media uploader dynamically renders the images "on demand" and there doesn't seem to be an event one can target to add the class. A gross way to do it is to override the wp.media.view.Attachment.Library.className attribute (before the frame is created) to return the extra class if the model id is in the initial selection. It means moving the ids select outside the open, eg

//Image Uploader function                  
odp_slideshowImageUpload = {

    // Call this from the upload button to initiate the upload frame.
    uploader : function() {
        // Get the id of all the images already in the slideshow
        var ids = $( '#odp_slider_container li[id]' ).map(function() { return this.id; }).get();
        wp.media.view.Attachment.Library = wp.media.view.Attachment.Library.extend({
            className: function () { return $.inArray(this.model.get('id').toString(), ids ) !== -1 ? 'attachment testing' : 'attachment'; }
        });
        var frame = wp.media({
            // etc
  • Thanks bonger. I agree, not the prettiest solution, but it works. This was a lot more complicated than I thought it would be. I expected there to be a built in event that I could target, but oh well... – ndiego Sep 21 '14 at 2:46

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.