3

I'm trying to add a range control underneath the feature image component in the admin dashboard, and I need to access the value from the post, so am saving it in post meta. It's all working great, but I can't figure out how to set a non-zero default value for the range control. Here's my code, first the component:

class RangeControlCustom extends React.Component {
    render() {
        const { meta, updateBackgroundPosition } = this.props;

        return (
            el(
                window.wp.components.RangeControl,
                {
                    label: 'Set image position',
                    help: "Choose where the image is to be aligned within it's container. Lower numbers set the top of the image lower, higher numbers set the top of the image higher.",
                    value: ( meta.banner_image_position !== '' && meta.banner_image_position !== null ) ? meta.banner_image_position : 50,
                    min: 0,
                    max: 100,
                    onChange:
                        ( value ) => {
                            this.setState( { value: value } );
                            updateBackgroundPosition( value, meta );
                        }
                }
            )
        );
    }
}

Now the composed control that gets included under the feature image control:

const composedRangeControl = wp.compose.compose( [
    withState( ( value ) => value ),        
    withSelect( ( select ) => {         
        const currentMeta = select( 'core/editor' ).getCurrentPostAttribute( 'meta' );
        const editedMeta = select( 'core/editor' ).getEditedPostAttribute( 'meta' );
        return {                
            meta: { ...currentMeta, ...editedMeta },            
        };      
    } ),        
    withDispatch( ( dispatch ) => ( {           
        updateBackgroundPosition( value, meta ) {               
            meta = {                    
                ...meta,                    
                banner_image_position: value,               
            };              
            dispatch( 'core/editor' ).editPost( { meta } );
        },
    } ) ),
] )( RangeControlCustom );

Now, if I change the value of the component to this:

value: meta.banner_image_position ? meta.banner_image_position : 50

... the default is then correct, but if the slider is moved to zero, it jumps to 50. I get why it does that from a logic perspective, but that leaves me with the same problem... how do I set the default value to something other than zero?

  • The initial value coming from meta is an empty string right? Isn't the approach you are showing in the component working value: ( meta.banner_image_position !== '' && meta.banner_image_position !== null ) ? meta.banner_image_position : 50,? (Im not sure you need to check for null) – Alvaro Aug 28 at 8:45
  • Well, no. That's the problem. There is currently no value in the database for this meta key, and I can't figure out what to check for. If I test directly for an empty string: meta.banner_image_position === '', it returns false. If I test for NaN, is returns false. If I test for null, it returns false. I have no idea what this value is, or how to check for a non-existent meta key here. – Jason RWD Aug 29 at 1:11
1

The issue here is on the PHP side. First we need to figure out if the meta key has been saved before and send this information to the editor. Once in the editor we can assign a default value if the meta key is new.

The way to check this is using get_post_custom_keys. We need to check for a certain post id and a certain meta key. To send this information to JavaScript we can use a rest route, lets say sending a rest request with the post id and the meta key which returns a boolean; or localize the output for the current post and then check against the array.

Lastly in the component we simply need to check if it exists. If so we apply the default value value: banner_image_position_has_been_saved ? meta.banner_image_position : 50.

Let me know if something was not clear.

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.