React-dnd: Disable drag on inputs inside a draggable component ?

Created on 15 Nov 2015  ·  6Comments  ·  Source: react-dnd/react-dnd

Is there any simple way of doing this ?

My use case is to make draggable components with editable fields inside them, and its really inconvenient when trying to select the text you start dragging the block.

Most helpful comment

I think you should be able to do something like

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);
}

All 6 comments

I think you should be able to do something like

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);
}

how about this?

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);
                });
              }
            }}
          />;
    }
}

@gaearon Thanks, its just simple and easy solution. Saved my day.

Hi, I'm new to react dnd, how am I supposed to pass connectDragSource to the child as in @gaearon 's answer?

@gaearon i'm having a serious trouble with my customer about issue in this page https://react-dnd.github.io/react-dnd/examples-nesting-drag-sources.html I have a tree. In the tree where are some nodes which are not allowed to be dragged. I return canDrag is false but because i'm using nested DnD so it's automatically call to parent and instead of not allow dragging for the children it dragged parent :(. Could you give me a clue how to disable asking parent by default?. It's really urgent from customer and I still can't figure out how :(

@deanmaster do you have a solution to your problem?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andrewQwer picture andrewQwer  ·  27Comments

schmaluk picture schmaluk  ·  34Comments

jchristman picture jchristman  ·  27Comments

prakhar1989 picture prakhar1989  ·  62Comments

gaearon picture gaearon  ·  30Comments