Jason G. Designs

WordPress Themes, Print-On-Demand Resources and more…

Hide and Show Controls in the WordPress Customizer With a Radio Button

4
May
2017
WordPress Customizer

You’ve probably seen the action of hiding controls until a radio button is clicked under the Static Front Page section of WordPress’s Customizer. You have a choice between Your latest posts and A static page. When A static page is selected, two more controls show.

Even though I couldn’t figure out exactly how they did it in Core, I came up with my own solution using some of the Customizer JavaScript API and jQuery. I used this method while creating a color scheme selection with two premade color schemes and a Custom option. When the Custom radio button is selected, it reveals several Color Pickers. Even though this is specific to WordPress, it can be useful generally, too, with adaptations. Because of this, I will show an example of the code that is generated by WordPress, so you can figure out how to apply the JavaScript code to your own code.

Create some Customizer controls

The given examples are just basic Customizer controls and settings, following the example in the Codex. I will give an example of some of the options presented in The M.X. as an example:

$wp_customize->add_setting(
	'the_mx_color_scheme', array(
		'type' => 'theme_mod',
		'capability' => 'edit_theme_options',
		'default' => 'brown',
		'transport' => 'refresh',
		'sanitize_callback' => 'the_mx_sanitize_color_choices',
		'sanitize_js_callback' => 'the_mx_sanitize_color_choices',
	)
);

$wp_customize->add_control(
	'the_mx_color_scheme', array(
		'type' => 'radio',
		'label' => __( 'Color Scheme', 'the-mx' ),
		'section' => 'colors',
		'choices' => array(
			'brown' => __( 'Brown', 'the-mx' ),
			'custom' => __( 'Custom', 'the-mx' ),
		),
	)
);

The first setting/control combination adds a radio button selection to WordPress’s default Colors section. the Brown selection would be the default.

$wp_customize->add_setting(
    'the_mx_custom_primary_1', array(
        'type' => 'theme_mod',
        'capability' => 'edit_theme_options',
        'default' => '#795548',
        'transport' => 'refresh',
        'sanitize_callback' => 'sanitize_hex_color',
    )
);
    
$wp_customize->add_control(
    new WP_Customize_Color_Control (
        $wp_customize,
        'the_mx_custom_primary_1', array(
            'label' => __( 'Primary Color 1', 'the-mx' ),
            'description' => __( 'Color for the title bar, footer, entry-title links, etc.', 'the-mx' ),
            'section' => 'colors',
            'settings' => 'the_mx_custom_primary_1',
            'active_callback' => 'the_mx_show_custom_colors',
        )
    )
);

$wp_customize->add_setting(
    'the_mx_custom_accent_1', array(
        'type' => 'theme_mod',
        'capability' => 'edit_theme_options',
        'default' => '#ffa000',
        'transport' => 'refresh',
        'sanitize_callback' => 'sanitize_hex_color',
    )
);
    
$wp_customize->add_control(
    new WP_Customize_Color_Control (
        $wp_customize,
        'the_mx_custom_accent_1', array(
            'label' => __( 'Accent Color 1', 'the-mx' ),
            'description' => __( 'Button colors, etc.', 'the-mx' ),
            'section' => 'colors',
            'settings' => 'the_mx_custom_accent_1',
        )
    )
);

Only two more control/setting combinations are shown for brevity’s sake. Keep in mind that only the idea is being shown here, so in your theme your radio buttons may be for selection of something else entirely.

In order for the controls to work, you must add validation to each control. sanitize_hex_color handles making sure a valid hex code is returned to the database. We must also create the callback for our radio buttons that only accepts the values found in our choices, or return a default, as shown below:

function the_mx_sanitize_color_choices( $input ) {
    if( !in_array( $input, array( 'brown', 'custom' ) ) ) {
        $input = 'brown';
    }
    return $input;
}

Once the validation functions are created, your controls should show up in the Customizer. Since this tutorial deals with only the behavior of the controls themselves, we won’t focus on what changes the controls will make on the front end. What we can display is the code that is generated by WordPress. If you were to right click in your browser on one of your controls you just created, and Inspect Element, you may see code similar to this:

