maddie
maddie

Reputation: 1954

React Drag and Drop: Div Refuses Drag

I have tried to build a react app that has drag and drop list functionality without downloading any external packages. I found a tutorial that purports to do exactly that

This is my code:

class App extends React.Component {
  state = {
    items: ["3", "2", "1", "4"]
  };

  onDragStart = (e, index) => {
    console.log("drag start!!!");
    this.draggedItem = this.state.items[index];
    e.dataTransfer.effectAllowed = "move";
    e.dataTransfer.setData("text/html", e.target.parentNode);
    e.dataTransfer.setDragImage(e.target.parentNode, 20, 20);
  };

  onDragOver = index => {
    const draggedOverItem = this.state.items[index];

    // if the item is dragged over itself, ignore
    if (this.draggedItem === draggedOverItem) {
      return;
    }

    // filter out the currently dragged item
    let items = this.state.items.filter(item => item !== this.draggedItem);

    // add the dragged item after the dragged over item
    items.splice(index, 0, this.draggedItem);

    this.setState({ items });
  };

  onDragEnd = () => {
    this.draggedIdx = null;
  };

  render() {
    return (
      <div className="App">
        <main>
          <h3>List of items</h3>
          <ul>
            {this.state.items.map((item, idx) => (
              <li key={item} onDragOver={() => this.onDragOver(idx)}>
                <div
                  className="drag"
                  draggable
                  onDragStart={e => this.onDragStart(e, idx)}
                  onDragEnd={this.onDragEnd}
                  style={{ cursor: "pointer" }}
                />
                <span className="content" style={{ cursor: "pointer" }}>
                  {item}
                </span>
              </li>
            ))}
          </ul>
        </main>
      </div>
    );
  }
}

I don't get any bugs in console. However, the items in the list refuse to be dragged. On the offhand chance that I can drag an item, I can't get it to where I want to go and it introduces a weird gap/space: enter image description here

This is my codesandbox:https://codesandbox.io/s/angry-dewdney-xzhsi

Upvotes: 1

Views: 1938

Answers (2)

Seth Samuel
Seth Samuel

Reputation: 355

Add the "draggable=true" to the element to want to drag You need to allow dropping by adding this code to the element to want to drop on. HTML by default doesn't allow drops

    onDragOver={event=>event.preventDefault()}

Upvotes: 0

Maria
Maria

Reputation: 295

Try changing the render to have the draggable div wrap the span with the text like this:

<div
 className="drag"
 draggable
 onDragStart={e => this.onDragStart(e, idx)}
 onDragEnd={this.onDragEnd}
 style={{ cursor: "pointer" }}
>
   <span className="content" style={{ cursor: "pointer" }}>
      {item}
   </span>
</div>

Otherwise you have to click on the empty div which would be next to impossible as you noted. This way the draggable div wraps the text so whenever you click on the text you're clicking the div.

Upvotes: 2

Related Questions