Add/remove controls dynamically based on other settings in Customizer

Ok so you can check out my repo with some custom controls

https://github.com/dingo-d/wordpress-theme-customizer-extra-custom-controls

I’ve adapted the contextual controls by Weston Ruters guide here:

https://make.xwp.co/2016/07/24/dependently-contextual-customizer-controls/

In my example in the repo I have the boxed body checkbox control that toggles boxed body.

You’ll need to enqueue a script to put the js code in

add_action( 'customize_controls_enqueue_scripts', 'mytheme_customizer_control_toggle' );

/**
 * Custom contextual controls
 *
 * @since 1.0.0
 */
function mytheme_customizer_control_toggle() {
    wp_enqueue_script( 'mytheme-contextualcontrols', get_template_directory_uri() . '/inc/customizer/js/customizer-contextual.js?v=' . rand(), array( 'customize-controls' ), false );
}

And in your customizer-contextual.js you’ll have something like:

( function( api ) {
    'use strict';

    api.bind( 'ready', function() {

        api( 'boxed_body', function(setting) {
            var linkSettingValueToControlActiveState;

            /**
             * Update a control's active state according to the boxed_body setting's value.
             *
             * @param {api.Control} control Boxed body control.
             */
            linkSettingValueToControlActiveState = function( control ) {
                var visibility = function() {
                    if ( true === setting.get() || 1 === setting.get() ) {
                        control.container.slideDown( 180 );
                    } else {
                        control.container.slideUp( 180 );
                    }
                };

                // Set initial active state.
                visibility();
                // Update activate state whenever the setting is changed.
                setting.bind( visibility );
            };

            // Call linkSettingValueToControlActiveState on the border controls when they exist.
            api.control( 'boxed_body_border_width', linkSettingValueToControlActiveState );
            api.control( 'boxed_body_border_color', linkSettingValueToControlActiveState );
            api.control( 'boxed_body_border_style', linkSettingValueToControlActiveState );
        });

    });

}( wp.customize ) );

You are targeting the control name (in this case it’s 'boxed body'), inside it you can check if that controle has active state or not, and accordingly set the ‘visibility’ of the other linked controls.

You can also toggle this change in the preview screeen by hooking to customize_preview_init hook

add_action( 'customize_preview_init', 'mytheme_customizer_live_preview' );
/**
 * Live preview script enqueue
 *
 * @since 1.0.0
 */
function mytheme_customizer_live_preview() {
    wp_enqueue_script( 'mytheme-themecustomizer', get_template_directory_uri() . '/inc/customizer/js/customizer.js?v=' . rand(), array( 'jquery', 'customize-preview' ), false );
}

Inside customizer.js you’ll have something like:

(function($, api) {
    'use strict';

    // Boxed Body Toggle.
    api( 'boxed_body', function(value) {
        value.bind(function(newval) {
            if (newval) {
                $( 'body' ).wrapInner( '<div class="boxed_body_wrapper" />' );
            } else {
                $( '.boxed_body_wrapper' ).contents().unwrap();
            }
        });
    });

})(jQuery, wp.customize);

Hope this helps 🙂

Leave a Comment