1

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();

    });
});
3
  • 2
    I'm unaware of any previous questions you've asked. For the purposes of context could you state clearly in 1 sentence as concisely as possible what your question is? I get the feeling your second to last paragraph almost does that but it's buried amongst a lot of description. Treat it as a "How do I do X, I tried Y, here are the details of what I have"
    – Tom J Nowell
    Feb 14, 2013 at 9:54
  • I've edited the question :). Feb 14, 2013 at 11:36
  • Edited question again and provided two versions of working code (ready to paste to functions.php and admin.js) for testing. Feb 14, 2013 at 12:12

1 Answer 1

5

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:

jQuery(document).ready(function($){
    $('.media-upload-button').click(function(e) {
        e.preventDefault();
        upload_image($(this));
        return false; 
    });
});
function upload_image(el){
    var $ = jQuery;
    var custom_uploader;
    var button = $(el);
    var id = button.attr('id').replace('_button', '');
    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();
}

this way its you "overwrite" the select event each time its called, and its actualy what i use in my admin page class

1
  • And this saved my day - great solution, I've only corrected some little errors in Your code (function name an element name) and it wokrs like a charm. Thanks a lot :). Feb 14, 2013 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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