1

I'm playing with the customizer for the first time and having a bit of trouble because I can't find documentation for the JS API anywhere.

I'm trying to implement JS based customize previews, and it all works fine except it only applies changes when I update a value in the controls. If I then go to another page (still in customizer), the style update that was applied on the last page disappears until I alter the control value again in some way (add a space or whatever to trigger a change event).

This is the essentials of my customizer-preview.js

(function($) {

$(document).ready(function(){

    var customize = wp.customize,
        $customStylesheet = $('<style type="text/css"></style>');

    // Custom css
    $customStylesheet.insertAfter($stylesheet); // Note I stripped out where $stylesheet is declared - this is not the cause
    customize( 'cf7md_options[custom_css]', function( value ) {
        var func = function(newval) {
            $customStylesheet.text(newval);
        }
        value.call( customize, func );
        value.bind( func );
    } );        

});

}(jQuery));

That's based on this example from the documentation for the customize_preview_init action.

wp.customize( 'YOUR_SETTING_ID', function( value ) {
    value.bind( function( newval ) {
        //Do stuff (newval variable contains your "new" setting data)
    } );
} );

value.call() (in my code) is my attempt at getting func to run immediately on init. It doesn't work obviously.

How am I supposed to persist the updates in the controls across page changes in the customizer? And is there an actual api reference somewhere that I haven't found?

1

Since you are invoking the change callback directly:

value.call( customize, func );

Since you're not passing in the value, then newval will be undefined and $customStylesheet.text(newval) will do nothing.

You need to pass in the value like so:

value.call( customize, func, value.get() );

Nevertheless, it would be better to re-use the existing style element that is already output by PHP and only update it when the setting is changed, rather than create it dynamically with JS each time.

So your PHP should have something like:

add_action( 'wp_head', function() {
    $options = get_theme_mod( 'cf7md_options' );
    echo '<style id="cf7md-style">';
    if ( isset( $options['custom_css'] ) ) {
        echo strip_tags( $options['custom_css'] );
    }
    echo '</style>';
}, 101 );

And your customizer preview JS can be simply:

(function( $, api ) {
    api( 'cf7md_options[custom_css]', function( setting ) {
        setting.bind( function onChange( value ) {
            $( '#cf7md-style' ).text( value );
        } );
    } );
}( jQuery, wp.customize ));
  • value.get() is what I was missing. Thanks! With that I can actually just do func( value.get() ); on init. Do you just know that from reading the source? Or is there an api reference or guide somewhere? – GusRuss89 Feb 21 '17 at 23:00
  • @GusRuss89 There's no API reference for this specifically in the customizer, as this is a somewhat unusual usage (as normally you'd use PHP to render as noted). It's more just about knowing JavaScript, probably. And yes, in your case you can in fact just do func( value.get() ). The only problem with doing this is that this in func would not refer to the Setting instance but would instead be null. In your case it isn't needed, but if you didn't know what the function contained you'd need to ensure the context was preserved. – Weston Ruter Feb 22 '17 at 0:23

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.