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">×</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">×</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

I love WordPress, WooCommerce and Gutenberg so much. 11 yrs of experience.

Need some custom developer help? Get in touch