Custom Gallery Metabox

This is some kind of addition to my previous tutorial about using WordPress default popup uploader in your own ways. There were a lot of questions about multiple uploads so far, so I hope this new tutorial will answer all of them.

First off all check out this video to understand what I mean:

So, following this video I can mention some of the requirements.


/*
 * A custom function that checks if element is in array, we'll need it later
 */
function in_array(el, arr) {
	for(var i in arr) {
		if(arr[i] == el) return true;
	}
	return false;
}

jQuery( function( $ ) {
	/*
	 * Sortable images
	 */
	$('ul.misha_gallery_mtb').sortable({
		items:'li',
		cursor:'-webkit-grabbing', /* mouse cursor */
		scrollSensitivity:40,
		/*
		You can set your custom CSS styles while this element is dragging
		start:function(event,ui){
			ui.item.css({'background-color':'grey'});
		},
		*/
		stop:function(event,ui){
			ui.item.removeAttr('style');

			var sort = new Array(), /* array of image IDs */
			    gallery = $(this); /* ul.misha_gallery_mtb */

			/* each time after dragging we resort our array */
			gallery.find('li').each(function(index){
				sort.push( $(this).attr('data-id') );
			});
			/* add the array value to the hidden input field */
			gallery.parent().next().val( sort.join() );
			/* console.log(sort); */
		}
	});
	/*
	 * Multiple images uploader
	 */
	$('.misha_upload_gallery_button').click( function(e){ /* on button click*/
		e.preventDefault();

		var button = $(this),
		    hiddenfield = button.prev(),
		    hiddenfieldvalue = hiddenfield.val().split(","), /* the array of added image IDs */
	    	    custom_uploader = wp.media({
			title: 'Insert images', /* popup title */
			library : {type : 'image'},
			button: {text: 'Use these images'}, /* "Insert" button text */
			multiple: true
		    }).on('select', function() {

			var attachments = custom_uploader.state().get('selection').map(function( a ) {
				a.toJSON();
            			return a;
			}),
			thesamepicture = false,
			i;

			/* loop through all the images */
          		for (i = 0; i < attachments.length; ++i) {

				/* if you don't want the same images to be added multiple time */
				if( !in_array( attachments[i].id, hiddenfieldvalue ) ) {
					
					/* add HTML element with an image */
					$('ul.misha_gallery_mtb').append('<li data-id="' + attachments[i].id + '"><span style="background-image:url(' + attachments[i].attributes.url + ')"></span><a href="#" class="misha_gallery_remove">&times;</a></li>');
					/* add an image ID to the array of all images */
					hiddenfieldvalue.push( attachments[i].id );
				} else {
					thesamepicture = true;
				}
          		}
			/* refresh sortable */
			$( "ul.misha_gallery_mtb" ).sortable( "refresh" );
			/* add the IDs to the hidden field value */
			hiddenfield.val( hiddenfieldvalue.join() );
			/* you can print a message for users if you want to let you know about the same images */
			if( thesamepicture == true ) alert('The same images are not allowed.');
		}).open();
	});

	/*
	 * Remove certain images
	 */
	$('body').on('click', '.misha_gallery_remove', function(){
		var id = $(this).parent().attr('data-id'),
		    gallery = $(this).parent().parent(),
		    hiddenfield = gallery.parent().next(),
		    hiddenfieldvalue = hiddenfield.val().split(","),
		    i = hiddenfieldvalue.indexOf(id);

		$(this).parent().remove();

		/* remove certain array element */
		if(i != -1) {
			hiddenfieldvalue.splice(i, 1);
		}

		/* add the IDs to the hidden field value */
		hiddenfield.val( hiddenfieldvalue.join() );

		/* refresh sortable */
		gallery.sortable( "refresh" );

		return false;
	});
	/*
	 * Selected item
	 */
	$('body').on('mousedown', 'ul.misha_gallery_mtb li', function(){
		var el = $(this);
		el.parent().find('li').removeClass('misha-active');
		el.addClass('misha-active');
	});
});

add_action( 'admin_enqueue_scripts', 'misha_scripts_for_gallery' );
function misha_scripts_for_gallery(){
	wp_enqueue_script('jquery-ui-core');
	wp_enqueue_script('jquery-ui-widget');
	wp_enqueue_script('jquery-ui-sortable');

	if ( ! did_action( 'wp_enqueue_media' ) )
		wp_enqueue_media();

	wp_enqueue_script('my_scripts', '... /my_scripts.js', array('jquery','jquery-ui-sortable') );
}

function misha_gallery_field( $name, $value = '' ) {

	$html = '<div><ul class="misha_gallery_mtb">';
	/* array with image IDs for hidden field */
	$hidden = array();

	
	if( $images = get_posts( array(
		'post_type' => 'attachment',
		'orderby' => 'post__in', /* we have to save the order */
		'order' => 'ASC',
		'post__in' => explode(',',$value), /* $value is the image IDs comma separated */
		'numberposts' => -1,
		'post_mime_type' => 'image'
	) ) ) {

		foreach( $images as $image ) {
			$hidden[] = $image->ID;
			$image_src = wp_get_attachment_image_src( $image->ID, array( 80, 80 ) );
			$html .= '<li data-id="' . $image->ID .  '"><span style="background-image:url(' . $image_src[0] . ')"></span><a href="#" class="misha_gallery_remove">&times;</a></li>';
		}

	}

	$html .= '</ul><div style="clear:both"></div></div>';
	$html .= '<input type="hidden" name="'.$name.'" value="' . join(',',$hidden) . '" /><a href="#" class="button misha_upload_gallery_button">Add Images</a>';

	return $html;
}

/*
 * Add a meta box
 */
add_action( 'admin_menu', 'misha_meta_box_add' );
 
function misha_meta_box_add() {
	add_meta_box('mishadiv', // meta box ID
		'More settings', // meta box title
		'misha_print_box', // callback function that prints the meta box HTML 
		'post', // post type where to add it
		'normal', // priority
		'high' ); // position
}
 
/*
 * Meta Box HTML
 */
function misha_print_box( $post ) {
	$meta_key = 'some_custom_gallery';
	echo misha_gallery_field( $meta_key, get_post_meta($post->ID, $meta_key, true) );
}
 
/*
 * Save Meta Box data
 */
add_action('save_post', 'misha_save');
 
function misha_save( $post_id ) {
	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
		return $post_id;
 
	$meta_key = 'some_custom_gallery';
 
	update_post_meta( $post_id, $meta_key, $_POST[$meta_key] );
 
	return $post_id;
}
Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on Twitter