1

I want to fire an event for when AFTER a new widget has been added to the previewer, and then AFTER a widget has been removed.

Use Case: After the widget has been added to the previewer DOM, I want to change it's class based on how many other widgets are in that same sidebar area. So when

wp.customize('sidebars_widgets[sidebar-1]').get().length

fires, its a little too early to count all the widgets.

So like, I'm thinking I add a widget in the Customizer controls sidebar, then the previewer adds the widget, once the widget is added to the Previewer DOM I was hoping it would emit an event saying "this widget has been added". I could listen for that event and then run some code to change the class names on all the widgets in that sidebar.

I already have this working, by having the Customizer send some data to the Previewer, waiting 1 second, and then counting the widgets. But that doesnt seem very reliable (what if it takes 1.3 seconds for the widget to load?).

In my Previewer javascript (loaded via the customize_preview_init hook, I have the following:

  $( document ).on( 'widget-added', function(event, widget) {
    console.log(widget);
  });

But this doesn't seem to do anything.

Anyone know what that would be?

5
  • Please share more details about the use case. You need to know when a widget is added to the preview window and when it is removed? Why the preview specifically and not a widget control being added or removed? Closely related to wordpress.stackexchange.com/a/293010/8521 Feb 10, 2018 at 5:24
  • Added a use case
    – rugbert
    Feb 10, 2018 at 15:12
  • By previewer do you mean the Customizer controls sidebar or the preview window iframe? In other words, are you working with the controls in the section or widgets in a sidebar on the frontend? Feb 10, 2018 at 16:16
  • Since this happens entirely on the browser side, this is a matter of javascript. It is not a WordPress question. That said, this plugin supports exactly what you want: github.com/pie6k/jquery.initialize
    – cjbj
    Feb 10, 2018 at 16:39
  • OK added further clarification. I used the answer in wordpress.stackexchange.com/a/293010/8521 to achieve my goal, but this specific question is to find a better (the right) way to do it.
    – rugbert
    Feb 10, 2018 at 16:39

2 Answers 2

1

In order to interact with the event "widget-added" , you should enqueue your JavaScript file using "customize_controls_enqueue_scripts" to avoid it being part of the repetitively loading preview iframe ( where $(document) is different from the parent page document).

I was able of interacting with the "widget-added" event using this example :

in theme's functions.php

function custom_enqueue_scripts(){
    wp_enqueue_script( 'custom-script', get_template_directory_uri() . '/js/custom.js',array('jquery','customize-widgets'),'',1 );

}
add_action('customize_controls_enqueue_scripts','custom_enqueue_scripts',10);

JavaScript file :

jQuery(document).ready(function($) {


    $( document ).on( 'widget-added', function(event, widget) {
        console.log(widget);
    });



});
1

I think you are better off dealing with the change at the sidebar level since you wish to change the classes for all the widgets in the sidebar depending on how many there are.

Here is the code to get you started (inspired by this):

(function($){
    $(document).on('ready', function () {
        // Change this selector depending on your target widget area
        var widgetArea = $('#secondary .widget-area');

        if ('undefined' !== typeof wp && wp.customize && wp.customize.selectiveRefresh) {
            wp.customize.selectiveRefresh.bind('sidebar-updated', function (sidebarPartial) {
                if ('sidebar-1' === sidebarPartial.sidebarId) {
                    // Do something to the widgetArea or its children
                }
            });
        }
    });
})(window.jQuery);

You should put this code in a file and only load it in the Customizer by using the customize_controls_enqueue_scripts action hook.

I hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.