I am working on a custom widget that includes a select options drop-down list of pages. When I select a page and save, the selected option does not stay selected. However, if I refresh the widgets page, the selected option (page) does show as selected.
class slideshow_widget extends WP_Widget {
// Main constructor
public function __construct() {
parent::__construct(
'slideshow_widget',
__( 'Slideshow', 'text_domain' ),
array(
'customize_selective_refresh' => true,
)
);
}
// The widget form (for the backend )
public function form( $instance ) {
// Set widget defaults
$defaults = array(
'title' => '',
'text' => '',
'textarea' => '',
'select_page' => '',
);
$links = array();
$pages = get_pages();
foreach ( $pages as $page ) {
$links[$page->ID] = array(
'title' => $page->post_title,
'url' => get_permalink( $page->ID )
);
}
// Parse current settings with defaults
extract( wp_parse_args( ( array ) $instance, $defaults ) ); ?>
<?php // Widget Title ?>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Widget Title:', 'text_domain' ); ?></label>
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
</p>
<?php // Text Field ?>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>"><?php _e( 'Slide Heading:', 'text_domain' ); ?></label>
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'text' ) ); ?>" type="text" value="<?php echo esc_attr( $text ); ?>" />
</p>
<?php // Textarea Field ?>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'textarea' ) ); ?>"><?php _e( 'Slide Text:', 'text_domain' ); ?></label>
<textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'textarea' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'textarea' ) ); ?>"><?php echo wp_kses_post( $textarea ); ?></textarea>
</p>
<?php // Dropdown ?>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'select_page' ) ); ?>"><?php _e( 'Target Page:', 'text_domain' ); ?></label>
<select class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'select_page' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'select_page' ) ); ?>" >
<?php foreach ( $links as $id => $link ): ?>
<option value="<?php echo $link['url'] ?>" <?php echo $this->get_field_id( 'select_page' ) == $link['url'] ? 'selected' : ''; ?> >
<?php echo $link['title'] ?>
</option>
<?php endforeach ?>
</select>
</p>
<?php }
// Update widget settings
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = isset( $new_instance['title'] ) ? wp_strip_all_tags( $new_instance['title'] ) : '';
$instance['text'] = isset( $new_instance['text'] ) ? wp_strip_all_tags( $new_instance['text'] ) : '';
$instance['textarea'] = isset( $new_instance['textarea'] ) ? wp_kses_post( $new_instance['textarea'] ) : '';
$instance['select_page'] = isset( $new_instance['select_page'] ) ? wp_strip_all_tags( $new_instance['select_page'] ) : '';
return $instance;
}
// Display the widget
public function widget( $args, $instance ) {
extract( $args );
// Check the widget options
$title = isset( $instance['title'] ) ? apply_filters( 'widget_title', $instance['title'] ) : '';
$text = isset( $instance['text'] ) ? $instance['text'] : '';
$textarea = isset( $instance['textarea'] ) ?$instance['textarea'] : '';
$select_page = isset( $instance['select_page'] ) ? $instance['select_page'] : '';
// WordPress core before_widget hook (always include )
echo $before_widget;
// Display the widget
echo '<div class="widget-text wp_widget_plugin_box">';
// Display widget title if defined
if ( $title ) {
echo $before_title . $title . $after_title;
}
// Display text field
if ( $text ) {
echo '<p>' . $text . '</p>';
}
// Display textarea field
if ( $textarea ) {
echo '<p>' . $textarea . '</p>';
}
// Display selected page field
if ( $select_page ) {
$page_url = parse_url($select_page, PHP_URL_PATH);
echo '<p>' . $page_url . '</p>';
}
echo '</div>';
// WordPress core after_widget hook (always include )
echo $after_widget;
}}
I was able to fix…
Replaced:
<?php foreach ( $links as $id => $link ): ?>
<option value="<?php echo $link['url'] ?>" <?php echo $this->get_field_id( 'select_page' ) == $link['url'] ? 'selected' : ''; ?> >
<?php echo $link['title'] ?>
</option><?php endforeach ?>
With:
<?php foreach ( $links as $id => $link ) { echo '<option value="' . esc_attr( $link['url'] ) . '" id="' . esc_attr( $id ) . '" '. selected( $select_page, $link['url'], false ) . '>'. $link['title'] . '</option>';} ?>