图片上传器小部件未预览所选图片
Posted
技术标签:
【中文标题】图片上传器小部件未预览所选图片【英文标题】:Image uploader widget is not previewing selected image 【发布时间】:2016-06-11 15:05:20 【问题描述】:我一直在尝试为 WordPress 开发一个图像小部件插件,并且由于以下代码,我几乎成功地做到了:
<?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
以下是前面代码附带的jQuery:
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));
你可以找到整个right here。
问题是选择的图像只有在我点击保存按钮后才会显示,如果它在选择图像后立即显示在预览字段中会很棒,而无需点击保存按钮,就像帖子编辑屏幕中的特色图片小部件一样。
有什么想法吗? :)
【问题讨论】:
【参考方案1】:我建议的第一件事是更好地重写整个内容。您正在编写小部件,并说您想要多个小部件,您将拥有多个相同的 id,这不是一件好事。
因此,请创建清晰易懂的类,您可以在点击事件中指向它们。
我做了一些有用的东西,但它可以大大增强(我相信你会做的事情:D)。
我添加了插件标头以便我可以安装它,并且我必须注册小部件以便我也可以在我的后端看到它。我添加了删除图像按钮,该按钮将删除图像并在单击时清除输入字段。
php部分:
<?php
/*
Plugin Name: Title_Page_Widget
Plugin URI:
Description: Title_Page_Widget
Version: 1.0.0
Author:
Author
License: GPL
*/
/**
* 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 class="button remove_image_button" >Remove Image</div>
</div>
<div id="title_image_preview" class="preview_placholder">
<?php
if ($title_image!='') echo '<img style="width:100%" 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
function twp_widget()
register_widget('Title_Page_Widget');
add_action('widgets_init', 'twp_widget');
JS部分:
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>';
var uploaded_image = jQuery('.uploaded_image');
if (uploaded_image.length)
uploaded_image.remove();
jQuery('.title_image').before('<img class="uploaded_image" src="'+attachment.url+'" style="width:100%";>');
jQuery('#' + preview_id).empty();
jQuery('#' + preview_id).append(html);
);
//Open the uploader dialog
custom_uploader.open();
jQuery(document).on('click','.remove_image_button', function(e)
e.preventDefault();
jQuery('.uploaded_image').remove();
jQuery('#title_image_preview img').remove();
jQuery('.title_image').val('');
);
function get_extension( url )
return url.substr((url.lastIndexOf('.') + 1));
我在这里添加了:
var uploaded_image = jQuery('.uploaded_image');
if (uploaded_image.length)
uploaded_image.remove();
jQuery('.title_image').before('<img class="uploaded_image" src="'+attachment.url+'" style="width:100%";>');
对于删除按钮:
jQuery(document).on('click','.remove_image_button', function(e)
e.preventDefault();
jQuery('.uploaded_image').remove();
jQuery('#title_image_preview img').remove();
jQuery('.title_image').val('');
);
我已经对其进行了测试,它可以工作,但正如我所说,它需要工作。您需要查看点击来自哪个小部件,以及从何处删除图像,等等。我怀疑如果你有多个,一旦你点击删除,你就会删除所有的图像。正如我所说,需要更多的工作。
希望这能让你朝着正确的方向前进。
【讨论】:
它就像我需要的那样工作!非常感谢你,@dingo_d! :) 我的实际代码看起来比我发布的代码要复杂一些,但这个代码足以用作示例。你能帮我看看你提到的最后一部分吗?如何将$this->get_field_id['title_image']
作为 JS 变量传递,以便在脚本文件中使用它?
好吧,只需将 DOM 元素定位为 JS 对象,例如:var my_element = jQuery('#your_element_id');
。因为您在输入字段id
中使用$this->get_field_id['title_image']
,所以您可以轻松定位它(如果我理解正确的话)并使用它。
嗯,在我脑海中什么都没有出现。您可以将 js 代码嵌入到您的 php 中,并为 id 使用相同的代码。这将为每个小部件创建一个小的 js 代码,但它会起作用。在<script>
中写入就像在 php 中写入常规的HTML
一样,这样您就可以在其中使用$this->get_field_id['title_image']
。
这只是一个事件委托。可以在here 找到对此的一个很好的解释。通常最好通过最近的父级绑定,但我知道如果您要动态添加元素,则需要绑定到文档对象。所以可能是这种情况......
我猜你的变量是out of scope。您需要小心地将所有变量都放在适当的范围内,以便您可以使用它们。请注意,通过添加小部件,您正在向 DOM 动态添加内容(小部件是使用 AJAX 添加的)。以上是关于图片上传器小部件未预览所选图片的主要内容,如果未能解决你的问题,请参考以下文章