Hooking onto WP’s media backbone

One of my Bulk Attachment Download users suggested I make it work for grid view as well as list view, and since this was entirely sensible and something I should have looked at sooner, off I went. Most of the work was relatively straightforward, but I hit a bump when trying to respond to users selecting attachments for download.

Although I could get a jQuery function to react to a click event on the image, nothing would happen when clicking on the check / uncheck icon at the top right of each image.

The problem came from an event.stopPropagation(); in this section of WordPress’s media handling:

/**
 * Add the model if it isn't in the selection, if it is in the selection,
 * remove it.
 *
 * @param {[type]} event [description]
 * @return {[type]} [description]
 */
checkClickHandler: function ( event ) {
	var selection = this.options.selection;
	if ( ! selection ) {
		return;
	}
	event.stopPropagation(); // <--- AHA!!!
	if ( selection.where( { id: this.model.get( 'id' ) } ).length ) {
		selection.remove( this.model );
		// Move focus back to the attachment tile (from the check).
		this.$el.focus();
	} else {
		selection.add( this.model );
	}

	// Trigger an action button update.
	this.controller.trigger( 'selection:toggle' );
}

Luckily the same section of code has the first part of the answer – the very last line:

this.controller.trigger( 'selection:toggle' );

Simple, I thought – just use that event to fire whatever I needed to. Except not quite. Using something like $( 'body' ).on( 'click', function() { // Do stuff } ); won’t work. Instead, and for reasons that I am not sure I fully understand yet, the event listener must be set to the wp.media.frame object. Thus anyone else struggling with this, the answer to is:

if ( 'undefined' != typeof( wp.media.frame ) ) {
	wp.media.frame.on('selection:toggle', function() {
		// Do stuff
	} );
}

Leave a Reply

Your email address will not be published. Required fields are marked *