How to implement a drag and drop on dynamic divs in react?

Viewed 1076

Basically what I'm trying to do is to make dynamic divs that are generated by mapping draggable and change position during the drop event. What I tried is changing the CSS of the div through its id on a drop event.

My thought process is that on a dragStart I'd set the divs id, clientX and clientY on the dataTransfer and onDrop it would move the element based on where the mouse drops it.

It moves but it's not what I expected.

Code below:

import React, { Component } from 'react';
import uuid from 'uuid'

class OutputContainer extends Component {

    state = {
        selectValue: "Variable List",
        propVariableArray: [],
        imageBoundary: {}
    }

    componentWillReceiveProps(updatedProps) {
        this.setState({ propVariableArray: updatedProps.variables })
    }

    componentDidMount() {
        this.setState({ imageBoundary: this.refs.image.getBoundingClientRect() });
    }

    onDrop = (event) => {
        event.persist();
        var targetParameters = event.dataTransfer.getData("text");

        targetParameters = targetParameters.split(',')

        let div = document.getElementById(targetParameters[0]);// probably not a good way 
        this.props.repositionXY(targetParameters)

        div.style.left = (parseInt(targetParameters[1]) + event.clientX) + 'px';
        div.style.top = (parseInt(targetParameters[2]) + event.clientY) + 'px';
    }
    onDragOver = (event) => {
        event.preventDefault();
    }

    onDrag = (event) => {
        event.dataTransfer.setData('text/plain', event.target.id + "," + event.clientX + "," + event.clientY);
    }

    render() {
        return (
            <div style={{ position: "absolute" }}>
                <div>
                    <select defaultValue={"Variable List"} onChange={e => this.setState({ selectValue: e.target.value })}>
                        <option disabled>{"Variable List"}</option>
                        {
                            this.state.propVariableArray.map(variable => {
                                return (
                                    <option key={uuid.v4()} >{variable.placeholder}</option>
                                )
                            })
                        }
                    </select>
                </div>

                <div
                    style={{ position: "absolute", zIndex: 0 }}
                    onDragOver={e => this.onDragOver(e)}
                    onDrop={e => this.onDrop(e)}
                >
                    {this.props.variables.map((variable, index) => {
                        return (

                            <div
                                key={uuid.v4()}
                                id={variable.id}
                                draggable
                                style={{ display: "block", marginRight: "1em", zIndex: index + 1, position: "absolute", left: variable.XY[0], top: variable.XY[1] }}
                                onDragStart={(e) => this.onDrag(e)}
                            >
                                {variable.placeholder}
                            </div>
                        )
                    })}
                    <img ref={'image'} src={this.props.imageSource} alt={"Certificate Preview"} style={{ position: "absolute" }} draggable='false' />
                </div>
            </div>
        )
    }
}

export default OutputContainer;

Any help is appreciated. Thanks!

0 Answers
Related