cbll
cbll

Reputation: 7219

Semantic-ui-react: How do I trigger a Popup without it being click/hover?

When submitting a form, I wish to show a small popup for 2.5 seconds if the server sends back a bad response.

The logic is fairly simple, however, I cannot figure out how to make this popup listen to a boolean somewhere in the state management(MobX in my case). I can get the content into the Popup just fine, however, the trigger is a button(and the content will show, if you click it) - But how do I make it listen to a boolean value somewhere?

Fairly simple class here:

import React from "react";
import { Popup, Button } from "semantic-ui-react";
import { inject } from "mobx-react";
const timeoutLength = 2500;

@inject("store")
export default class ErrorPopup extends React.Component {

    state = {
        isOpen: false
    };

    handleOpen = () => {
        this.setState({
            isOpen: true
        });

        this.timeout = setTimeout(() => {
            this.setState({
                isOpen: false
            })
        }, timeoutLength)
    };

    handleClose = () => {
        this.setState({
            isOpen: false
        });
        clearTimeout(this.timeout)
    };

    render () {

        const errorContent = this.props.data;


        if(errorContent){
            return(
                <Popup
                    trigger={<Button content='Open controlled popup' />}
                    content={errorContent}
                    on='click'
                    open={this.state.isOpen}
                    onClose={this.handleClose}
                    onOpen={this.handleOpen}
                    position='top center'
                />
            )
        }
    }
}

However, the trigger value is a button which is rendered if this.props.data is present. But that's not the behavior I wish; I simply want the popup to render(and thus trigger) if this.props.data is there; alternatively, I can provide a true value with props if need be.

But how do I make this component trigger without it being a hover/button?

Upvotes: 4

Views: 10220

Answers (2)

Greg Wozniak
Greg Wozniak

Reputation: 7182

Just use the property open as in the documentation. There is a separate example when popup is opened by default.

Upvotes: 0

Stas Parshin
Stas Parshin

Reputation: 1673

How about passing in the isOpen prop? Then you could add some logic onto the componentWillReceiveProps hook:

import React from "react";
import { Popup, Button } from "semantic-ui-react";
import { inject } from "mobx-react";
const timeoutLength = 2500;

@inject("store")
export default class ErrorPopup extends React.Component {

 constructor(props) {
   super(props);
   this.state = {
     isOpen: false,
   }
 };

  //This is where you trigger your methods
  componentWillReceiveProps(nextProps){
    if(true === nextProps.isOpen){
      this.handleOpen();
    } else {
      this.handleClose();
    }
  }

  handleOpen = () => {

    this.setState({
      isOpen: true
    });

    this.timeout = setTimeout(() => {
      //No need to repeat yourself - use the existing method here
      this.handleClose();
    }, timeoutLength)
  };

  handleClose = () => {
    this.setState({
      isOpen: false
    });
    clearTimeout(this.timeout)
  };

  render () {

    const errorContent = this.props.data;

    if(errorContent){
      return(
        <Popup
          trigger={<Button content='Open controlled popup' />}
          content={errorContent}
          on='click'
          open={this.state.isOpen}
          position='top center'
        />
      )
    }
  }
}

Without a need of handling delay - you could simply pass in the isOpen prop and that would do the trick.

And here what it could look like in your parent component's render:

let isOpen = this.state.isOpen; 
<ErrorPopup isOpen={isOpen}/>

Set this value to control the popup, ideally, this should be a part of your parent component's state. Having a stateful component as a parent is important to make the popup re-rendered

Upvotes: 3

Related Questions