Skip to content

Instantly share code, notes, and snippets.

@westonruter
Last active November 26, 2018 21:17
Show Gist options
  • Save westonruter/9676069 to your computer and use it in GitHub Desktop.
Save westonruter/9676069 to your computer and use it in GitHub Desktop.
Test widget plugin for WordPress issue #27491: Widget Customizer: Dynamically-created inputs cause from to replace itself without event to trigger re-initialization https://core.trac.wordpress.org/ticket/27491
[submodule "chosen"]
path = chosen
url = git@github.com:harvesthq/chosen.git
/*global jQuery */
jQuery( function ( $ ) {
function init( widget_el, is_cloned ) {
// Clean up from the clone which lost all events and data
if ( is_cloned ) {
widget_el.find( '.chosen-container' ).remove();
}
widget_el.find( 'select.dynamic-field-chosen-select' ).chosen( { width: '100%' } );
}
/**
* @param {jQuery.Event} e
* @param {jQuery} widget_el
*/
function on_form_update( e, widget_el ) {
if ( 'dynamic_fields_test' === widget_el.find( 'input[name="id_base"]' ).val() ) {
init( widget_el, 'widget-added' === e.type );
}
}
$( document ).on( 'widget-updated', on_form_update );
$( document ).on( 'widget-added', on_form_update );
$( '.widget:has(.dynamic-field-chosen-select)' ).each( function () {
init( $( this ) );
} );
} );
<?php
/**
* Plugin Name: Customize Widget Dynamic Fields Test
* Description: For testing purposes.
* Author: Weston Ruter, X-Team
* Author URI: http://x-team.com/profile/weston-ruter/
*/
class Dynamic_Fields_Test_Widget extends WP_Widget {
public $chosen_options;
function __construct() {
parent::__construct(
'dynamic_fields_test',
'Dynamic Fields test',
array(
'description' => 'Test customizing widgets with dynamic fields.',
)
);
$this->chosen_options = array(
'' => __( '(None)' ),
'red' => __( 'Red' ),
'green' => __( 'Green' ),
'blue' => __( 'Blue' ),
);
}
/**
* Front-end display of widget.
*
* @param array $args Widget arguments.
* @param array $instance Saved values from database.
*/
public function widget( $args, $instance ) {
$instance = wp_parse_args( $instance, $this->default_instance() );
$title = apply_filters( 'widget_title', $instance['title'] );
echo $args['before_widget']; // xss ok
if ( ! empty( $title ) ) {
echo $args['before_title'] . $title . $args['after_title']; // xss ok
}
echo '<pre>';
echo esc_html( print_r( $instance, true ) );
echo '</pre>';
echo $args['after_widget']; // xss ok
}
/**
* Back-end widget form.
*
* @param array $instance Previously saved values from database.
* @return void
*/
public function form( $instance ) {
wp_enqueue_style(
'chosen',
plugin_dir_url( __FILE__ ) . '/chosen/chosen.css'
);
wp_enqueue_script(
'chosen',
plugin_dir_url( __FILE__ ) . '/chosen/chosen.jquery.js',
array( 'jquery' )
);
wp_enqueue_script(
'dynamic-fields-test-widget',
plugin_dir_url( __FILE__ ) . '/' . basename( __FILE__, '.php' ) . '.js',
array( 'jquery', 'chosen' )
);
$instance = wp_parse_args( $instance, $this->default_instance() );
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id( 'chosen' ); ?>"><?php _e( 'Chosen:' ); ?></label>
<select id="<?php echo $this->get_field_id( 'chosen' ); ?>" class="dynamic-field-chosen-select" name="<?php echo $this->get_field_name( 'chosen' ); ?>">
<?php foreach ( $this->chosen_options as $value => $text ): ?>
<option value="<?php echo esc_attr( $value ) ?>" <?php selected( $value, $instance['chosen'] ) ?>><?php echo esc_html( $text ) ?></option>
<?php endforeach; ?>
</select>
</p>
<p>
<?php _e( 'Form loaded at: ' ) ?><?php echo date( 'H:m:s' ) ?>
</p>
<?php
}
/**
* @return array
*/
public function default_instance() {
return array(
'title' => '',
'chosen' => '',
);
}
/**
* Sanitize widget form values as they are saved.
*
* @see WP_Widget::update()
*
* @param array $new_instance Values just sent to be saved.
* @param array $old_instance Previously saved values from database.
*
* @return array Updated safe values to be saved.
*/
public function update( $new_instance = array(), $old_instance = array() ) {
$instance = wp_parse_args( $new_instance, $this->default_instance() );
$instance['title'] = strip_tags( $new_instance['title'] );
if ( ! isset( $this->chosen_options[ $instance['chosen'] ] ) ) {
$instance['chosen'] = '';
}
return $instance;
}
}
add_action( 'widgets_init', function () {
register_widget( 'Dynamic_Fields_Test_Widget' );
} );
@iLenTheme
Copy link

I have the same problem but found this https://core.trac.wordpress.org/ticket/19675 yet still can not load the script then to drag the widget

@iLenTheme
Copy link

add a new field in all widget but in the event you add it to a sidebar do not load me the script, specifically a "WpColorPicker' but I do not load, I only load when save but when dragging no longer works for me.

http://i.imgur.com/fv3xTcD.png

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment