I’m creating a custom plugin and I need users to be able to upload multiple images. I want them to be able to do this through the built-in media page but through a modal/pop up from the plugins settings page.
Something similar is when using Thrive Architect
and selecting the Image
tab, a modal appears and it looks exactly like the media library on the admin screen. How do I achieve this?
I did a search for wordpress media modal
and it returns Javascript Reference/wp.media but I’m not entirely sure if this is what I am looking for.
Is this a built-in feature in WordPress or will I need to find my own way of creating this?
Lastly, any suggestions that others may have found are also welcomed! Always nice to know what solutions others have found.
Ah!
The classic issue anyone that’s cared about their users’ experience has come to face.
As per my experience, wp.media
is the way to go.
This is not my code, but it gets the job done. I’ve used it plenty.
I’ll explain what it does, piece by piece:
// Source: https://vedmant.com/using-wordpress-media-library-in-widgets-options/
jQuery(document).ready(function ($) {
$(document).on("click", ".upload_image_button", function (e) {
e.preventDefault();
var $button = $(this);
// Create the media frame.
var file_frame = wp.media.frames.file_frame = wp.media({
title: 'Select or upload image',
library: { // remove these to show all
type: 'image' // specific mime
},
button: {
text: 'Select'
},
multiple: false // Set to true to allow multiple files to be selected
});
// When an image is selected, run a callback.
file_frame.on('select', function () {
// We set multiple to false so only get one image from the uploader
var attachment = file_frame.state().get('selection').first().toJSON();
$button.siblings('input').val(attachment.url).change();
});
// Finally, open the modal
file_frame.open();
});
});
First thing’s first. We need a button, tied to an input, more about this later on. This can be in the customizer, or it can be anywhere you need it to be:
<button class="upload_image_button">Upload Image</button>
Then we need an ingester of data that is tied to this button. Unfortunately, this is out-of-scope, but assuming you’re doing this in a widget, this will to the trick:
<p>
<label for="<?php echo $this->get_field_id( 'image' ); ?>">Image:</label>
<br>
<input class="widefat" id="<?php echo $this->get_field_id( 'image' ); ?>" name="<?php echo $this->get_field_name( 'image' ); ?>" value="<?php echo $instance['image'];?>" />
<br>
<button class="upload_image_button">Upload Image</button>
</p>
So far, we’re just targeting the button, going on:
// Create the media frame.
var file_frame = wp.media.frames.file_frame = wp.media({
title: 'Select or upload image',
library: { // remove these to show all
type: 'image' // specific mime
},
button: {
text: 'Select'
},
multiple: false // Set to true to allow multiple files to be selected
});
The code is well commented, but here’s the correspondent documentation files: https://codex.wordpress.org/Javascript_Reference/wp.media
So we’re just calling the WP JS API to access the media-frame. Now, on to getting the file path we need:
file_frame.on('select', function () {
Whenever we select something from the frame, get the path of the said file in an AJAX call, JSON format and let me use it –
var attachment = file_frame.state().get('selection').first().toJSON();
Remember that button that had to be connected to an input? Yea, so we insert this link we just got into that input:
$button.siblings('input').val(attachment.url).change();
And thus, a new link to your image is born.