3

How can i access the customizer by the DOM ?
I'll explain myself to be clear.
I've recently learned jQuery basics while working on a plugin.
Ok, so while in the customizer preview, if I listen to the DOM,
I can get an answer to any element outside the customizer's panel,
but i'm unable to access the customizer by the DOM, answer is always 0 !
For example, while in the customizer preview :

alert($('#sidebar').length);  

will return an answer of 1 since I have a widgets area that have sidebar as id.
But, while in the customizer preview, if I try to reach a panel, a section, a control, or even the customizer itself, nothing happens, the answer is always 0 !
For example :

alert($('.wp-customize').length);  

will return 0 ! .wp-customize is the "highest" class in the customizer

I hope that my question is clear and that someone can explain to me the reason and help me access the customizer with jQuery.

Thanks a lot in advance for your help.

  • What is it that you are trying to do? this sounds like you are trying to use the customizer in a way it should not be used – Mark Kaplun Nov 26 '16 at 6:59
  • @MarkKaplun I'm trying to access the customizer with jQuery because I'm very confused about the JS customizer API (very poor documentation from my point of view), since my knowledge in JS is not good at all for now... I'm trying to hide a control of a widget if this widget is not active. @WestonRuter helped me a lot link but my low knowledge in JS is helding me back on this ! 'active_callback'=>'is_active-widget' will not work in PHP but in a JS solution... Thanks in advance if you have a solution – LebCit Nov 26 '16 at 21:50
  • this is still somewhat not clear. If you have created the widget properly, its settings panel will not be displayed in the customizer, and you will only be able to add it to a sidebar. If the widget is part of the sidebar but it is hidden with CSS, than you will probably will not be able to hide ir in the customizer, so the exaact definition of "active" in your case is very important here – Mark Kaplun Nov 27 '16 at 3:38
  • I'm trying to hide a control when the widget (related to this control by a setting on this widget) is not active. Is it clear now ? You didn't read well my comment, or you're not into 'active_callback' for a control's setting in the Customizer as I suspect. Have a nice day. – LebCit Nov 27 '16 at 7:56
3

The customizer preview is in a different window than the window that contains the customizer controls. Specifically, the customizer preview is contained inside of an iframe. So that is why you cannot directly use jQuery to select elements. One way to work around this is to use parent.jQuery from the preview, but this is not recommended since the customizer preview may in fact be on a separate domain entirely and such a call would violate the same-origin policy in the browser. Therefore, if you're wanting to interact with the controls from the preview, what you need to do is pass messages from the preview to the pane. Examples of this can be seen in core actually, specifically in customize-selective-refresh.js where it sends the focus-control-for-setting message and then in customize-controls.js where it receives this message. Here is a standalone example and how to obtain the root jQuery container for a given control when you mouse over the site title.

Enqueue this script at the wp_enqueue_scripts action if is_customize_preview(), and let it have the customize-preview script as its dependency:

// customize-preview-example.js
(function( api, $ ) {
    api.bind( 'preview-ready', function() {

        $( '.site-title' ).on( 'mouseover', function() {
            api.preview.send( 'site-title-mousedover', 'some optional message value' );
        } );

    } );
}) ( wp.customize, jQuery );

And then this script that runs in the controls (parent) window which depends on customize-controls and is enqueued at the customize_controls_enqueue_scripts action:

// customize-controls-example.js
(function( api ) {
    api.bind( 'ready', function() {

        // Wait for the site title control to be added.
        api.control( 'blogname', function( siteTitleControl ) {
            api.previewer.bind( 'site-title-mousedover', function( message ) {
                console.info( 'Message sent from preview:', message );
                console.info( 'The jQuery container element for the site title control:', siteTitleControl.container );
            } );
        } );
    } );
}) ( wp.customize );

This being said, be wary of using jQuery to manipulate controls. The customizer controls are tied to their associated customizer settings. If you want to make a change to the value shown in a given control's input, you need to modify the setting associated with it, not modify the control's input directly. Also, if you want to hide a control then what you're looking for is the active_callback on the added control.

  • As you suspected @WestonRuter I'm still trying to find a solution to hide a control when the widget (related to this control by a setting on this widget) is not active. As I've said above, I've learned jQuery basics while working on a plugin and found jQuery easy to learn and understand (unlike JS from my point of view...). This is why I'm trying to access the customizer via jQuery. Thanks again for you great explanation and your time. SYA :) – LebCit Nov 26 '16 at 22:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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