<ul id="sub-accordion-section-colors" class="customize-pane-child ... open">
    ...
    <li id="customize-control-background_color" class="customize-control customize-control-color" style="display: list-item;">
    ...
    </li>
    <li id="customize-control-the_mx_color_scheme" class="customize-control customize-control-color" style="display: list-item;">
    ...
    </li>
    <li id="customize-control-the_mx_custom_primary_1" class="customize-control customize-control-color" style="display: list-item;">
    ...
    </li>
    <li id="customize-control-the_mx_custom_accent_1" class="customize-control customize-control-color" style="display: list-item;">
    ...
    </li>
</ul>

I used pseudo code here with the ellipses replacing the actual rendering code for the controls because WordPress generates a lot of code, while we are interested in the li tags that each control sits in. Note the id titles, as we will refer to them later in our script.

Enqueue a script that will manipulate our Controls

The next step is to enqueue a script specifically for our controls. If you are using Underscores as a base for your theme, as I am, you can write this function in your customizer.php file.

function the_mx_customizer_controls() {
    wp_enqueue_script( 'the-mx-customizer-controls', get_template_directory_uri() . '/js/customize-controls.js', array( 'jquery' ), '20170412', true );
}
add_action( 'customize_controls_enqueue_scripts', 'the_mx_customizer_controls' );

If your scripts are in a different folder, adjust the paths accordingly. Now, we can create the customize-controls.js file. In it, enter a wrapping function:

/**
 * Scripts to alter the behavior of Customizer controls.
 */
( function ( $ ) {

} ) (jQuery);

This assigns the $ sign to the jQuery object. In this file, we will enter the first parts of our inner function.

( function ( $ ) {
	wp.customize.bind( 'ready', function() {

		function hideShowColorControls() {
			/* Hide and show controls for Background Color and custom color schemes when "Custom" color scheme is chosen */
			// array for our id titles
			var colorControlIds = [
				'the_mx_custom_primary_1',
				'the_mx_custom_accent_1'
			];
			var bgColorControlId = '#customize-control-background_color';

		}
		
	} );
} ) (jQuery);

The wp.customize.bind( 'ready' ... ) bit of code checks that all controls and settings are loaded before adding our code. Next, we set up an array with the id titles of our two custom controls, taken from the Customizer settings. We also will hide the included Background Color by default, as well, indicated by the ID #customize-control-background_color. This was found by right clicking the control in question and inspecting it with the browser.

The next part is setting up an if-else statement that determines if we chose custom or anything else (brown) in our radio button control. Right after the variable setup, type the if statement:

			if ( wp.customize.instance( 'the_mx_color_scheme' ).get() === 'custom' ) {
				$.each( colorControlIds, function ( i, value ) {	
					$( '#customize-control-' + value ).show();
					$( bgColorControlId ).show();
				} );
			} else {
				$.each( colorControlIds, function ( i, value ) { 
					$( '#customize-control-' + value ).hide();
					$( bgColorControlId ).hide();
					//console.log( '#customize-control-' + value );
				} );
			}
			
			return hideShowColorControls;
		}
	} );
} ) (jQuery);

What we are doing here is retrieving the current value of the control with the id ‘the_mx_color_scheme’, using the Customizer JavaScript API .get() function and comparing it with the string ‘custom’. If it is equal, then we use jQuery’s each function to loop through each control.

Reading through the documentation for the each function, it accepts two arguments, an integer index and the element in the array. We’re interested in getting the element name, specified with the variable value. We look for each control that begins with #customize-control- and add each value from our array (colorControlIds). Along with bgColorControlId, we use jQuery’s show function. Otherwise, if the .get() function is not equal to ‘custom’, we hide everything. The return statement executes this function when called.

Now we want to call this function twice–once when the page loads, and then on change. Outside of the hideShowColorControls function, call it twice.

		}
	
		// Call this function on page load
		hideShowColorControls();
		
		// ... and on radio button change
		$( '#customize-control-the_mx_color_scheme' ).on( 'change', hideShowColorControls );

	} );

} ) (jQuery);

What happens on change, is that it switches the Color Pickers between show and hide based on the condition if custom is chosen or not. If you look at the code for the controls now, the list items that have become hidden have the inline style display: none applied to them.

Conclusion

In WordPress’s Static Front Page section, the underlying code for this functionality is probably written differently, but this method is based on a few new things I learned and the limits of my current knowledge. Since it worked, I think it achieved its goal and may fulfill this functionality for your theme. Below are images of the before and after.

WordPress Customizer

Customizer with hidden controls

WordPress Customizer

Customizer with shown controls.

Resources

Below are some of the articles that were very helpful.

Tags for this post: ,

Leave a Reply

Your email address will not be published. Required fields are marked *