React-select: Click event "goes through" and clicks on elements behind list

Created on 22 Oct 2015  路  33Comments  路  Source: JedWatson/react-select

I have a problem whereby the click to select an option seems to go through to elements underneath the list. The selection itself works, but I dont want things underneath to get clicked on. How can I stop this?

issubug-confirmed issureviewed

Most helpful comment

I can confirm @luciandragomir's answer works for MaterialUI users - adding this solved the problem for me:

  .Select-menu-outer {
    z-index: 3;
  }

All 33 comments

I think this issue is actually related to react-tap-event-plugin which unfortunately is a requirement of the very popular material-ui. This library must do something with the events which isn't compatible in some way. Any ideas?

Relevant discussion: https://github.com/facebook/react/issues/2061

I believe react-tap-event-plugin will eventually be built into react by the time 1.0 arrives -- so it might be useful to tackle this now.

+1

Did you find a solution ?

I have a hack in place that listens on the react-select events to set pointer-events: none on everything while the select box is open -- pretty horrible.

Horrible things can save me :p
How do you catch when the select box is open ?

I have bound these attributes to the select

onFocus={this.disableClick.bind(this, true)} onBlur={this.disableClick.bind(this, false)}

disableClick does something like:

disableClick(disable) {
    this.setState({ disableClick: disable });
    return true;
}

And then in my render I have this on an element which wraps both the select and everything that could potentially be underneath it:

style={{pointerEvents: this.state.disableClick ? 'none' : 'all'}}

Note that this wont fix browsers that don't support pointer events which I think is < IE 11.

Does this have something to do with react-select triggering on mousedown rather than on click?

I am also running into this issue, and can confirm that is is related to https://github.com/zilverline/react-tap-event-plugin. Anything behind the dropdown listening to onTouchTap events will trigger through the dropdown's container.

Has anyone tried using 1.0's CustomComponents and onTouchDown events, similar to this?

+1 Also ran into this problem.

I am using react select in a dialogue box. I made the options overflow the dialogue box. Every time an overflowed option is closed, the dialogue box automatically closes, as if the area below the options and outside of the dialogue is clicked.

It seems that this problem has been fixed in the 1.0.0 version of react-tap-event-plugin. Reference: https://github.com/facebook/react/issues/2061

However, the bug still exists in my project.

+1 same problem.

I also ran into a variation of this problem so I thought this might help.

I am using the Checkbox component from material-ui and the select menu goes on top of the checkbox, but whenever I selected the option right on top of the checkbox, it would get checked/unchecked.
After two days of scanning through the libraries to find why that happens I saw that the checkbox uses the z-index: 2 which causes the click to propagate to the checkbox first, so I managed to fix that by setting the z-index to a really high value on the Select-menu-outer class.

So what is the solution for this problem?

I'm currently using "react-select": "1.0.0-rc.2" and "react-tap-event-plugin": "2.0.0"

My solution to this was to stop using react-tap-event-plugin.

This might not work for everyone but the 300ms delay is history as of iOS 10 (and recent updates of iOS 9) it's also easily worked around in most "recent" versions of Android. Even iOS 8 does not wait 300ms if you use a "long touch".

I hope that helps!

Unfortunately, I don't use react-tap-event and the problem still occurs?
@adamscybot solution seems a bit hackish for my taste ...

See prateekjahead's comment: https://github.com/JedWatson/react-select/issues/1010
"HubSpot's react-select-plus takes in dropdownComponent as a prop which solves the issue."

Can some one try react-select-plus and see if it fixes the issue?

I can confirm @luciandragomir's answer works for MaterialUI users - adding this solved the problem for me:

  .Select-menu-outer {
    z-index: 3;
  }

Seems like the issue is that it hides the options on a Mouse down, now if there are elements behind it, they are triggered by the Mouse up event. At least that was the issue in my case. Changed the element below to trigger on mouse up and it fixed it for me.
It has been mentioned before in : https://github.com/JedWatson/react-select/issues/432

I did so:
injectTapEventPlugin({
shouldRejectClick: () => document.body.querySelector('.Select-menu-outer')
});

+1 I see this problem on mobile devices and no solution mentioned seems to fix it. I think it is specifically because of the touch events. I am not using Material UI and not using react-tap-event-plugin.

A custom option component, where mouse-down handlers were replaced by mouse-up handlers, worked for me:

import React from 'react'
import createClass from 'create-react-class'
import PropTypes from 'prop-types'

