Creating custom metaboxes and the built in uploader

I’ve been browsing for a way to use my own up-loader in a custom metabox.

While the best way is to check out Matt’s post.

But the problem arose when I used the custom metabox and uploader on a post or page. It overwrote the insert to post feature, not allowing an image to be sent to the edit field.

If you follow Matt’s instructions you’ll have to modify two code snippets to make it work with posts and pages.

An example of a custom upload metabox field
An example of a custom upload metabox field

First, remove the if statements that will check if it’s a plugin or theme setting page. I’m sure there is a way to only apply this to post.php and page.php..

if (isset($_GET['page']) && $_GET['page'] == 'my_plugin_page') {
    add_action('admin_print_scripts', 'my_admin_scripts');
    add_action('admin_print_styles', 'my_admin_styles');
}

Second, change the javascript file to read:

jQuery(document).ready(function() {
	
	var formfield;
	
	jQuery('#Image_button').click(function() {
		jQuery('html').addClass('Image');
		formfield = jQuery('#Image').attr('name');
		tb_show('', 'media-upload.php?type=image&TB_iframe=true');
		return false;
	});
	
	// user inserts file into post. only run custom if user started process using the above process
	// window.send_to_editor(html) is how wp would normally handle the received data

	window.original_send_to_editor = window.send_to_editor;
	window.send_to_editor = function(html){

		if (formfield) {
			fileurl = jQuery('img',html).attr('src');
			
			jQuery('#Image').val(fileurl);

			tb_remove();
			
			jQuery('html').removeClass('Image');
			
		} else {
			window.original_send_to_editor(html);
		}
	};

});

Of course, be sure to change the ID’s to read like your meta fields..

That’s it, now your media uploader with work with the editor and custom metabox.

Links

