2

I am implementing the drag and drop mechanic using react-dnd library, but I find it hard to style my drop targets. I want to show the user which drop target is available to drop on, but using the isOver and canDrop will only style the item that is currently being hovered on.
If I use the !isOver value, all the divs are being styled, without even dragging any of the elements.
How can I style the drop targets only when the dragging of an element happens?
This is my code so far, for a @DropTarget:

import React from 'react';
import {DropTarget} from 'react-dnd';
import {ItemTypes} from './Constants';

const target = {
    drop(props, monitor, component){
        // console.log("Dropped on", props.id);
    },

    canDrop(props, monitor, component){
        var cardColumn = monitor.getItem().column;
        var targetColumn = props.column;
        return false; // still testing styling when only an element is being dragged on the page
    }

};

@DropTarget(ItemTypes.CARD, target, (connect, monitor) => ({
    connectDropTarget: connect.dropTarget(),
    isOver: monitor.isOver({shallow: true}),
    canDrop: monitor.canDrop(),
}))
class CardList extends React.Component{
    constructor(props){
        super(props);

        this.addClass = this.addClass.bind(this);
    }

    addClass(){
        const {isOver, canDrop} = this.props;
        if(isOver && canDrop){
            return "willDrop"; // green background for .card-list
        }
        if(isOver && !canDrop){
            return "noDrop"; // red background for .card-list
        }
        if(!isOver && !canDrop){
            return ""; // will style all the backgrounds in a color, but not when dragging
        }

    }

    render(){
        const {connectDropTarget} = this.props;

        return connectDropTarget(
            <div class={"card-list col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12 " + this.addClass()} id={this.props.id}>
                {this.props.children}
            </div>
        );
    }
}

export default CardList;

Is there a way to get the isDragging value when an element is being dragged on the page, since this is the only possibility to obtain what I want.
Thanks!

Justplayit
  • 667
  • 1
  • 7
  • 22

1 Answers1

1

Both isOver and canDrop implicitly do the isDragging check, per http://react-dnd.github.io/react-dnd/docs-drop-target-monitor.html - note that they only return true if a drag operation is in progress. Therefore, if you want to style drop targets such that only when something that can be dragged is being dragged, then I think you need another case in your addClass() function to handle that, like this:

addClass(){
    const {isOver, canDrop} = this.props;
    if(isOver && canDrop){
        return "willDrop"; // green background for .card-list
    }
    if(isOver && !canDrop){
        return "noDrop"; // red background for .card-list
    }
    if(!isOver && canDrop){
        return ""; // THIS BLOCK WILL EXECUTE IF SOMETHING IS BEING DRAGGED THAT *COULD* BE DROPPED HERE
    }
}

And I don't think you want the !isOver && !canDrop block - this will execute even when nothing is being dragged at all.

Ben Hare
  • 4,365
  • 5
  • 27
  • 44