I've been trying to develop an image widget plugin for WordPress, and I've almost successfully done that thanks to the following code:
<?php
/*
Plugin Name: Title Page Widget (PB)
Plugin URI: http://www.example.com
Description: Creates a full-screen title page for a post (designed to used with Site Origin Page Builder)
Author: Me
Version: 1.0
Author URI: http://www.example.com
*/
// Block direct requests
if ( !defined('ABSPATH') )
die('-1');
add_action( 'widgets_init', function(){
register_widget( 'Title_Page_Widget' );
});
/**
* Adds Title_Page_Widget widget.
*/
class Title_Page_Widget extends WP_Widget {
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'Title_Page_Widget', // Base ID
__('Title Page Widget (PB)', 'text_domain'), // Name
array('description' => __( 'Creates a full-screen title page - designed for use with Site Origin\'s Page Builder plugin', 'text_domain' ),) // Args
);
add_action( 'sidebar_admin_setup', array( $this, 'admin_setup' ) );
}
function admin_setup(){
wp_enqueue_media();
wp_register_script('tpw-admin-js', plugins_url('tpw_admin.js', __FILE__), array( 'jquery', 'media-upload', 'media-views' ) );
wp_enqueue_script('tpw-admin-js');
wp_enqueue_style('tpw-admin', plugins_url('tpw_admin.css', __FILE__) );
}
/**
* Back-end widget form.
*
* @see WP_Widget::form()
*
* @param array $instance Previously saved values from database.
*/
public function form( $instance ) {
$title_text = ( isset( $instance['title_text'] ) ) ? $instance['title_text'] : '';
$title_image = ( isset( $instance['title_image'] ) ) ? $instance['title_image'] : '';
?>
<div class="titlepage_widget">
<h3>Title</h3>
<p>
<div class="widget_input">
<label for="<?php echo $this->get_field_id( 'title_text' ); ?>"><?php _e( 'Text :' ); ?></label>
<input class="title_text" id="<?php echo $this->get_field_id( 'title_text' ); ?>" name="<?php echo $this->get_field_name( 'title_text' ); ?>" value="<?php echo $title_text ?>" type="text"><br/>
</div>
<div class="widget_input">
<label for="<?php echo $this->get_field_id( 'title_image' ); ?>"><?php _e( 'Image :' ); ?></label>
<input class="title_image" id="<?php echo $this->get_field_id( 'title_image' ); ?>" name="<?php echo $this->get_field_name( 'title_image' ); ?>" value="<?php echo $title_image ?>" type="text"><button id="title_image_button" class="button" onclick="image_button_click('Choose Title Image','Select Image','image','title_image_preview','<?php echo $this->get_field_id( 'title_image' ); ?>');">Select Image</button>
</div>
<div id="title_image_preview" class="preview_placholder">
<?php
if ($title_image!='') echo '<img src="' . $title_image . '">';
?>
</div>
</p>
</div>
<?php
}
/**
* 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, $old_instance ) {
$instance = array();
$instance['title_text'] = ( ! empty( $new_instance['title_text'] ) ) ? strip_tags( $new_instance['title_text'] ) : '';
$instance['title_image'] = ( ! empty( $new_instance['title_image'] ) ) ? strip_tags( $new_instance['title_image'] ) : '';
return $instance;
}
} // class My_Widget
And the following is the jQuery which accompanies the previous code:
var custom_uploader;
function image_button_click(dialog_title, button_text, library_type, preview_id, control_id) {
event.preventDefault();
//If the uploader object has already been created, reopen the dialog
//if (custom_uploader) {
// custom_uploader.open();
// return;
//}
//Extend the wp.media object
custom_uploader = wp.media.frames.file_frame = wp.media({
title: dialog_title,
button: {
text: button_text
},
library : { type : library_type },
multiple: false
});
//When a file is selected, grab the URL and set it as the text field's value
custom_uploader.on('select', function() {
attachment = custom_uploader.state().get('selection').first().toJSON();
jQuery('#' + control_id).val(attachment.url);
var html = '';
if (library_type=='image') {
html = '<img src="' + attachment.url + '">';
}
if (library_type=='video') {
html = '<video autoplay loop><source src="' + attachment.url + '" type="video/' + get_extension( attachment.url ) + '" /></video>';
}
jQuery('#' + preview_id).empty();
jQuery('#' + preview_id).append(html);
});
//Open the uploader dialog
custom_uploader.open();
}
function get_extension( url ){
return url.substr((url.lastIndexOf('.') + 1));
}
You can can find the whole thing right here.
The problem is that the selected image is only showed after I click on the Save button, and it would be great if it would be shown in the preview field right after the image is selected, without having to click on the Save button, just like the Featured Image widget does in the Post Edit screen.
Any ideas? :)