Two ways of doing the same thing:
First one:
var _custom_media = true,
_orig_send_attachment = wp.media.editor.send.attachment;
$('.media-upload-button').click(function(e) {
var send_attachment_bkp = wp.media.editor.send.attachment;
var button = $(this);
var id = button.attr('id').replace('_button', '');
console.log(id);
_custom_media = true;
wp.media.editor.send.attachment = function(props, attachment){
if ( _custom_media ) {
$('#'+id).val(attachment.url);
$('#'+id).prev().attr('src', attachment.url);
console.log(id);
} else {
return _orig_send_attachment.apply( this, [props, attachment] );
};
}
wp.media.editor.open(button);
return false;
});
$('.add_media').on('click', function(){
_custom_media = false;
});
Second one:
$('.media-upload-button').click(function(e) {
e.preventDefault();
var button = $(this);
var id = button.attr('id').replace('_button', '');
console.log(id);
//If the uploader object has already been created, reopen the dialog
if (custom_uploader) {
custom_uploader.open();
return;
}
//Extend the wp.media object
custom_uploader = wp.media.frames.file_frame = wp.media({
title: 'Wybierz zdjÄcie',
button: {
text: 'Wybierz zdjÄcie'
},
multiple: false
});
//When a file is selected, grab the URL and set it as the text field's value
custom_uploader.on('select', function() {
attachment = custom_uploader.state().get('selection').first().toJSON();
$('#'+id).val(attachment.url);
$('#'+id).prev().attr('src', attachment.url);
//console.log(attachment);
console.log(id);
//custom_uploader.close();
});
//Open the uploader dialog
custom_uploader.open();
});
Both works well when there is only one field/button that they are “attached” to, but if there is more than one, only first works ok. The second one always insert data to firstly clicked button/field, even if You click second one (second console.log shows oryginal “id” that is diffrent than one showed in console after click of button).
But the second interface looks better for a designed job, so the question is – how the second code should be changed, so it can work with multiple input fields/buttons?
AFAIK, the problem with second code is, that Media Manager object that is being created once, stays “in memory” so second callout only displays it, and doesnt ovverrite oryginal “custom_uploader.on” with initial id in it. Maybe somehow object should be destroyed after closing it?
To clear thing out – question is: how should I use wp.media.frames.file_frame correctly with more than one button/field instead of wp.media.editor.send.attachment?
Ps… for those, who would like to test entire code:
functions.php:
add_action( 'add_meta_boxes', 'cs_products_mb_create' );
function cs_products_mb_create() {
//create a custom meta box
add_meta_box( 'products-info', 'Ustawienia Produktu', 'cs_products_mb_function', 'posts', 'normal', 'high' );
}
function cs_products_mb_function( $post ) { ?>
<div id="appcustomsettings">
<p><input id="cs_product_menu_img_src" type="text" name="cs_product_menu_img_src" value="" /> <input id="cs_product_menu_img_src_button" type="button" value="Add / Change" class="button-secondary media-upload-button" /></p>
<p><input id="cs_product_bg_img_src" type="text" name="cs_product_bg_img_src" value="" /> <input id="cs_product_bg_img_src_button" type="button" value="Add / Change" class="button-secondary media-upload-button" /></p>
</div>
<?php
}
add_action('admin_enqueue_scripts', 'cs_admin_customposttype_scripts');
function cs_admin_customposttype_scripts(){
wp_enqueue_media();
wp_enqueue_script( 'cs-image-upload', get_bloginfo('template_url').'/js/admin.js', array( 'jquery') );
}
Its stripped from loading and saving data, but it does what it should
The admin.js that works but uses wp.media.editor.send.attachment instead of wp.media.frames.file_frame:
jQuery(document).ready(function($){
var _custom_media = true,
_orig_send_attachment = wp.media.editor.send.attachment;
$('.media-upload-button').click(function(e) {
var send_attachment_bkp = wp.media.editor.send.attachment;
var button = $(this);
var id = button.attr('id').replace('_button', '');
console.log(id);
_custom_media = true;
wp.media.editor.send.attachment = function(props, attachment){
if ( _custom_media ) {
$('#'+id).val(attachment.url);
console.log(id);
} else {
return _orig_send_attachment.apply( this, [props, attachment] );
};
}
wp.media.editor.open(button);
return false;
});
$('.add_media').on('click', function(){
_custom_media = false;
});
});
And admin.js that uses and looks as I would like, but doesnt work coccectly with two or more inputs:
jQuery(document).ready(function($){
var custom_uploader;
$('.media-upload-button').click(function(e) {
e.preventDefault();
var button = $(this);
var id = button.attr('id').replace('_button', '');
console.log(id);
//If the uploader object has already been created, reopen the dialog
if (custom_uploader) {
custom_uploader.open();
return;
}
//Extend the wp.media object
custom_uploader = wp.media.frames.file_frame = wp.media({
title: 'Wybierz zdjÄcie',
button: {
text: 'Wybierz zdjÄcie'
},
multiple: false
});
//When a file is selected, grab the URL and set it as the text field's value
custom_uploader.on('select', function() {
attachment = custom_uploader.state().get('selection').first().toJSON();
$('#'+id).val(attachment.url);
//console.log(attachment);
console.log(id);
//custom_uploader.close();
});
//Open the uploader dialog
custom_uploader.open();
});
});
you can move the wp.media stuff to an external function which accepts the element as a parameter and call it on the click event like this:
this way its you “overwrite” the select event each time its called, and its actualy what i use in my admin page class