RiddleMeThis
RiddleMeThis

Reputation: 1345

React JS JSX Show or Hide Based on Another Toggle Component

I have 2 toggle components that show/hide panels under them which is working fine. However, If I toggle the second panel I need to make sure the first panel is off. Same with the first, I don't want the two panels toggled open at once.

Here is a basic example of what I have.

<ToggleControl
    label={__( 'Toggle One' )}
    checked={ toggleOne }
    onChange={ () => this.props.setAttributes({ toggleOne: ! toggleOne }) }
/>

    { toggleOne ?
        <PanelBody>
            ... Show Panel 1 Stuff
        </PanelBody>
    : null }

<ToggleControl
    label={__('Add Image Divider')}
    checked={toggleTwo}
    onChange={() => this.props.setAttributes({ toggleTwo: !toggleTwo })}
/>

    { toggleTwo ?
        <PanelBody>
            ... Show Panel 2 Stuff
        </PanelBody>
    : null }

I can toggle the other panel inside the onChange() of the other toggle by doing this...

onChange={() => this.props.setAttributes({ toggleTwo: !toggleTwo, toggleOne: !toggleOne })}

But I don't want to toggle it if its already off and can't seem to figure it out.

Thanks.

Upvotes: 0

Views: 202

Answers (2)

Bryan Scott
Bryan Scott

Reputation: 4737

[Edit: Props are read-only, and while my original answer and the accepted answer were identical and do the trick, I'm adjusting my answer to show the "proper" way to do it through manipulating state, not props.]

I don't know why you're tracking the changes on this.props instead of this.state, but here is one way:

To be added in constructor:

this.state = { toggleOne: this.props.toggleOne, toggleTwo: this.props.toggleTwo }

For Toggle One:

onChange={ () => this.setState({ toggleOne: !this.state.toggleOne, toggleTwo: !this.state.toggleOne ? false : this.state.toggleTwo }) }

For Toggle Two:

onChange={ () => this.setState({ toggleTwo: !this.state.toggleTwo, toggleOne: !this.state.toggleTwo ? false : this.state.toggleOne }) }

And of course set the checked attributes to this.state.toggledOne/Two.

Logic:

  1. Set ourselves to our opposite state.
  2. If our current state is off (false) and we're toggled on (!false), turn our neighbor off (false); if we're switching from on to off, leave our neighbor where they are (which in most cases will be off because we were just on).

My additional true/false check at the end vs. the default of false in the accepted answer is meant to catch the case that both toggles were opened on purpose (i.e. programmatically). This may not ever be the case for your scenario, but for others looking for a similar solution who may want this feature, there you have it.

Upvotes: 1

Mi_Onim
Mi_Onim

Reputation: 412

To turn off a panel, you can just set the toggle variable to false.

To turn off the first panel when toggling the second panel, you can do the following:

onChange={() => this.props.setAttributes({ toggleTwo: !toggleTwo, toggleOne: false })}

Similarly, to turn off the second panel when toggling the first panel, you can do the following:

onChange={() => this.props.setAttributes({ toggleOne: !toggleOne, toggleTwo: false })}

This will make sure that when toggling one panel, the other one is always off, so that you will not have both panels toggled on at the same time.

Upvotes: 1

Related Questions