0

I am trying to make a draggable button using react.

The button drags over the page in a proper manner but when I drop it. Its top and left values become negative(not even reset to their original top:0,left:0) i.e. the component goes out of the page.

code sand box link : code

main draggable.js component:

import React, { Component } from 'react';
import { Button } from '@material-ui/core';

class DraggableButton extends Component {

    constructor() {
        super();
        this.state = {
            dragging: false,
            diffX: 0,
            diffY: 0,
            style: {
                top: 0,
                left: 0
            }
        }
    }

    handleMouseDown = (event) => {
        console.log("element caught");
        this.setState({
            diffX: event.clientX - event.currentTarget.getBoundingClientRect().left,
            diffY: event.clientY - event.currentTarget.getBoundingClientRect().top,
            dragging: true
        })
    }

    handleMouseMove = (event) => {
        if (this.state.dragging) {
            console.log("dragging");
            let left = event.clientX - this.state.diffX;
            let top = event.clientY - this.state.diffY;

            this.setState({
                style: {
                    left,
                    top
                }
            }, console.log("style ", this.state.style))
        }
    }


    handleMouseUp = () => {

        console.log('element released');
        console.log('left value ', this.state.style.left);
        console.log('top value ', this.state.style.top);
        this.setState({
            dragging: false,
        })
    }


    render() {
        return (

            <Button
                variant="contained" color="primary"
                style={{ position: "absolute", ...this.state.style }}
                draggable={true}
                onDragStart={this.handleMouseDown}
                onDrag={this.handleMouseMove}
                onDragEnd={this.handleMouseUp}
            // onMouseDown={this.handleMouseDown}
            // onMouseMove={this.handleMouseMove}
            // onMouseUp={this.handleMouseUp}
            >
                draggable button
            </Button>
        );
    }
}

export default DraggableButton;

console screenshot :

console view

As is visible in the image above at the time of dragging top: 193 left : 309 and as we dropped the element it turned to left: -109 top: -13.

why is this happening how can we fix it ?

1 Answer 1

1

In your handleMouseMove you need to check if event.clientX is a positive integer and then change the state, or else it will reduce the diffX value and it will be nevative. (On drag release this becomes 0)

let left = event.clientX - this.state.diffX;



  handleMouseMove = (event) => {
    if (this.state.dragging) {
      let left = event.clientX - this.state.diffX;
      let top = event.clientY - this.state.diffY;

      if (event.clientX !== 0)
        this.setState({
          style: {
            left,
            top
          }
        });
    }
  };
Sign up to request clarification or add additional context in comments.

2 Comments

this worked can you tell me why onDrag ( handleMouseMove ) was fired when it should be just onDragEnd ( handleMouseUp ) when we release the mouse button
since you are in dragging process, it will be always called. check this https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_ondrag and replace "The p element is being dragged" with new Date().getTime() to see that it is constantly updating the div

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.