0

I need to simulate a click outside of my react dropdown. The problem is, I am a junior dev (not even that) with 3 months experience, non with react. I have tried many tutorials but to no avail. I guess I am just not good enough for now, and I don't understand, so i'm asking here as my last resort, maybe someone with more skill can help me hide my dropdown. This is my code:

render() {
  return (
    <div className="header-dropdown-wrap d-none d-md-inline-block ">
      <svg className="header-dropdown-icon" viewBox={ClockIcon.viewBox} width="15">
        <use xlinkHref="#clock" />
      </svg>
      <Dropdown
        className="header-dropdown"
        onMouseOver={() => this.hover(true)}
        onMouseLeave={() => this.dynamicHoverHandle()}
        isOpen={this.state.toggle || this.state.hover}
        toggle={this.toggle}
      >
        <DropdownToggle>
          <span>{this.state.time.format("HH:mm")}</span>
        </DropdownToggle>
        <DropdownMenu onMouseDown={this.props.onMouseDown} onMouseUp={this.props.onMouseUp} modifiers={horizontalMiddleModifier()}>
          <div className="extra-padding">
            <div className="dropdown-menu-inner-wrap inner-menu">
              <Scrollbar style={{ height: 300, width: 400 }}
                thumbYProps={{
                  renderer: props => {
                    const { elementRef, ...restProps } = props;
                    return (<div {...restProps} ref={elementRef} className="tHuMbY" >
                      <span style={{
                        "position": "absolute",
                        "display": "block",
                        "width": "100%",
                        "height": "100%",
                        "top": "0",
                        "left": "0",
                        "content": " "
                      }} className="huj" onMouseDown={() => this.changeActiveScrollState()}></span>
                    </div>);
                  }
                }}
              >
                {TIMEZONES.map((timezone, idx) => {
                  return (
                    <DropdownItem active={timezone.offset === this.state.timezone} key={idx} onClick={() => this.select(timezone.offset)}>
                      {/*<span className="dropdown-item-icon"></span>*/}
                      <span className="dropdown-item-text">{timezone.name}</span>
                    </DropdownItem>
                  );
                })}
              </Scrollbar>
            </div>
          </div>
        </DropdownMenu>
      </Dropdown>
    </div>
  );
}

Here are the states and the constructor:

constructor() {
  super();

  this.state = {
    toggle: false,
    time: moment(),
    hover: false,
    timezone: '',
    activeScroll: false
  };

  this.toggle = this.toggle.bind(this);
  this.update = this.update.bind(this);
  this.hover = this.hover.bind(this);
  this.dynamicHoverHandle = this.dynamicHoverHandle.bind(this);
  this.changeActiveScrollState = this.changeActiveScrollState.bind(this);
}

componentDidMount() {
  const timezone = parseInt(localStorage.getItem("timezone"));
  if (timezone !== null) {
    this.setState({ timezone });
  }
  this.update();
  this.intervalID = setInterval(this.update, 1000)

  //this.scrollbar.thumbYElement.addEventListener('mousedown', () => {
  //    console.log('dsaadadd')
  //})
}

componentWillUnmount() {
  clearInterval(this.intervalID);
}

update() {
  const timezone = this.state.timezone;
  const time = (timezone !== null) ? moment().utcOffset(timezone) : moment();
  this.setState({ time })
}

toggle() {
  this.setState({ toggle: !this.state.toggle });
  console.log('isToggled');
}



hover(hover) {
  if (hover !== this.state.hover) {
    this.setState({ hover });
    this.setState({ toggle: hover });
  }
}

select(timezone) {
  this.setState({
    time: moment().utcOffset(timezone),
    timezone,
    hover: false,
  });
  localStorage.setItem('timezone', timezone);
}

dynamicHoverHandle() {
  if (!this.state.activeScroll) {
    // close on hover when scroll not clicked
    console.log('scroll was NOT clicked');
    this.hover(false)
  } else {
    // not close
    this.hover(true)
    console.log('scroll was clicked');
  }
}

changeActiveScrollState() {
  this.setState({ activeScroll: true });
}

A fix has been found in the link provided by @ford04

Kris KL
  • 1
  • 1
  • I need to simulate a click outside of the dropdown and when that happens the dropdown dissapears if it was open. – Kris KL Jul 30 '20 at 08:16
  • Welcome. Have you already looked into [this post](https://stackoverflow.com/questions/32553158/detect-click-outside-react-component)? – ford04 Jul 30 '20 at 08:18
  • @ford04 Yes, but my knowledge is not good enough to understand everything there. I am sorry If I shouldnt have posted this and tried hard. But yea, ill try looking harder into that one because it seems like a valid and good way of doing it. – Kris KL Jul 30 '20 at 08:27
  • So I used the first solution on the post you recommended, I got the: You clicked outside of me alert going when I click outside of it, but how do I close my dropdown when that happens? Sorry for bothering with stupid questions. @ford04 – Kris KL Jul 30 '20 at 10:10
  • You presumably need to toggle some sort of `visible` flag state for the Dropdown component, when the click handler is triggered (having only skimmed over the code) – ford04 Jul 30 '20 at 10:30
  • I created a hook file as it was shown on the post you shared, how do I access the hover or toggle state from my main file in my new file, how do I call it ```function handleClickOutside(event) { if (ref.current && !ref.current.contains(event.target)) { console.log('You clicked outside of me'); this.setState( { hover: false }) } }``` I added it here but on the console it says this.setState is not a function. – Kris KL Jul 30 '20 at 10:49
  • I edited my question with: A fix has been found in the link provided by @ford04 I had to do a little tinkering. Its all good now thank you for your help. – Kris KL Jul 31 '20 at 09:23

0 Answers0