Closed danyj closed 7 years ago
@danyj No, in_widget_form
it's an action, look in Codex, mate.
PolyLang plugin uses this action to output language selection.
https://developer.wordpress.org/reference/hooks/in_widget_form/
I know is an action , I made own plugin before and this worked fine
add_action( 'in_widget_form', array(&$this, 'thz_aw_in_widget_form' ), 10, 3);
placing all my extra fields at the bottom
_filter_form_callback
is trowing that error for the second attribute ,
@moldcraft you think this is ok ?
add_action( 'in_widget_form', array($this, '_filter_form_callback' ), 10, 3);
public function _filter_form_callback( $instance, $empty, $values ) {
$options = $this->get_options('test');
$prefix = $instance->get_field_id('test');
$this->print_widget_javascript('fw-ext-test-widget-options-'. $prefix);
echo '<div class="fw-force-xs" id="fw-ext-test-widget-options-'. esc_attr($prefix) .'">';
echo fw()->backend->render_options($options, $values, array(
'id_prefix' => $prefix .'-',
'name_prefix' => $prefix,
));
echo '</div>';
return $values;
}
that places the options at the bottom , you think there can be some issues with fw options?
I'm trying to make this work right from widgets
.
But, it disappears after saving.
Code:
<?php if ( ! defined( 'ABSPATH' ) ) { die( 'Tranquility - the highest manifestation of power!' ); }
class Fw_Theme_Widget_Friends extends WP_Widget {
/**
* Widget constructor.
*/
function __construct() {
$widget_ops = array( 'description' => __( 'Links list of your friendly websites.', 'unyson' ) );
parent::__construct( false, __( 'Kronos / Our Friends', 'unyson' ), $widget_ops );
}
function widget( $args, $instance ) {
extract( $args );
$params = array();
foreach ( $instance as $key => $value ) {
$params[ $key ] = $value;
}
$title = $before_title . $params['widget-title'] . $after_title;
unset( $params['widget-title'] );
$filepath = dirname( __FILE__ ) . '/views/widget.php';
$instance = $params;
$before_widget = str_replace( 'class="', 'class="tag-cloud-sidebar ', $before_widget );
if ( file_exists( $filepath ) ) {
include( $filepath );
}
}
function update( $new_instance, $old_instance ) {
$options = array(
'demo1' => array(
'type' => 'text',
'value' => 'default value'
),
'demo2' => array(
'type'=>'select',
'choices' => array(
'tiger' => 'Tiger',
'puma' => 'Puma',
'lynx' => 'Lynx',
'pantera' => 'Pantera'
)
)
);
$prefix = 'our-friends';
return array_merge(
$values,
fw_get_options_values_from_input($options, FW_Request::POST($prefix, array()))
);
}
function form( $values ) {
$options = array(
'demo1' => array(
'type' => 'text',
'value' => 'default value'
),
'demo2' => array(
'type'=>'select',
'choices' => array(
'tiger' => 'Tiger',
'puma' => 'Puma',
'lynx' => 'Lynx',
'pantera' => 'Pantera'
)
)
);
$prefix = 'our-friends';
$this->print_widget_javascript('fw-ext-test-widget-options-'. esc_attr($prefix));
echo '<div class="fw-force-xs" id="fw-ext-test-widget-options-'. esc_attr($prefix) .'">';
echo fw()->backend->render_options($options, $values, array(
'id_prefix' => $prefix .'-',
'name_prefix' => $prefix,
));
echo '</div>';
return $values;
}
private function print_widget_javascript($id) {
?><script type="text/javascript">
jQuery(function($) {
var selector = '#<?php echo esc_js($id) ?>', timeoutId;
$(selector).on('remove', function(){ // ReInit options on html replace (on widget Save)
clearTimeout(timeoutId);
timeoutId = setTimeout(function(){ // wait a few milliseconds for html replace to finish
fwEvents.trigger('fw:options:init', { $elements: $(selector) });
}, 100);
});
});
</script><?php
}
}
Maybe because id="fw-ext-test-widget-options-'. esc_attr($prefix) .'"
is exactly the same as id="..."
in test extension?
@moldcraft Nope, my $prefix is different. But, anyway, I've already done my own solution, that adds my own fields to add them to Widgets, and even repeatable fields is supported.
Unyson can't provide normal way to layout widget settings this time, maybe in further it will be updated & official support for this will be added.
Nope, my $prefix is different. Anyway, I've done my own solution, which is quite ease to use and even supports repeatable fields.
With my solution, widget class code looks like this: http://pastebin.com/Yuj2VtcQ
I've created successfully Widget with Unyson options from widget class without extension. Add options right from widget, work with all option types.
Only issue I can't resolve right now is: with some options which have javascript, when I click save button, I must reload to use them full functionally. Eg, addable
option, when save button is clicked, I can't sort the item; after reloading, everything is okay.
There are some options work out of the box, such as select-multiple
@moldcraft, if you're interested in this, I can send you the code, right now I don't have enough time to resolve javascript issue. I think if the javascript problem is resolve, we can add a docs section for widget, creating widget with Unyson options is fast as light. :)
@dinhtungdu Have you tried the above @danyj solution?
@moldcraft: I tried. But @danyj solution uses action. The approach I'm using is inspired by Priler , I add options right from Widget class, no extension, no action or filter. Because I think add action from widget is more elegant and more suitable. Here is an example before saving http://prntscr.com/b3583n After saving: http://prntscr.com/b358ni
Give me your code and I will inspect it.
@moldcraft Here we go: Widget with Unyson options
/* This CSS need to force display option after saving */
.fw-theme-admin-widget-wrap .fw-backend-option, .fw-theme-admin-widget-wrap .fw-postbox {
opacity: 1;
}
This css means that you are doing things wrong, option is not displayed because it is not initialized from javascript.
Your code is not using WP_Widget::get_field_name(...);
and WP_Widget::get_field_id(...);
which generates a unique/incremented name and id, to prevent multiple elements in html with same id/name.
Also you don't initialize the options in javascript (like in the above examples. have you read them?) with $this->print_widget_javascript($id);
<?php if ( ! defined( 'ABSPATH' ) ) { die( 'Tranquility - the highest manifestation of power!' ); }
class Widget_Online_Support extends WP_Widget {
/**
* Widget constructor.
*/
private $options;
private $prefix;
function __construct() {
$widget_ops = array( 'description' => __( 'Display online support infomation', 'unyson' ) );
parent::__construct( false, __( 'Online Support', 'unyson' ), $widget_ops );
$this->options = array(
'title' => array(
'type' => 'text',
'label' => __('Widget Title', 'unyson'),
),
'block' => array(
'type' => 'addable-box',
'label' => __('Apartment', 'unyson'),
'box-options' => array(
'skype' => array( 'type' => 'text', 'label' => __('Skype', 'unyson'), ),
'tel' => array( 'type' => 'text', 'label' => __('Telephone', 'unyson'), ),
'desc' => array( 'type' => 'text', 'label' => __('Aparment name', 'unyson'), ),
),
'box-controls' => array( // buttons next to (x) remove box button
'control-id' => '<small class="dashicons dashicons-smiley"></small>',
),
'limit' => 0, // limit the number of boxes that can be added
'add-button-text' => __('Add New', 'unyson'),
'sortable' => true,
),
);
$this->prefix = 'online_support';
}
function widget( $args, $instance ) {
extract( $args );
$params = array();
foreach ( $instance as $key => $value ) {
$params[ $key ] = $value;
}
$filepath = dirname( __FILE__ ) . '/views/widget.php';
$instance = $params;
if ( file_exists( $filepath ) ) {
include( $filepath );
}
}
function update( $new_instance, $old_instance ) {
return fw_get_options_values_from_input(
$this->options,
FW_Request::POST(fw_html_attr_name_to_array_multi_key($this->get_field_name($this->prefix)), array())
);
}
function form( $values ) {
$prefix = $this->get_field_id($this->prefix);
$id = 'fw-widget-options-'. $prefix;
echo '<div class="fw-force-xs fw-theme-admin-widget-wrap" id="'. esc_attr($id) .'">';
$this->print_widget_javascript($id);
echo fw()->backend->render_options($this->options, $values, array(
'id_prefix' => $prefix .'-',
'name_prefix' => $this->get_field_name($this->prefix),
));
echo '</div>';
return $values;
}
private function print_widget_javascript($id) {
?><script type="text/javascript">
jQuery(function($) {
var selector = '#<?php echo esc_js($id) ?>', timeoutId;
$(selector).on('remove', function(){ // ReInit options on html replace (on widget Save)
clearTimeout(timeoutId);
timeoutId = setTimeout(function(){ // wait a few milliseconds for html replace to finish
fwEvents.trigger('fw:options:init', { $elements: $(selector) });
}, 100);
});
});
</script><?php
}
}
@moldcraft You're my hero! Worked perfectly! Next time, I will check my code more carefully before submit here. Thanks for pointing my mistakes!
Hi there,
Just tested @moldcraft script and everything works very well except JavaScript is no initialized when widget is added and page is not reloaded. When I reload page, there are no issues and everything works.
I can't see any JavaScript or PHP errors/warnings.
EDIT: When pressing Save button twice it starts working (after first click options simply disappears, but after second click it loads again and JS starts working)
@pear1 In my updated version, when user add new widget, he just needs one click on Save button. This causes by the not matching id in javascript of that widget when it's added first time. I'm trying to make it work at the first time but at the moment no luck.
@dinhtungdu At the moment only solution I can think of would be to trigger Save button click twice by JS, immediately after widget is added. Then content is fully reloaded and JS starts working. That could be a pretty bad solution, but at least everything would work as it should.
Does this have anything to do with the following problem?
http://blog.codebusters.pl/en/click-doesn-t-work-after-ajax-load-jquery/
@dinhtungdu I tested your latest gist just now and seems like is not working anymore ,
@moldcraft what is the 100% working code now since we mixed up extension that adds option and widgets with options
@moldcraft , @dinhtungdu , @Priler hm , we saved everything and all nice and sweet , but does any of you know how to retrieve the saved values per widget?
what is the 100% working code now since we mixed up extension that adds option and widgets with options
I will inspect this issue later.
we saved everything and all nice and sweet , but does any of you know how to retrieve the saved values per widget?
They should be somewhere in wp_options
Usually a widget is like a shortcode, the $atts
are available only on render, in widget case it is in widget()
method https://codex.wordpress.org/Widgets_API
This fixes the disappearing options in @dinhtungdu example.
jQuery(function($) {
var timeoutId;
$(document).on('widget-updated widget-added', function(){
clearTimeout(timeoutId);
timeoutId = setTimeout(function(){ // wait a few milliseconds for html replace to finish
fwEvents.trigger('fw:options:init', { $elements: $('#widgets-right .fw-theme-admin-widget-wrap') });
}, 100);
});
});
Note: you should put this in a script file and load it once. Still it's not a clean script but it does it's job and no visual side effects for user. Waiting for an official fix though.
@moldcraft , I tried something else and seems to work , but need small help ,
most of us would have bunch of shortcodes that we want to have as widgets also , so instead of copy the code I did this
function __construct() {
$widget_ops = array( 'description' => __( 'Display online support infomation', 'unyson' ) );
parent::__construct( false, __( 'Tabs', 'unyson' ), $widget_ops );
$sh_options = fw_get_variables_from_file(get_template_directory() .$this->_sh_path('tabs').'/options.php', array('options' => null));
$sh_options = $sh_options['options'];
$this->options = array(
'widget_options' => array(
'type' => 'popup',
'options' => $sh_options,
'title' => __('Widget Options', '{domain}'),
'modal-size' => 'large',
'desc' => __('Customize Widget Options', '{domain}'),
),
);
$this->prefix = 'online_support';
}
function _sh_path($shortcode){
return '/inc/thzframework/extensions/shortcodes/shortcodes/'.$shortcode;
}
function widget( $args, $instance ) {
extract( $args );
$params = array();
foreach ( $instance as $key => $value ) {
$params[ $key ] = $value;
}
$filepath = get_template_directory() .$this->_sh_path('tabs').'/views/view.php';
$instance = $params;
if ( file_exists( $filepath ) ) {
include( $filepath );
}
}
and in tabs shortcode just on top of view.php
if(isset($instance)){
$atts = $instance;
}
now I have full tabs output in front and options in widget ,
but 2 things are bugging
it would be great if you could help.
as of popup container , I can move that to popup option type and do this in view
if(isset($instance)){
$atts = $instance['widget_options'];
}
but still need the static
This is my final solution to the IN WIDGET options using @moldcraft example above , add in a single enqueued to widgets page script :
/*
Enable FW options in widgets on add (without refresh)
By simulating a save click after add and then initialize them with fw:options:init
*/
jQuery(function($) {
let timeoutAddId;
$(document).on('widget-added', function(ev, $widget){
clearTimeout(timeoutAddId);
timeoutAddId = setTimeout(function(){ // wait a few milliseconds for html replace to finish
$widget.find('form input[type="submit"]').click();
}, 300);
});
let timeoutUpdateId;
$(document).on('widget-updated', function(ev, $widget){
clearTimeout(timeoutUpdateId);
timeoutUpdateId = setTimeout(function(){ // wait a few milliseconds for html replace to finish
fwEvents.trigger('fw:options:init', { $elements: $widget });
}, 100);
});
});
You get the$widget
object as the second parameter for events widget-added
and widget-updated
so no need to search for that.
Thanks @moldcraft , But i face another problem. When i add "icon-v2" field in widget area, in popup option no field are shown !!! How can i solve it ???
Hello, mhsohag11, you are a genius person. now, you are working for GitHub unison group. I didn't understand why you do not solve this. I hope you can try, you will be solved this problem.because you are a genius person.
Be careful if you are using 'wp-editor' option type in your widget since WordPress version 4.9.6.
You'll see error in your console.
More info on WordPress trac
It can be fixed in includes/option-types/wp-editor/static/scripts.js
by wrapping code tinymce.ui.FloatPanel.zIndex = 100100;
on line 148 in if
statement like so:
if ( tinymce.ui.FloatPanel !== undefined ) { tinymce.ui.FloatPanel.zIndex = 100100; }
Please note that you'll loose this changes after Unyson plugin update.
Could you please show me best possible way to add any unsyon option to widgets? I would like to add list of custom class names that user can pick to display different widgets style/ It is a simple select with list of class names.
This is what I have in mind but with unyson options http://prntscr.com/76c7vg