Viewing 8 replies - 1 through 8 (of 8 total)
  • Plugin Author Weston Ruter

    (@westonruter)

    @bradklosterman See my post on “Dependently-Contextual Customizer Controls”: https://make.xwp.co/2016/07/24/dependently-contextual-customizer-controls/

    Weston,

    I love your plugin, and I am currently moving my themes to being fully customizer compliant. I am, however, having a problem dealing with your dynamically created controls.

    I have also implemented the add-on (https://github.com/Invulu/custom-customizer-postmeta) to load my custom post meta. These are fields that I have created via ACF. All of these fields work perfectly for me, using the combination of your two plugins but I would like to add some UI/UX to the meta fields, and hide elements based on checkboxes being checked. If you look at the link below, you will see an example of what I am trying to do:
    https://www.dropbox.com/s/u7nxu9as4dxvsio/customizer-screen-shot.jpg?dl=0

    I read the article you referenced (above) but it seems to me that that only applies to controls that are either not created dynamically or are using options/theme_mods instead of post meta.

    Is is possible to dynamically show and hide these js created fields based on the checkbox or dropdown status? I know how to do all of this via jquery, in my wordpress plugins, but I am having a hard time figuring out what hook to use, or what code to use to properly bind to these controls in the JS-API

    Thanks so much for you work on this plugin, I look forward to hearing back from you.

    Plugin Author Weston Ruter

    (@westonruter)

    @tele2rn Hi. Actually the approach in my article on Dependent Contextual Controls will apply to dynamically-created controls, if you use the JS approach shown toward the bottom of the post.

    Weston,

    Thank you so much for your very quick response, but this is still not working for me. The first time through, I missed the link to your example called “Dependently-Contextual Site Title and Tagline Customizer Controls”, and that helped me understand the proper hooks to use, but it seems that i am still missing something

    I will try to layout my code below, and if you would be so kind, maybe you could tell me where I am going wrong:

    Here is my PHP

    <?php
    /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
    /* %%%%% Setup Controls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
    /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
    
    function fc_edit_customizer( $wp_customize ) {	
    	$custom_sidebars_controls = array_filter( array(
    		$wp_customize->get_control( 'page_layout' ),
    		$wp_customize->get_control( 'sidebar_left' ),
    		$wp_customize->get_control( 'sidebar_right' ),
    	) );
    	foreach ( $custom_sidebars_controls as $control ) {
    		$control->active_callback = function( $control ) {
    		$setting = $control->manager->get_setting( 'custom_sidebars' );
    		if ( ! $setting ) {
    			return true;
    		}
    			return 'blank' !== $setting->value();
    		};
    	}
    }
    add_action( 'customize_register' , 'fc_edit_customizer', 100 );
    
    /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
    /* %%%%% Enqueue JS File %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
    /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
    function fc_customize_controls_js() { 
    	wp_enqueue_script( 'fc-customizer-controls', plugin_dir_url( __FILE__ ).'js/customizer-controls.js', array( 'customize-controls' ) ); 
    }
    add_action( 'customize_controls_enqueue_scripts', 'fc_customize_controls_js' );
    ?>

    Here is my JS in the enqueued file (above)

    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    // %%%%% Contents of the customizer-controls.js File %%%
    // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    ( function( api ) {
    	'use strict';
    
    	api( 'custom_sidebars', function( setting ) {
    		var isDisplayed, linkToActiveState;
    
    		isDisplayed = function() { return 'blank' !== setting.get(); };
    
    		linkToActiveState = function( control ) {
    			var setActiveState = function() { control.active.set( isDisplayed() ); };
    
    			control.active.validate = isDisplayed;
    
    			setActiveState();
    
    			setting.bind( setActiveState );
    		};
    
    		api.control( 'page_layout', linkToActiveState );
    	} );
    
    }( wp.customize ) );

    My post_meta fields are called “custom_sidebars” and “page_layout” respectively.

    Is is possible that because this is not an option or a theme_mod, and that potentially there are many fields in the post_meta table that have this key, that maybe I have to somehow designate which post_ID I am trying to use.

    Again, I greatly appreciate your help on this, and thanks again for your great work on this plugin.

    Sincerely,

    Jesse W.

    Plugin Author Weston Ruter

    (@westonruter)

    @tele2rn I don’t see the custom_sidebars and page_layout settings being registered. This is probably related to what you’re saying with “maybe I have to somehow designate which post_ID I am trying to use”. In fact, if you look at Customize Posts you’ll see that it creates settings that have the post ID as part of the ID itself. For example, if a page (with ID 123) has a postmeta page_layout, then the setting ID for this postmeta that is added to the Customizer will be post[page][123][page_layout].

    I suggest studying the code in Customize Posts that is responsible for managing the featured image postmeta:
    https://github.com/xwp/wp-customize-posts/blob/develop/js/customize-featured-image.js
    https://github.com/xwp/wp-customize-posts/blob/develop/php/class-wp-customize-featured-image-controller.php

    There is some extra abstraction in there with the “controller” so you can also refer to the standalone “preamble” plugin: https://gist.github.com/westonruter/f8473159e48fbacbef9dcd6498155846

    Weston,

    Thanks again, for your help, your code examples helped me understand how I would need to format the IDs to get my code to work. And I have the following code working on my site, with one exception (I will explain below):

    api( 'postmeta[page][2][custom_sidebars]', function( setting ) {
    	var setActiveState, isDisplayed;
    
    	isDisplayed = function() {
    		if (setting.get() === true) { return true; } else { return false; }
    	};
    
    	setActiveState = function( control ) {
    		var setActiveState = function() {
    			control.active.set( isDisplayed() );
    		};
    
    		control.active.validate = isDisplayed;
    		setActiveState();
    		setting.bind( setActiveState );
    	};
    
    	api.control( 'postmeta[page][2][page_layout]', setActiveState );
    } );

    The one problem that I am still having, is that the active state is not being set on page reload or save. For example If I check my “custom_sidebars” checkbox, the “page_layout” menu appears, but if I save the changes, the “page_layout” menu disappears, and if I reload the customizer, the “page_layout” menu is hidden, until I check the “custom_sidebars” checkbox off and then on again. Any Ideas? I really appreciate your help.

    Sincerely,

    Jesse W.

    Plugin Author Weston Ruter

    (@westonruter)

    @tele2rn I’m guessing the problem is that your setting value is a boolean true in JavaScript when you modify it, but it is getting stored in postmeta as a string '1' since meta_value is a TEXT field in MySQL. So you should add a sanitize_js_callback which converts the PHP-saved value back into its client-side representation, so essentially boolval( $value ).

    • This reply was modified 7 years, 4 months ago by Weston Ruter.

    Weston,

    Thanks, that helped. i just changed the line like the following and everything is working great now:

    if (setting.get() == '1') { return true; } else { return false; }

    THanks again, your the best!

    Sincerely,

    Jesse W.

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘Conditionally Active Controls.’ is closed to new replies.