Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't select input text in Chrome #438

Closed
maxsalven opened this issue Apr 13, 2016 · 10 comments
Closed

Can't select input text in Chrome #438

maxsalven opened this issue Apr 13, 2016 · 10 comments

Comments

@maxsalven
Copy link

I believe this is still an issue for <input />. See screen grab:

#358 (comment)

@mondaychen
Copy link

mondaychen commented Jun 9, 2016

+1 for this. It's pretty annoying and I can't find a good way to fix it.
I found this workaround #335 but my <input> is in a grandchild component. It's hard to add event listeners from drag source level.

@kesne kesne added the triage label Aug 20, 2016
@ngoctigerstyle
Copy link

Had this issue been fixed?

@tention
Copy link

tention commented Aug 3, 2017

Encountered the same problem here.

@tcosentino
Copy link

tcosentino commented Aug 14, 2017

I am also looking for a good solution to this.

Here is a collection of issues that have been created for this, for reference:

Per @mondaychen, here is @gaearon's suggestion from #335:

render() {
  let element = (
    <div>
      <input
        onMouseEnter={() => this.setState({ overInput: true }) }
        onMouseLeave={() => this.setState({ overInput: false }) }
      />
    </div>
  );

  if (this.state.overInput) {
    return element;
  }

  return this.props.connectDragSource(element);
}

The reason this doesn't work for me is that I have somewhat "unknown" children. The children are always forms but can be nested and used in other (non-draggable) situations. In my application, we could add onMouseEnter and onMouseLeave to each input, and keep overInput in our redux store to always know if an input is being hovered - but this will be overkill in any situation other than the sorting page.

@cscleison added this suggestion 11/11/16:

class RowDraggable extends React.Component {
    node = undefined;
    constructor(props, ctx) {
      super(props, ctx);

      this.onHoverOverInput = this.onHoverOverInput.bind(this);
      this.onHoverOutOfInput = this.onHoverOutOfInput.bind(this);

      this.state = {overInput: false};
    }
    componentWillUnmount() {
      this.detachEventListeners(this.node);
      this.node = undefined;
    }
    getInputElements(node) {
      return node
        ? Array.prototype.slice
            .call(node.getElementsByTagName('input'))
            .filter(e => !e.readOnly)
        : [];
    }
    onHoverOverInput() {
      this.setState({overInput: true});
    }
    onHoverOutOfInput() {
      this.setState({overInput: false});
    }
    detachEventListeners(node) {
      this.getInputElements(node).map(e => {
        e.removeEventListener('mouseleave', this.onHoverOutOfInput);
        e.removeEventListener('mouseenter', this.onHoverOverInput);
      });
    }
    render() {
      const { rowProps, isOver, connectDropTarget, connectDragSource
        } = this.props;
      const { overInput } = this.state;

      return <YourRow
            isOver={isOver}
            ref={instance => {
              this.detachEventListeners(this.node);
              this.node = findDOMNode(instance);

              if (!overInput) {
                connectDragSource(this.node);
                connectDropTarget(this.node);
                this.getInputElements(this.node).map(e => {
                  e.addEventListener('mouseenter', this.onHoverOverInput);
                });
              } else {
                this.getInputElements(this.node).map(e => {
                  e.addEventListener('mouseleave', this.onHoverOutOfInput);
                });
              }
            }}
          />;
    }
}

This seems like my best option so far. It seems very hacky but like it would work. Any other ideas?

@tention
Copy link

tention commented Aug 15, 2017

Workaround mine with the use of Redux store instead of React state when my <input> is in a child component. Assign connectDropTarget() only when editing is true.

Similar to gaearon suggestion #335 but replace the state with Redux store.

@tcosentino
Copy link

@tention yes, sounds like this might be best. I wish I didn't have to remind form makers to include these events on each input going forward, but probably not much else to do!

@lulupy
Copy link

lulupy commented Dec 14, 2018

my solution is:

<input
  onDragStart={(event) => {
     event.stopPropagation();
      event.preventDefault();
   }}
   draggable
/>

@stale
Copy link

stale bot commented Jul 6, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jul 6, 2019
@stale stale bot closed this as completed Jul 13, 2019
@harekuer
Copy link

my solution is:

<input
  onDragStart={(event) => {
     event.stopPropagation();
      event.preventDefault();
   }}
   draggable
/>

it works for me,great

@rbehal
Copy link

rbehal commented Dec 7, 2023

This is not documented very well, but if you add the class name nodrag this works to not allow dragging by the text input field, meaning you can select and highlight text with your cursor.

No other solutions solved my issue.

      <>
        <Input
          disabled={isDisabled}
          value={value}
          onChange={handleChange}
          className={'nodrag'}
          placeholder={placeholder}
          multiline
          error={error_message}
        />
      </>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants