I have widgets that have javascript controls attached to them.
If the widget is present when the widget admin page loads, the controls work correctly.
When I add a new widget, they do not work correctly, I get the markup, but no javascript events take effect.
If I save the new widget, when the form reloads, the controls are created correctly and now work.
Refreshing the page also fixes the issue, but only for existing widgets. New widgets have this issue still.
Specifically I'm running selectize on select inputs at these points:
- document ready
- Ajaxcomplete
I've verified that my code is run on each event as desired, but the results are not as expected.
Here is a test plugin that demonstrates the issue:
https://gist.github.com/Tarendai/8466299
You'll see I have a counter that increases with every select element it finds that it can convert.
Notes:
- When the widget page loads, I can see the counter increasing in the JS console as expected
- When I add a new widget, the code is run, however, it fails to find any select elements it can run on, as demonstrated by found.length being 0. This should not be the case, as every new widget of that type should have a select element
- select elements have a class to identify them, this class is removed once the selectize library is applied to prevent duplication and re-processing on existing widgets.
- Prior to using selectize, I used Select2, which had the same issue
- Commenting out the AJAX code, I would expect new widgets to have a standard select input. They do not. I don't know why this is the case
So how do I make the selectize control work without telling the user to refresh/click save prior to making changes?
.on()
method. Which requires you to bind an event to the document. However what event will be appropriate I'm not sure right now. Ultimately it's because your original bindings represent the initial version of the DOM when the page was loaded and for the most part are blind to the new elements ( widget content ) that are being added via ajax. Hopefully that'll point you in the right direction, if not I can answer better when I'm at work.jQuery( document ).ajaxStop( function() {
part so that I could initialise the controls in the newly loaded widgets. However if I removed that line I would expect new widgets to have standard HTML select inputs, but they do not =swidget-updated
andwidget-added
events. Also I want to emphasize, in @michaeljames code, the use of the element id#widgets-right
. Be sure to use it in order to target active widgets elements inside your JS code otherwise you might get duplicate elements as your code may also select hidden inactive widget elements on the left side of the screen (and those get cloned when widget is added).