70

WordPress 3.5 has been released recently, I used the WordPress Media Upload system via thickbox and window.send_to_editor for some options in my WordPress theme (backgrounds, logos etc...).

But as you know WordPress has integrated a new Media Manager, I wanted to used this new feature to upload images/files as custom fields. So I spent the morning to find a way to get the wished result.

I found with this solution, which can be useful for some of you. Thanks to give me your feedback on the code or any improvements you have in mind!

HTML Sample:

<a href="#" class="custom_media_upload">Upload</a>
<img class="custom_media_image" src="" />
<input class="custom_media_url" type="text" name="attachment_url" value="">
<input class="custom_media_id" type="text" name="attachment_id" value="">

jQuery Code:

$('.custom_media_upload').click(function() {

    var send_attachment_bkp = wp.media.editor.send.attachment;

    wp.media.editor.send.attachment = function(props, attachment) {

        $('.custom_media_image').attr('src', attachment.url);
        $('.custom_media_url').val(attachment.url);
        $('.custom_media_id').val(attachment.id);

        wp.media.editor.send.attachment = send_attachment_bkp;
    }

    wp.media.editor.open();

    return false;
});

If you want to see every settings contained in the attachment variable you can do a console.log(attachment) or alert(attachment).

Maxime
  • 8,645
  • 5
  • 50
  • 53
Mattpx
  • 721
  • 1
  • 6
  • 8
  • 1
    Wordpress admin uses noConflict so I had to change the $ -> jQuery. Very helpful thanks! – styks Dec 14 '12 at 16:33
  • Thanks a zillion for that crisp example! Passing a post ID is as simple as passing it as a param in the wp.media.editor.open() – Jos Dec 16 '12 at 20:06
  • I'm wondering how to load Media API as dependency to some script in `wp_enqueue_script()`. I know that `wp_enqueue_media()` is there but I'd prefer to use dependency - is there a way to do this? – Atadj Jan 24 '13 at 11:07

5 Answers5

35

Your going about it in a way that was unintended. Your javascript code should probably look something like this:

$('.custom_media_upload').click(function(e) {
    e.preventDefault();

    var custom_uploader = wp.media({
        title: 'Custom Title',
        button: {
            text: 'Custom Button Text'
        },
        multiple: false  // Set this to true to allow multiple files to be selected
    })
    .on('select', function() {
        var attachment = custom_uploader.state().get('selection').first().toJSON();
        $('.custom_media_image').attr('src', attachment.url);
        $('.custom_media_url').val(attachment.url);
        $('.custom_media_id').val(attachment.id);
    })
    .open();
});
DiverseAndRemote.com
  • 19,314
  • 10
  • 61
  • 70
  • Can you suggest me how to remove the media library option from the uploader – user930026 Jun 20 '13 at 12:14
  • `custom_uploader.on('open', function(){...customize...})` ? – NoBugs Aug 03 '13 at 04:46
  • 5
    does anyone know full list of arguments for `wp.media()`? For instance it has library too, and it takes type, but I'd like to exclude certain ID's from the select options. – Ciantic Dec 12 '13 at 20:47
  • It opens the instance 2 times, I don't get it why is this like that? Thanks – Herr Nentu' Jan 02 '14 at 15:16
  • I don't think the full list of arguments are documented but if you want you can look at the code in `wp-includes/js/media-views.js`. Just search for "media.controller.Library =" – DiverseAndRemote.com Oct 22 '14 at 15:37
33

Don't forget to use wp_enqueue_media (new in 3.5) if you'r not on the post edit page

To use the old media upload box you can do this:

if(function_exists( 'wp_enqueue_media' )){
    wp_enqueue_media();
}else{
    wp_enqueue_style('thickbox');
    wp_enqueue_script('media-upload');
    wp_enqueue_script('thickbox');
}
Xaver
  • 11,144
  • 13
  • 56
  • 91
  • 1
    I'm wondering how to load Media API as dependency to some script in `wp_enqueue_script()`. I know that `wp_enqueue_media()` is there but I'd prefer to use dependency - is there a way to do this? I'm looking for names of all required libraries - like you do with pre-WP3.5 media scripts in your example. – Atadj Jan 24 '13 at 11:14
  • Best to check out the source what exactly get enqueued: http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/media.php#L1437 – Xaver Feb 13 '13 at 10:42
7

I modified this code a bit more to make it usable for multiple fields at once:

HTML:

<!-- Image Thumbnail -->
<img class="custom_media_image" src="" style="max-width:100px; float:left; margin: 0px     10px 0px 0px; display:inline-block;" />

<!-- Upload button and text field -->
<input class="custom_media_url" id="" type="text" name="" value="" style="margin-bottom:10px; clear:right;">
<a href="#" class="button custom_media_upload">Upload</a>

jQuery:

jQuery(document).ready(function($){

$('.custom_media_upload').click(function() {

        var send_attachment_bkp = wp.media.editor.send.attachment;
        var button = $(this);

        wp.media.editor.send.attachment = function(props, attachment) {

            $(button).prev().prev().attr('src', attachment.url);
            $(button).prev().val(attachment.url);

            wp.media.editor.send.attachment = send_attachment_bkp;
        }

        wp.media.editor.open(button);

        return false;       
    });

});
JasonDavis
  • 48,204
  • 100
  • 318
  • 537
4

I found nothing to trigger a custom function if the editor closes. I uses this:

wp.media.editor.open();
$('.media-modal-close, .media-modal-backdrop').one('click', function(){
    //do some stuff
});

or better:

var id = wp.media.editor.id();
var editor = wp.media.editor.get( id );
if('undefined' != typeof( editor )) editor = wp.media.editor.add( id );

if ( editor ) {
    editor.on('close', function(){
        //do some stuff
    });
}
Xaver
  • 11,144
  • 13
  • 56
  • 91
  • There are `close` and `escape`, among other events, that you can bind on the `wp.media` object. For example, `wp.media.editor.add('content').on('all',function(n){alert(n);})` – NoBugs Jan 09 '13 at 06:32
3

I haven't had much chance to play with this, but for those looking to leverage the gallery element, this code should set you on your way.

It is just a start point - it only provides a comma separated list of image id's, but that should be enough to start being creative.

<input id="custom_media_id" type="text" name="attachment_id" value="">
<a href="#" class="button custom_media_upload" title="Add Media">Add Media</a>

<script type="text/javascript">
  jQuery('.custom_media_upload').click(function() {
    var clone = wp.media.gallery.shortcode;
    wp.media.gallery.shortcode = function(attachments) {
    images = attachments.pluck('id');
    jQuery('#custom_media_id').val(images);
    wp.media.gallery.shortcode = clone;
    var shortcode= new Object();
    shortcode.string = function() {return ''};
    return shortcode;
  }
jQuery(this).blur(); // For Opera. See: http://core.trac.wordpress.org/ticket/22445
wp.media.editor.open();
return false;       
});
</script>

This will populate the input field with a comma separated list of the image id's, in the order they were set in the editor (using the new drag and drop functionality).

The function expects the shortcode to be sent back for placement in the main editor, but we don't want to do this, so we create a new object that returns a blank string for insertion.

Also note, this doesn't handle inserting a single image as described above - it'll just put it into the post editor. So try combining the two listeners, or remove the appropriate tabs.

EDIT

Having spent some time looking at the core, I think this whole process can actually be done easier using the technique laid out here, but as you'll read I haven't figured out yet how to pre-select the images when you reopen the media manager.

Community
  • 1
  • 1
Mark
  • 3,005
  • 1
  • 21
  • 30