Reputation: 4580
Im creating a wordpress widget, and it should contain some plain text that the admin user should be able to input, and that part works fine. But i also need to upload a file, and my javascript works fine right up until the point where jQuery tries to change the value of the input#image_url field, because it just doesn't update. it sets the value correct with the .val() method, so it contains the value it just doesn't show it in the DOM, so the change isn't visible. Then i tried to go into the console and just standard select the input field with jQuery and with the normal document api like so:
var input = document.getElementById("image_url");
input.value = "herpderp";
which also fails, so there is just something fundamental about not being able to change the value of that input field, in something like jsfiddle.net the above code works 100% correct. So my question is if anyone have tried anything in Wordpress where it ruins the input fields? I have allready checked if my html is malformed, but i think it looks allright. My code is below, for any reference:
file:my_theme/functions.php
include_once('widgets/intro.php');
function caribia_enqueue_styles()
{
$parent_style = 'parent-style';
wp_enqueue_style($parent_style, get_template_directory_uri() . '/style.css');
wp_enqueue_style('child-style', get_stylesheet_directory_uri() . '/style.css', array($parent_style));
wp_enqueue_style('caribia-css', get_stylesheet_directory_uri() . '/css/caribia.css');
wp_enqueue_script('caribia-js', get_stylesheet_directory_uri() . '/js/caribia.js', array('jquery'));
}
function caribia_register_widgets() {
register_widget('Intro_Widget');
}
function load_wp_media_files() {
wp_enqueue_media();
}
add_action('wp_enqueue_scripts', 'caribia_enqueue_styles', 12);
add_action('admin_enqueue_scripts', 'caribia_enqueue_styles');
add_action('widgets_init', 'caribia_register_widgets');
add_action( 'admin_enqueue_scripts', 'load_wp_media_files' );
file:my_theme/widgets/intro.php
<?php
/**
* Widget API: Intro_Widget class
*
* @package WordPress
* @subpackage Widgets
* @since 4.4.0
*/
/**
* Adds Foo_Widget widget.
*/
class Intro_Widget extends WP_Widget {
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'intro_widget',
__( 'Intro widget', 'text_domain' ),
array( 'description' => __( 'A intro widget, should output a image, header, sub-headers
and a description for each subheader', 'text_domain' ), )
);
add_action('admin_enqueue_scripts', array($this, 'upload_scripts'));
}
/**
* Upload the Javascripts for the media uploader
*/
public function upload_scripts()
{
wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');
wp_enqueue_script('upload_media_widget', get_stylesheet_directory_uri() . '/js/upload-media.js', array('jquery'));
wp_enqueue_style('thickbox');
}
/**
* Front-end display of widget.
*
* @see WP_Widget::widget()
*
* @param array $args Widget arguments.
* @param array $instance Saved values from database.
*/
public function widget($args, $instance) {
echo $args['before_widget'];
echo "herpderp";
echo $args['after_widget'];
}
/**
* @param array $instance
* @return string Default return is 'noform'.
*/
public function form($instance) {
?>
<div>
<label for="image_url">Image</label>
<input type="text" name="image_url" id="image_url" class="regular-text">
<input type="button" name="upload-btn" id="upload-btn" class="button-secondary" value="Upload Image">
</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 ) {
return $new_instance;
}
}
Some javascript:
jQuery(document).ready(function($) {
$(document).on('click','#upload-btn',function(e) {
var image = wp.media({
title: 'Upload Image',
multiple: false
}).open().on('select', function(e){
console.log('select was called');
var uploaded_image = image.state().get('selection').first();
console.log(uploaded_image);
var image_url = uploaded_image.toJSON().url;
$('#image_url').val(image_url);
});
});
});
Upvotes: 0
Views: 512
Reputation: 26
I had a similar issue with using .val
and not having the widget page button be eligible to update. That is until I used the .trigger('change')
method. So for the first comment, you made I would replace
$('#image_url').val(image_url);
with
$('#image_url').val(image_url).trigger('change');
After this correction is made, the update button on the widget page should be eligible for update.
Upvotes: 1
Reputation: 4580
So i had a look at it, and i dont think i ever found out exactly what was wrong, but copying over a input field from another widget and then modifying it made it work somehow. So my widget looks like this now:
<?php
/**
* Widget API: Intro_Widget class
*
* @package WordPress
* @subpackage Widgets
* @since 4.4.0
*/
/**
* Adds Foo_Widget widget.
*/
class Intro_Widget extends WP_Widget {
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'intro_widget',
__( 'Intro widget', 'text_domain' ),
array( 'description' => __( 'A intro widget, should output a image, header, sub-headers
and a description for each subheader', 'text_domain' ), )
);
add_action('admin_enqueue_scripts', array($this, 'upload_scripts'));
}
/**
* Upload the Javascripts for the media uploader
*/
public function upload_scripts()
{
wp_enqueue_script('media-upload');
wp_enqueue_script('thickbox');
wp_enqueue_script('upload_media_widget', get_stylesheet_directory_uri() . '/js/upload-media.js', array('jquery'));
wp_enqueue_style('thickbox');
}
/**
* Front-end display of widget.
*
* @see WP_Widget::widget()
*
* @param array $args Widget arguments.
* @param array $instance Saved values from database.
*/
public function widget($args, $instance) {
echo $args['before_widget'];
echo "herpderp";
echo $args['after_widget'];
}
/**
* @param array $instance
* @return string
*/
public function form($instance) {
$title = !empty( $instance['title'] ) ? $instance['title'] : __( 'New title', 'text_domain' );
$image_url = !empty($instance['image_url']) ? $instance['image_url'] : __('New imageurl', 'text_domain');
?>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( esc_attr( 'Title:' ) ); ?></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>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'image_url' ) ); ?>"><?php _e( esc_attr( 'Image url:' ) ); ?></label>
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'image_url' ) ); ?>"
name="<?php echo esc_attr( $this->get_field_name( 'image_url' ) ); ?>" type="text" value="<?php echo esc_attr( $image_url ); ?>">
<input type="button" name="upload-btn" id="upload-btn" class="button-secondary" value="Upload Image">
</p>
<?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 = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['image_url'] = strip_tags($instance['image_url']);
$this->flush_widget_cache();
return $instance;
}
}
And then i changed the javascript to this:
jQuery(document).ready(function($) {
$(document).on('click','#upload-btn',function(e) {
var image = wp.media({
title: 'Upload Image',
multiple: false
}).open().on('select', function(e){
console.log('select was called');
var uploaded_image = image.state().get('selection').first();
console.log(uploaded_image);
document.getElementById("widget-intro_widget-3-image_url").value = uploaded_image.toJSON().url;
});
});
});
Upvotes: 0