web-dev-qa-db-fra.com

Modifier un champ personnalisé dans la médiathèque à l'aide de JavaScript

J'ai ajouté un champ personnalisé à mes pièces jointes multimédia:

function set_image_data( $form_fields, $post ) {

    $form_fields['text_color'] = array(
        'label' => 'Text Color',
        'input' => 'text',
        'value' => get_post_meta( $post->ID, '_text_color', true )
    );

    return $form_fields;
}
add_filter( 'attachment_fields_to_edit', 'set_image_data', 10, 2 );

Ce qui est bien et dandy, mais maintenant j'aimerais ajouter Colorpicker (je comprends que c'est obsolète) au champ ci-dessus. Malheureusement, jQuery ne semble pas avoir d'effet, car la médiathèque est dynamique. J'ai essayé des gestionnaires mais je n'arrive pas à saisir l'entrée pour même y placer une val() générique.

Je crois qu'une fois que j'ai compris comment modifier le champ, je devrais être capable de comprendre comment attacher Colorpicker au champ.

Comment utiliser JS ou jQuery pour modifier le champ ci-dessus sur une base pièce jointe à pièce jointe dans la médiathèque?

3
Howdy_McGee

Une façon de le faire (ce qui est probablement mauvais) consiste à sélectionner le contrôle en ajoutant un bloc de javascript à l'aide du champ tr de $form_fields:

function set_image_data( $form_fields, $post ) {

    $form_fields['text_color'] = array(
        'label' => 'Text Color',
        'input' => 'text',
        'value' => get_post_meta( $post->ID, '_text_color', true )
    );
    ob_start();
    ?>
    <script type="text/javascript">
    jQuery('[name$="[text_color]"]').myColorPicker();
    </script>
    <?php
    $text_color_js = ob_get_clean();
    $form_fields['text_color_js'] = array(
        'tr' => $text_color_js, // Adds free-form stuff to table.
    );

    return $form_fields;
}
add_filter( 'attachment_fields_to_edit', 'set_image_data', 10, 2 );

Le javascript utilise une version personnalisée de wpColorPicker qui remplace la close pour déclencher un événement change (nécessaire car le champ caché text_color ne reçoit/perd jamais le focus, donc ne le fait pas lui-même):

add_action( 'admin_print_footer_scripts', function () {
        ?>

        <script type="text/javascript">
        jQuery(function ($) {
            // Extend wpColorPicker to trigger change on close.
            $.widget('custom.myColorPicker', $.wp.wpColorPicker, {
                close: function () {
                    this._super();
                    if (this.initialValue !== this.element.val()) {
                        this.element.change();
                    }
                }
            });
        });
        </script>

        <?php
}, 50 );

Vous pouvez éventuellement encapsuler ce qui précède dans une condition afin qu'il n'inclue que le script lors du téléchargement, mais il peut ne pas se déclencher dans certains cas.

if ( get_current_screen()->base == 'upload' ) {}

Ensuite, il y a des choses standard pour charger wp-color-picker et sauvegarder les données:

add_action( 'admin_enqueue_scripts', function () {
    if ( get_current_screen()->base == 'upload' ) {
        wp_enqueue_style( 'wp-color-picker' );
        wp_enqueue_script( 'wp-color-picker' );
    }
});
add_filter( 'attachment_fields_to_save', function ( $post, $attachment ) {
    if ( isset( $attachment['text_color'] ) ) {
        update_post_meta( $post['ID'], '_text_color', $attachment['text_color'] );
    }
    return $post;
}, 10, 2 );

Update

Cette utilisation a généré un bogue dans wpColorPicker (voir trac https://core.trac.wordpress.org/ticket/32856 ), en ce que si le sélecteur de couleur est laissé ouvert et que le modal Détails de la pièce jointe est fermé, une exception est jeté qui met les choses dans un état drôle. La solution de contournement consiste à ne pas appeler this._super(); dans la fermeture (très commodément remplacée) mais à répliquer le code à la place, avec le correctif:

add_action( 'admin_print_footer_scripts', function () {

        ?>
        <script type="text/javascript">
        jQuery(function ($) {
            // Extend wpColorPicker to trigger change on close.
            $.widget('custom.myColorPicker', $.wp.wpColorPicker, {
                close: function () {
                    this.element.hide();
                    if ( this.element.iris( 'instance' ) ) {
                        this.element.iris( 'toggle' );
                    }
                    this.button.addClass( 'hidden' );
                    this.toggler.removeClass( 'wp-picker-open' );
                    $( 'body' ).off( 'click.wpcolorpicker', this.close );
                    if (this.initialValue !== this.element.val()) {
                        this.element.change();
                    }
                }
            });
        });
        </script>
        <?php

}, 50 );
3
bonger