Skip to content

Instantly share code, notes, and snippets.

@RadGH
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RadGH/859622d84c8570402e58 to your computer and use it in GitHub Desktop.
Save RadGH/859622d84c8570402e58 to your computer and use it in GitHub Desktop.
Easily create a media browse button, automatically insert URL, title, thumbnail, alt text, etc. into other inputs automatically.
/*
Rad's WordPress Media Upload Button API
Serves as an easy-to-use relay between your form fields and the media browser.
----------
Example Usage:
Retrieve the image URL and the attachment ID of an image with a single "Browse" button, and display a preview of the selected image.
Upload an image:
<input
type="button"
value="Browse"
class="media-browse"
data-media-url="input[name='my-media-url'], img#my-media-preview"
data-media-id="input[name='my-media-id']"
/>
Preview:
<img src="" style="display: none;" id="my-media-preview" />
Attachment ID:
<input type="text" name="my-media-id" />
Image URL:
<input type="text" name="my-media-url" />
----------
HOW TO USE:
1. Load the media resources within wordpress. This code will load it on any post editor screen (post, page, or custom post types):
function posts_enqueue_media_scripts() {
$screen = get_current_screen();
if ( $screen->base == 'post' && $screen->id == 'page' ) wp_enqueue_media();
}
add_action('admin_enqueue_scripts', 'posts_enqueue_media_scripts');
2. Create your input(s) that will receive information about the image, such as the image URL, thumbnail, title, or attachment ID:
<input type="text" name="my-image-url" value="" />
3 (HTML). Create a button with class "media-browse" and attribute "data-media-url" which includes a selector pointing to the input above:
<a href="#" class="media-browse" data-media-url="#HELLOworld">Browse</a>
(JS). Assign the data-attributes listed below, such as "data-media-url", to the button of your choice. Initialize the media selector by using an event:
jQuery('input.my-upload-button').on('click', lm_media_add);
4. Click the button to browse, select an image. The image URL will be passed back to the input. This works for all "attachment" properties returned by the API, including:
id, title, filename, url, link, alt, author, description,
caption, name, status, uploadedTo, date, modified,
menuOrder, mime, type, subtype, icon, dateFormatted,
nonces, editLink, sizes, height, width, orientation, compat
Tip: Create a "media-remove" button as a sibling of your browse button to remove media, or bind an element's click event to the lm_media_remove function. You can give the remove button the attribute "data-browse-button" pointing to the browse button instead. Any field which will be modified by the browse button will be cleared when the remove button is pressed. (This does not physically remove the attachment from the server.)
Tip: Extend this functionality by listening for the selected attachment yourself with the custom event "attachment-selected" on your browse button. When a user finishes their selection, the event will be fired. The attachment data will be stored on the browse button via jQuery(this).data('attachment').
Tip: If you are having trouble directly referencing your fields, you can specify a parent container using data-container. This container should hold the browse button, as well as any elements linked to via data-media attributes. For example, if you have data-container="div.field-container" and data-media-url="input[type=text]", then only the text input which is a child of the .field-container will be affected. If you do not use data-container in this case, all of the text inputs on the page will be modified. The parent is selected via jQuery.closest(), where children are located with jQuery.find(). The removal button also supports the data-container property.
*/
var lm_media_file_frame;
var lm_media_btn; // The active button, stored between clicking on the button and selecting media (closing lightbox)
var lm_media_properties = [
'id', 'title', 'filename', 'url', 'link', 'alt', 'author', 'description',
'caption', 'name', 'status', 'uploadedTo', 'date', 'modified',
'menuOrder', 'mime', 'type', 'subtype', 'icon', 'dateFormatted',
'nonces', 'editLink', 'sizes', 'height', 'width', 'orientation', 'compat'
];
jQuery(init_media_browse_button);
function lm_media_remove(e) {
e.preventDefault();
if ( !wp || !wp.media ) {
alert('The media gallery is not available. You must admin_enqueue this function: wp_enqueue_media()');
return;
}
var $container = jQuery('body');
if ( jQuery(this).attr('data-container') ) $container = jQuery(this).closest( jQuery(this).attr('data-container') );
if ( jQuery(this).attr('data-browse-button') ) var $browse = $container.find( jQuery(this).attr('data-browse-button') );
else var $browse = jQuery(this).siblings('.media-browse');
if ( !$browse.length ) {
alert('No sibling browse button found, or the data-browse-button attribute had no matching elements');
return false;
}
$browse.data('attachment', false).trigger('attachment-removed');
// Trigger the update for the browse button's fields
for(i = 0; i < lm_media_properties.length; i++) {
var $browse_container = jQuery('body');
if ( $browse.attr('data-container') ) $browse_container = $browse.closest( $browse.attr('data-container') );
var media_key = lm_media_properties[i];
var selector = $browse.attr('data-media-' + media_key); // data-media-url, data-media-link, data-media-height
if ( selector ) {
var $target = $browse_container.find(selector);
if ( $target.length ) {
$target.val('').trigger('media-updated').trigger('change');
if ( $target.is('img') && media_key == 'url' ) {
$target.attr( 'src', '' );
}else if ( $target.is('a') && media_key == 'url' ) {
$target.attr( 'href', '' );
}else if ( $target.is(':input') ) {
$target.val( '' ).trigger('media-updated').trigger('change');
}else{
$target.text( '' );
}
}
}
}
return false;
}
function lm_media_add(e) {
e.preventDefault();
lm_media_btn = jQuery(this);
if ( !wp || !wp.media ) {
alert('The media gallery is not available. You must admin_enqueue this function: wp_enqueue_media()');
return;
}
// If the media frame already exists, reopen it.
if ( lm_media_file_frame ) {
lm_media_file_frame.open();
return;
}
// Create the media frame.
lm_media_file_frame = wp.media.frames.lm_media_file_frame = wp.media({
title: lm_media_btn.attr('data-media-title') || 'Browsing Media',
button: {
text: lm_media_btn.attr('data-media-text') || 'Select',
},
multiple: false // Set to true to allow multiple files to be selected
});
// When an image is selected, run a callback.
lm_media_file_frame.on( 'select', function() {
// We set multiple to false so only get one image from the uploader
attachment = lm_media_file_frame.state().get('selection').first().toJSON();
// Extend this plugin yourself by binding the "attachment-selected" event to the button.
lm_media_btn.data('attachment', attachment).trigger('attachment-selected');
var $container = jQuery('body');
if ( lm_media_btn.attr('data-container') ) $container = lm_media_btn.closest( lm_media_btn.attr('data-container') );
// Allow each file property to be assigned to a field. Fields are referenced by the button's data attrbiutes
// All methods support a data attribute.
// data-media-{index}
// Example:
// attachment.url is assigned to the element matching the value of the "data-media-url" attribute (if available)
for(i = 0; i < lm_media_properties.length; i++) {
var media_key = lm_media_properties[i];
var selector = lm_media_btn.attr('data-media-' + media_key); // data-media-url, data-media-link, data-media-height
if ( selector ) {
var $target = $container.find(selector);
if ( !$target.length ) {
if ( console && console.log ) {
console.log('Selector contains zero matched elements:', selector, 'Value expected:', attachment[media_key]);
continue;
}
}
// Assign the target field the given value, and trigger two events for developers to check for
// Images can have the URL set as their src automatically (Only works for URL). Inputs will use .val(). Everything else will use .text().
$target.each(function() {
if ( jQuery(this).is('img') && media_key == 'url' ) {
jQuery(this).attr( 'src', attachment[media_key] );
}else if ( jQuery(this).is('a') && media_key == 'url' ) {
jQuery(this).attr( 'href', attachment[media_key] );
}else if ( jQuery(this).is(':input') ) {
jQuery(this).val( attachment[media_key] ).trigger('media-updated').trigger('change');
}else{
jQuery(this).text( attachment[media_key] );
}
jQuery(this).trigger('media-updated').trigger('change');
});
}
}
});
// Finally, open the modal
lm_media_file_frame.open();
}
function init_media_browse_button() {
jQuery('.media-remove').on( 'click', lm_media_remove );
jQuery('.media-browse').on( 'click', lm_media_add );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment