I'm making a custom field in a custom meta box in WordPress. I have input text fields, textareas, and checkboxes that are all working fine. I also included a browse button for the image gallery that is working.
When you click on the "Browse" button, it pulls up the WordPress media upload screen, and when you select that image, it will replace the input value (as well as an image thumbnail).
Here is the relevant part of the WordPress meta box set up.
function show_custom_fields_meta_box() {
global $post;
$meta = get_post_meta( $post->ID, 'custom_fields', true ); ?>
<input type="hidden" name="custom_meta_box_nonce" value="<?php echo wp_create_nonce( basename(__FILE__) ); ?>">
<!-- image upload field -->
<p>
<label for="custom_fields[image]">Image Upload</label><br>
<input type="text" name="custom_fields[image]" id="custom_fields[image]" class="meta-image regular-text" value="<?php echo $meta['image']; ?>">
<input type="button" class="button image-upload" value="Choose or Upload an Image">
<div class="image-preview"><img src="<?php echo $meta['image']; ?>" style="max-width: 250px;"></div>
</p>
}
And here's the jQuery I'm using to open the WordPress media gallery and upload the image.
<script>
/*
* Attaches the image uploader to the input field
*/
jQuery(document).ready(function ($) {
// Instantiates the variable that holds the media library frame.
var meta_image_frame;
// Runs when the image button is clicked.
$('.image-upload').click(function (e) {
// Prevents the default action from occuring.
e.preventDefault();
var selected = $(this);
var meta_image = $('.meta-image');
// If the frame already exists, re-open it.
if (meta_image_frame) {
meta_image_frame.open();
return;
}
// Sets up the media library frame
meta_image_frame = wp.media.frames.meta_image_frame = wp.media({
title: meta_image.title,
button: {
text: meta_image.button
}
});
// Runs when an image is selected.
meta_image_frame.on('select', function () {
// Grabs the attachment selection and creates a JSON representation of the model.
var media_attachment = meta_image_frame.state().get('selection').first().toJSON();
// Sends the attachment URL to our custom image input field.
$('.meta-image').val(media_attachment.url);
var imgurl = $('.meta-image').val();
$(selected).prev().val(imgurl);
$(selected).closest('div').find('.image-preview').children('img').attr('src',imgurl);
});
// Opens the media library frame.
meta_image_frame.open();
});
});
</script>
Now, this works perfectly fine as-is. The input
button has a class of .image-upload
, and the input
text field has a class of meta-image
.
However, if I add another field...(custom_fields[image2]
)
<p>
<label for="custom_fields[image2]">Image Upload</label><br>
<input type="text" name="custom_fields[image2]" id="custom_fields[image2]" class="meta-image regular-text" value="<?php echo $meta['image2']; ?>">
<input type="button" class="button image-upload" value="Choose or Upload an Image">
<div class="image-preview"><img src="<?php echo $meta['image2']; ?>" style="max-width: 250px;"></div>
</p>
The jQuery will apply to both browse buttons and text inputs, because it's a class. I know (think) I have to use some form of $(this)
to get the correct button and text input, but all of my efforts have been in vain so far.
I've tried $(this).closest('.meta-image')
, but that doesn't seem to work.
Thank you!