const CustomReactSelectOption = createClass({
  propTypes: {
    children: PropTypes.node,
    className: PropTypes.string,
    isDisabled: PropTypes.bool,
    isFocused: PropTypes.bool,
    isSelected: PropTypes.bool,
    onFocus: PropTypes.func,
    onSelect: PropTypes.func,
    option: PropTypes.object.isRequired,
  },
  handleMouseUp(event) {
    event.preventDefault()
    event.stopPropagation()
    this.props.onSelect(this.props.option, event)
  },
  handleMouseEnter(event) {
    this.props.onFocus(this.props.option, event)
  },
  handleMouseMove(event) {
    if (this.props.isFocused) return
    this.props.onFocus(this.props.option, event)
  },
  render() {
    return (
      <div
        className={this.props.className}
        onMouseUp={this.handleMouseUp} // Mouse Up instead of Mouse Down
        onMouseEnter={this.handleMouseEnter}
        onMouseMove={this.handleMouseMove}
        title={this.props.option.title}
        role="listitem"
      >
        {this.props.children}
      </div>
    )
  },
})

export default CustomReactSelectOption

and then

import CustomReactSelectOption from './CustomReactSelectOption'
...
          <Select
            ...
            optionComponent={CustomReactSelectOption}
            ...
          />

I did this wild thing where I added onClick={e => e.preventDefault()} to a parent div of all the react-select components and then the click-through bug stopped.

Does this work for anyone else?

@ptboyer it did not work for me =(

Did you only wrap the react-select components or did you also wrap the stuff underneath it?

@donatoaz something like this worked for me:

  <span onClick={e => e.preventDefault()}>
      <div>
        <Select />
      </div>
      <div>
        <Select />
      </div>
      <div>
        <Select />
      </div>
  </span>

Thanks @ptboyer

Yeah, that did not work out for me... Underneath the select I have a react-big-calendar and the onSelectSlot is being triggered.

Perhaps an issue with that lib then.

For some reason, clicking an option in a react-select v1 dropdown did not cause the underlying component onClick() to fire, to the best of my knowledge. Now that I upgraded to v3, it does.

It would be nice if we were able to pass down a custom onClick to the Select component to just preventDefault() and/or stopPropagation() without having to add a wrapper div that could potentially break bad CSS styles.

I used the event.stopPropogation() method and it worked.
Reference: https://stackoverflow.com/questions/37568550/react-prevent-event-trigger-on-parent-from-child

Yeah, that did not work out for me... Underneath the select I have a react-big-calendar and the onSelectSlot is being triggered.

Perhaps an issue with that lib then.

Did you get a solution to this?

@JohnDDuncanIII Thanks a lot! This solved my issue.

In my case, clickable list item behind Dialog was clicked whenever I click anywhere in the opened Dialog. I am using @material-ui. Now added following in Dialog and problem resolved.

onClick={e => { e.preventDefault(); e.stopPropagation(); }}

@ajay-bsoft glad it worked. Our solution was similar (we just wrapped that specific select with a div that invokes preventDefault and stopPropagation).

return (
    <div
        // necessary because the Select onClick() event propagates down to the SheetCell onClick() every time we click on a select,
        // which re-calls clickCell() after the unclickCell() action creator is fired in patchColumnData of sheet-action-creators
        // Since it is not possible to pass an onClick prop down to a react-select component, this is necessary
        // https://github.com/JedWatson/react-select/issues/532
        onClick={(e) => {
            e.preventDefault()
            e.stopPropagation()
        }}
    >
        <Select
            loadOptions={this.loadOptions}
            {...this.props}
            className={className}
        />
    </div>
)

Hi all,

In an effort to sustain the react-select project going forward, we're cleaning up and closing old issues.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.

If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.

However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!

Still relevant

Thanks for the feedback @nuxf10ir, much appreciated.

I saw this issue in version 3.1.0, I experienced it on touch devices only. Adding e.preventDefault() and e.stopPropagation() into onClick on a container did not resolve it. Nor did adding those to onMouseDown, onMouseUp, or onTouchStart.

This was finally resolved by adding e.preventDefault() in onTouchEnd on the select's containing element.

@nuxf10ir do you have a use case that is not resolved by the solutions above?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

steida picture steida  路  3Comments

mjuopperi picture mjuopperi  路  3Comments

sampatbadhe picture sampatbadhe  路  3Comments

geraldfullam picture geraldfullam  路  3Comments

coder-guy22296 picture coder-guy22296  路  3Comments