自定义小组件表单:无法更改任何输入字段的值


Custom widget form: Cannot change the value of any input fields

我正在创建一个wordpress小部件,它应该包含一些管理员用户应该能够输入的纯文本,并且该部分工作正常。但是我还需要上传一个文件,我的javascript一直工作正常,直到jQuery尝试更改input#image_url字段的值,因为它只是不更新。它使用 .val() 方法设置正确的值,因此它包含的值只是没有在 DOM 中显示它,因此更改不可见。然后我尝试进入控制台,只是使用 jQuery 和普通文档 api 标准选择输入字段,如下所示:

var input = document.getElementById("image_url");
input.value = "herpderp";

这也失败了,所以无法更改该输入字段的值有一些基本的东西,比如 jsfiddle.net 上面的代码 100% 正确。所以我的问题是,是否有人在 Wordpress 中尝试过破坏输入字段的任何内容?我已经准备好检查我的 html 格式是否不正确,但我认为它看起来没问题。 我的代码如下,供参考:

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;
    }
}

一些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);
        });
    });
});

我在使用 .val 并且没有小部件页面按钮有资格更新时遇到了类似的问题。直到我使用了.trigger('change')方法。所以对于第一条评论,你做了我会替换

$('#image_url').val(image_url);

$('#image_url').val(image_url).trigger('change'); 

进行此更正后,小组件页面上的更新按钮应符合更新条件。

所以我看

了一下它,我认为我从来没有发现到底出了什么问题,但是从另一个小部件复制输入字段然后修改它使它以某种方式工作。所以我的小部件现在看起来像这样:

<?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;
    }
}

然后我把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);
            document.getElementById("widget-intro_widget-3-image_url").value = uploaded_image.toJSON().url;
        });
    });
});