web-dev-qa-db-fra.com

3.5 Media Manager - Appel dans les métaboxes

Deux façons de faire la même chose:

Premier:

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

Deuxième:

$('.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();

});

Les deux fonctionnent bien quand il n'y a qu'un seul champ/bouton auquel ils sont "attachés", mais s'il y en a plus d'un, seul le premier fonctionne correctement. Le second insère toujours les données dans le premier bouton/champ cliqué, même si vous cliquez sur le second (le deuxième fichier console.log affiche un "identifiant" oryginal différent de celui affiché dans la console après un clic sur le bouton).

Mais la deuxième interface a meilleure apparence pour un travail conçu. La question est donc de savoir comment le deuxième code doit être modifié pour pouvoir fonctionner avec plusieurs champs/boutons de saisie.

Si je comprends bien, le problème avec le second code est que cet objet Media Manager créé une fois reste "en mémoire", de sorte que la seconde légende ne l'affiche que, et ne sur-écrive pas "custom_uploader.on" oryginal avec l'identifiant initial. Peut-être que quelque chose devrait être détruit après la fermeture?

Pour résoudre le problème, la question est la suivante: comment utiliser correctement wp.media.frames.file_frame avec plusieurs boutons/champs au lieu de wp.media.editor.send.attachment?

Ps ... pour ceux qui voudraient tester le code entier:

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') );
}

Il est dépourvu de chargement et de sauvegarde des données, mais il fait ce qu’il devrait

Le fichier admin.js qui fonctionne mais utilise wp.media.editor.send.attachment au lieu de 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;
    });
});

Et admin.js qui utilise et ressemble à ce que je voudrais, mais ne fonctionne pas de manière coccectuelle avec deux entrées ou plus:

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

    });
});
1
Marcin Bobowski

vous pouvez déplacer le fichier wp.media vers une fonction externe qui accepte l'élément en tant que paramètre et l'appeler lors de l'événement click de la manière suivante:

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

de cette façon, vous "écrasez" l'événement de sélection chaque fois qu'il est appelé et c'est ce que j'utilise dans ma classe de page

5
Bainternet