web-dev-qa-db-ja.com

JavaScriptを使用してメディアライブラリのカスタムフィールドを変更する

メディアの添付ファイルにカスタムフィールドを追加しました。

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

これは問題ありませんが、今度は上記のフィールドにColorpickerを追加したいと思います(これは廃止予定です)。残念ながら、メディアライブラリは動的であるため、jQueryは効果がないようです。私はハンドラを試したことがありますが、一般的なval()を入れるために入力を受け取ることができないようです。

フィールドの変更方法を理解したら、次にColorpickerをフィールドに接続する方法を理解することができるはずです。

メディアライブラリで添付ファイルごとにJSまたはjQueryを使用して上記のフィールドを変更する方法を教えてください。

3
Howdy_McGee

そのための1つの方法(これはおそらく邪悪です)は、$form_fieldstrフィールドを使用してjavascriptのブロックを追加することによってコントロールを選択することです。

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

JavascriptはwpColorPickerをオーバーライドするカスタマイズされたバージョンのcloseを使用してchangeイベントをトリガーします(隠されたtext_colorフィールドは決してフォーカスを取得または失うことはないので必要ありません)。

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

アップロード時にスクリプトのみを含めるようにオプションで上記を条件付きでラップすることもできますが、場合によっては起動しないことがあります。

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

それからwp-color-pickerをロードしてデータを保存する標準的なものがあります:

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

更新

この使用法はwpColorPicker(trac https://core.trac.wordpress.org/ticket/32856 を参照)のバグを投げかけることになります。 pickerは開いたままにしてAttachment Detailsモーダルを閉じます。物事を面白い状態にする例外がスローされます。この問題を回避するには、(非常に便利にオーバーライドされた)クローズでthis._super();を呼び出すのではなく、代わりにコードを複製して修正します。

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