Reputation: 801
A day before tomorrow, I developed a custom widget for my Recent WordPress theme. In that widget, have an image upload field with some other fields. I have done everything and the widget is working very well except one problem. When I am dragging the widget in sidebar and giving the information needed in all fields, its showing fine in front-end. But after that when I am trying to change the image from that widget back-end then the save button remain saved. Image doesn’t change.
Codes are below:
class Themeslug_About_Widget extends WP_widget{
public function __construct(){
parent::__construct('author_info', esc_html__( 'About Info Box', 'blogista' ), array(
'description' => esc_html__( 'About Info Box contain brief about Author/ Company.', 'blogista' ),
));
}
public function widget( $args, $instance ){
echo $args['before_widget'];
echo $args['before_title'] . $instance['title'] . $args['after_title'];
?>
<img src="<?php echo $instance['author_box_image']; ?>" alt="<?php echo $instance['title']; ?>" />
<div class="widget-content">
<h3 class="title">
<a href="#"><?php echo $instance['author_name']; ?></a>
</h3>
</div>
<?php
echo $args['after_widget'];
}
public function form( $instance ){
$title = '';
if( !empty( $instance['title'] ) ) {
$title = $instance['title'];
}
$author_box_image = '';
if( ! empty( $instance['author_box_image'] ) ) {
$author_box_image = $instance['author_box_image'];
}
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e( 'Title:', 'blogista' ); ?></label>
<input type="text" value="<?php echo esc_attr( $title ); ?>" name="<?php echo $this->get_field_name('title'); ?>" id="<?php echo $this->get_field_id('title'); ?>" class="widefat">
</p>
<p>
<button class="button button-primary" id="author_info_image"><?php _e( 'Upload Image', 'blogista' ); ?></button>
<input type="hidden" name="<?php echo $this->get_field_name('author_box_image'); ?>" id="<?php echo $this->get_field_id('author_box_image'); ?>" class="image_link" value="<?php echo esc_url( $author_box_image ); ?>" >
<div class="image_show">
<img src="<?php echo $instance['author_box_image']; ?>" width="200" height="auto" alt="">
</div>
</p>
<?php
}
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? esc_attr( $new_instance['title'] ) : '';
$instance['author_box_image'] = ( ! empty( $new_instance['author_box_image'] ) ) ? esc_url( $new_instance['author_box_image'] ) : '';
return $instance;
}
}
function themeslug_admin_enqueue_scrits(){
wp_enqueue_media();
wp_enqueue_script( 'admin_custom_script', get_theme_file_uri() . '/js/libs/admin_scripts.js', array( 'jquery' ), '1.0', true );
}
add_action( 'admin_enqueue_scripts', 'themeslug_admin_enqueue_scrits' );
Then added the below jQuery code:
(function($){
$(document).ready(function(){
$('button#author_info_image').on("click",function( e ){
e.preventDefault();
var imageUploader = wp.media({
'title' : 'Upload Author Image',
'button' : {
'text' : 'Set The Image'
},
'multiple' : false
});
imageUploader.open();
imageUploader.on("select", function(){
var image = imageUploader.state().get("selection").first().toJSON();
var link = image.url;
$("input.image_link").val( link );
$(".image_show img").attr('src', link);
});
});
});
}(jQuery))
Every thing is working fine first time but when trying to change the image then Widget save button remain saved. Please Help.
Thanks in Advance.
Upvotes: 0
Views: 1221
Reputation: 11
I will Suggest you to follow my way to create your custom widget using image upload system.
public function widget( $args, $instance ) {
// Our variables from the widget settings
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Default title', 'text_domain' ) : $instance['title'] );
$image = ! empty( $instance['image'] ) ? $instance['image'] : '';
ob_start();
echo $args['before_widget'];
if ( ! empty( $instance['title'] ) ) {
echo $args['before_title'] . $title . $args['after_title'];
}
?>
<?php if($image): ?>
<img src="<?php echo esc_url($image); ?>" alt="">
<?php endif; ?>
<?php
echo $args['after_widget'];
ob_end_flush();
}
And the form function will be:
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : __( 'New title', 'text_domain' );
$image = ! empty( $instance['image'] ) ? $instance['image'] : '';
?>
<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( $title ); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id( 'image' ); ?>"><?php _e( 'Image:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'image' ); ?>" name="<?php echo $this->get_field_name( 'image' ); ?>" type="text" value="<?php echo esc_url( $image ); ?>" />
<button class="upload_image_button button button-primary">Upload Image</button>
</p>
<?php
}
And here is the update function:
public function update( $new_instance, $old_instance ) {
$instance = array();
$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
$instance['image'] = ( ! empty( $new_instance['image'] ) ) ? $new_instance['image'] : '';
return $instance;
}
As you can see, I’ve added a button underneath image input field with class “.upload_image_button”, but it will not work for now and to make it work, need to add our custom admin JavaScript.
First need to create javascript file and put it into your theme, let’s create a file, called our_admin.js in assets/js under your theme folder.
Next you will need to register and enqueue our script to make it load in the admin panel, so lets add few lines to widget class constructor function:
function __construct() {
// Add Widget scripts
add_action('admin_enqueue_scripts', array($this, 'scripts'));
parent::__construct(
'our_widget', // Base ID
__( 'Our Widget Title', 'text_domain' ), // Name
array( 'description' => __( 'Our Widget with media files', 'text_domain' ), ) // Args
);
}
And you will need then “scripts” function in our widget class:
public function scripts()
{
wp_enqueue_script( 'media-upload' );
wp_enqueue_media();
wp_enqueue_script('our_admin', get_template_directory_uri() . '/assets/js/our_admin.js', array('jquery'));
}
As you can notice, I added wp_enqueue_script( ‘media-upload’ ); and wp_enqueue_media(); to enqueue media library popup scripts.
And finally, here is js script, that will call WordPress media library popup and put selected image into the input field:
jQuery(document).ready(function ($) {
$(document).on("click", ".upload_image_button", function (e) {
e.preventDefault();
var $button = $(this);
// Create the media frame.
var file_frame = wp.media.frames.file_frame = wp.media({
title: 'Select or upload image',
library: { // remove these to show all
type: 'image' // specific mime
},
button: {
text: 'Select'
},
multiple: false // Set to true to allow multiple files to be selected
});
// When an image is selected, run a callback.
file_frame.on('select', function () {
// We set multiple to false so only get one image from the uploader
var attachment = file_frame.state().get('selection').first().toJSON();
$button.siblings('input').val(attachment.url);
});
// Finally, open the modal
file_frame.open();
});
});
Now compare your code and you will see the error.
I will suggest to use Plugin to show author information to save your time.
Upvotes: 1