Opened 14 years ago
Closed 7 years ago
#14686 closed defect (bug) (wontfix)
Widget Instance Form Update Bug
Reported by: | digitalnature | Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 3.0.1 |
Component: | Widgets | Keywords: | has-patch |
Focuses: | Cc: |
Description
Hi.
When dragging and dropping a widget into a sidebar the widget form doesn't get properly updated, unless you manually press the "Save" button. However the widget instance data is saved (you can see the widget in the frontend even if you don't press 'save').
This problem is noticeable when you're developing a widget and want to display some widget options in the form based on the widget's location or position. You can't do this because $widget->id or $widget->number appear to be initialized within the form() function only after you press Save...
I can provide the code of a test widget if necessary
Attachments (2)
Change History (18)
#2
@
14 years ago
a basic example:
class test_widget extends WP_Widget{ function test_widget(){ $this->WP_Widget(false, 'test'); } function widget($args, $instance){ echo 'front-end'; } function form($instance){ print_r($this); } } add_action('widgets_init', create_function('', 'register_widget("test_widget");'));
$this->id, $this->number and other variables are only available after you press the Save button.
#3
@
14 years ago
- Keywords widgets reporter-feedback removed
Confirmed: when the widget is saved for the first time, the form is not updated.
That's because $wp_registered_widget_controls[$widget_id] is NULL.
To fix this, we have to get rid of all the global $wp_registered_widget_* rubbish.
#5
@
14 years ago
- Keywords needs-patch added
- Milestone changed from Awaiting Review to Future Release
#7
@
13 years ago
I ran into this problem today. Thought it was something wrong I was doing until I got pointed to this ticket.
My specific issue was not being able to access the jQuery '.click' event when a new widget is dragged into a widget area. You can only do so once the widget has been Saved.
I wanted to hide/show an advanced section of widget options via a jQuery toggle button. This works great apart from the very first time the widget is dragged into the widget area.
As as a stop gap I am looking into automatically clicking the Save button via JavaScript, but this method is a bit of a hack, so it would be great if this was given a closer look for the next release or two.
#8
@
13 years ago
- Version changed from 3.0.1 to 3.3
When you first drag a widget into a widget area the 'save-widget' and 'widgets-order' ajax requests are fired, and when you manually click to save the widget the 'save-widget' ajax request is fired again.
However, the widget object is not accessible on the first ajax request. If the widget object could be set on the FIRST ajax request then there wouldn't be a problem.
Just wondering why it only sets the widget object on the second 'save-widget' ajax response?
#9
@
13 years ago
The first 'save-widget' is run to actually create the widget instance in PHP (i.e. let the back-end know there's a new instance of that widget and run any PHP hooks on it). Then all of the new widget instance's HTML is loaded into the new widget "wrap" on the front as return from that XHR request. This includes any changes made by the PHP hooks.
Don't think there's a way around this, seems we can fire a custom event after the initial XHR to trigger changes that need to be made by JS on adding new widget instance.
#10
@
13 years ago
- Version changed from 3.3 to 3.0.1
Version number indicates when the bug was initially introduced/reported.
#11
@
13 years ago
I posted a fix here, still kind of "hacky":
http://wordpress.stackexchange.com/a/37707/1986
This basically fires another save action again after the buggy save action has completed...
#12
@
12 years ago
Added a patch that fixes the issues in this ticket. It basically fires another XHR request when a widget is FIRST dragged into a widget area.
The patch along with the test widget code above works fine. Plus, JS/jQuery is available to the widget, without having to manually click Save, so you can easily add jQuery tabs or toggle advanced widget options etc.
Seeing as this extra XHR request fires ONLY the first time a widget is dragged into a widget area I think it's an acceptable fix.
Obviously it would be preferable to have the form HTML returned along with the first XHR request but it seems this is not possible without some fundamental changes to the widget code (see comment 9 from azaozz).
It 'almost' tantalizingly seems like this is possible looking at the code in ajax-actions.php as the initial XHR request returns nothing back to widgets.php. However there is no access to the global $wp_registered_widget_controls variable in wp_ajax_save_widget() during the initial XHR request so we can't just return the form HTML as a response.
#14
follow-up:
↓ 15
@
10 years ago
The patch I added works on the widgets admin page but not on the Customizer. When adding new widget instances on the Customizer similar code is needed to make sure the widget form gets properly updated.
#15
in reply to:
↑ 14
@
10 years ago
Replying to dgwyer:
The patch I added works on the widgets admin page but not on the Customizer. When adding new widget instances on the Customizer similar code is needed to make sure the widget form gets properly updated.
When implementing widgets in the Customizer, I intentionally made it so that the widget form would not submit when first added. If you try submitting an empty widget form, oftentimes a widget form may then display a validation/error message about a field being required. It would be a poor experience if adding a widget would be immediately followed by an error message displayed.
Please do.