27 comments on “Creating custom metaboxes and the built in uploader

  1. It seems that you forgot the my_admin_script and my_admin_style function. I’ve read the the first link in your reference, and there they are.

  2. I try the above code under wordpress 3.0 beta 2, it seems that the send_to_editor function has never been called. any idea what am i missing?

    1. No not sure, it’s been working for me in test developments in WordPress 3 since before beta and even now with the latest release candidate.

      1. thnx for the reply frost, anyway do you have a working plugin that uses this code or functionality?

  3. I cannot get this to work. I’ve even tried changing all the ids and classes… the code still posts to my meta field ALWAYS…even if I try to post an image to my Editor box.

    Very very strange.

  4. I need a bit of help here… this works perfectly and is a great deal of help for me but what I would like to do is make it so that when you click on the image after its been uploaded it takes you directly to the “edit image” page… Any idea how i can achieve this?

  5. “I’m sure there is a way to only apply this to post.php and page.php..”

    Absolutely.

    The following adds your code to every admin page:

    add_action(‘admin_print_scripts’, ‘my_admin_scripts’);
    add_action(‘admin_print_styles’, ‘my_admin_styles’);

    Not Good.

    Should be:

    add_action(‘admin_print_scripts-post.php’, ‘my_admin_scripts’);
    add_action(‘admin_print_styles-post.php’, ‘my_admin_styles’ );

    This will only add your code to the post and page edit pages.

    I hope that helps.

  6. I went ahead and packed up a variation on your code as a jQuery plugin (well, not quite a pristine plugin, but hopefully clean and relatively easy to use in this context). Hopefully I get your markup right:

    (function (window, $) {	
    	jQuery.fn.wpMediaBox = function (options) {	
    		var inputEl, defaults, eL, opts, originalSendToEditor;
    
    		if (window.send_to_editor) {			
    			originalSendToEditor = window.send_to_editor;
    		}
    	
    		defaults = {		
    			'type' : 'image'			
    		};
    	
    		opts = jQuery.extend(defaults, options);		
    		eL = jQuery(this);
    		
    		eL.click(function () {			
    			inputEl = opts.inputID;
    			
    			tb_show('', 'media-upload.php?type=' + opts.type + '&TB_iframe=true');			
    			return false;			
    		});
    		
    		window.send_to_editor = function (html) {
    			var imgurl;
    			
    			if (inputEl === opts.inputID) {
    				imgurl = jQuery(html).attr("href");
    				jQuery('#' + inputEl).val(imgurl);
    				tb_remove();
    				inputEl = false;
    			} else {
    				originalSendToEditor(html);
    			}
    		};		
    	};
    	
    }(this, jQuery));
    
    
  7. I found that if you uploaded something in the metabox and then tried to add an image in the original post, that the send_to_editor function was still triggering your modified version… b/c formfield still had a value. i tweaked that by setting formfield back to nothing at the end of your if statement.

    i’ve also changed to a class based selector so that i can use it multiple times.

    http://pastebin.com/PaQzsB4z

  8. Thought I’d share with you a little further hack I developed. One of the things about this that has driven me crazy is the “Insert Into Post” button reading, well, “Insert Into Post” when using the Media Upload for purposes OTHER than inserting into post.

    So, if you declare this variable (right next to where you declared formfield):
    var formfield, tbframe_interval;

    then, add this line of code in the “click” function:

    tbframe_interval = setInterval(function() {jQuery('#TB_iframeContent').contents().find('.savesend .button').val('Use This Image');}, 2000);
    

    then in the “send_to_editor” function, add this:

    clearInterval(tbframe_interval);
    

    What you get is the button reading “Use This Image” instead of “Insert Into Post”.

  9. @Cale – thanks for the “hack”!! that has always bothered me about using the media uploader for other purposes- such as theme options and meta boxes.

  10. Im trying to make mine able to handla multiple images. But i cant really get the button working if a add new fields via javascript. Here’s my code:

    jQuery(document).ready(function($) {
    var formfield;
    tbframe_interval = setInterval(function() {jQuery(‘#TB_iframeContent’).contents().find(‘.savesend .button’).val(‘Använd den här bilden’);}, 2000);
    $(‘.upload_image_button’).click(function() {
    formfield = $(this).prev(‘input’);
    tb_show(”, ‘media-upload.php?type=image&TB_iframe=true’);
    return false;
    });

    window.original_send_to_editor = window.send_to_editor;
    window.send_to_editor = function(html){
    if (formfield) {
    fileurl = $(‘img’,html).attr(‘src’);
    formfield.val(fileurl);
    tb_remove();
    formfield = ”; //reset formfield to null
    } else {
    window.original_send_to_editor(html);
    }
    clearInterval(tbframe_interval);
    };

    }); //end doc-ready

    Here’s a video showing the problem.. Please help!

    http://vimeo.com/26491327

  11. it is a good idea but the problem is that this method works fine only in the first time. i explain :
    first the user select an image for defaut editor ==> OK
    second he user select an image for custom editor ==> OK
    third the user select an image for defaut editor ==> KO
    why ? because the var formfield will be always true when the click first time excutes…
    im still looking for a solution…

  12. I added “formfield = null;” just before the “jQuery(‘html’).removeClass(‘upload_image’);” line, so I can still use the editor later, and I also changed some lines as follows:

    jQuery(document).ready(function() {
    var formfield;
    var $image_input;

    jQuery(‘.upload_image_button’).click(function() {
    jQuery(‘html’).addClass(‘upload_image’);
    var $cont = jQuery(this).parent();
    $image_input = jQuery(‘input[type=text]’, $cont);
    formfield = $image_input.attr(‘name’);
    tb_show(”, ‘media-upload.php?type=image&TB_iframe=true’);
    tbframe_interval = setInterval(function() {jQuery(‘#TB_iframeContent’).contents().find(‘.savesend .button’).val(‘Use image’);}, 2000);
    return false;
    });

    window.original_send_to_editor = window.send_to_editor;
    window.send_to_editor = function(html){
    clearInterval(tbframe_interval);
    if (formfield) {
    fileurl = jQuery(‘img’,html).attr(‘src’);

    $image_input.val(fileurl);

    tb_remove();

    formfield = null;
    jQuery(‘html’).removeClass(‘upload_image’);

    } else {
    window.original_send_to_editor(html);
    }
    };

    });

    So I can use many image buttons in the same screen.

    Thanks for the code!
    Cheers!

  13. This has been very helpful. Had used the webmaster-source.com article as I was adding a secondary upload button to my WEBphysiology Portfolio plugin’s portfolio edit screen. However that method was hijacking the standard media uploader, which was fine until someone wanted to add an image to the content (description) area of the custom (portfolio) post type. Now they can!

    Thanks!

  14. Thankyou so much for this. So simple, can’t understand why people don’t caveat that tbshow media upload code with this!

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>