1

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.

3

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.