I’ve added a custom field into my media attachments:
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 );
Which is fine and dandy, but now I’d like to add Colorpicker ( I understand it is deprecated ) to the above field. Unfortunately, jQuery doesn’t seem to have an effect as the Media Library is dynamic. I’ve tried handlers but I can’t seem to catch the input to even place a generic val() into it.
I believe once I understand how to modify the field I should be able to grasp then how to attach Colorpicker to the field.
How can I use JS or jQuery to modify the field above on an attachment to attachment basis in the Media Library?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
One way to do it (which is probably evil) is to select the control by adding a block of javascript using the tr field of $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 );
The javascript is using a customized version of wpColorPicker that overrides the close to trigger a change event (needed since the hidden text_color field never gets/loses focus so doesn’t do it itself):
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 );
You could optionally wrap the above in a conditional so that it only includes the script on upload but it may not fire in some cases.
if ( get_current_screen()->base == 'upload' ) {}
Then there’s standard stuff to load wp-color-picker and save the data:
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
This usage threw up a bug in wpColorPicker (see trac https://core.trac.wordpress.org/ticket/32856) in that if the color picker is left open and the Attachment Details modal is closed, an exception is thrown which puts things into a funny state. The workaround is not to call this._super(); in the (very conveniently overridden) close but to replicate the code instead, with the fix:
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 );
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0