0

I am trying to use react DnD in my react Project. In my render method I define a variable named Populate like show below, which returns a list of cards like this

 render() {
        var isDragging = this.props.isDragging;
        var connectDragSource = this.props.connectDragSource;

        var Populate = this.props.mediaFiles.map((value) => {
            return(
                <div>
                <MuiThemeProvider>
                    <Card style= {{marginBottom: 2, opacity: isDragging ? 0 : 1}}  id={value.id} key={value.id}
                          onMouseOver={this.onMouseOver}
                          onMouseOut={this.onMouseOut}
                          //onTouchTap={() => {this.handleClick(value.id)}}
                          zDepth={this.state.shadow}>
                        <CardHeader
                            title={value.Episode_Name}
                            //subtitle={value.description}
                            actAsExpander={false}
                            showExpandableButton={false}
                        />
                    </Card>
                </MuiThemeProvider>
                </div>
                )
        });

And my return of render method looks like this

return connectDragSource (
            <div>
                <MuiThemeProvider>
                    <div className="mediaFilesComponent2">
                       {Populate}    
                    </div>
                </MuiThemeProvider>
            </div>
        )

Problem is when I try using drag, then the whole list of cards gets selected for drag. I want all the cards having individual drag functionality.

EdG
  • 2,243
  • 6
  • 48
  • 103

1 Answers1

0

If you want each card to have drag functionality than you'll have to wrap each card in a DragSource, and not the entire list. I would split out the Card into it's own component, wrapped in a DragSource, like this:

import React, { Component, PropTypes } from 'react';
import { ItemTypes } from './Constants';
import { DragSource } from 'react-dnd';


const CardSource = {
  beginDrag: function (props) {
    return {};
  }
};

function collect(connect, monitor) {
  return {
    connectDragSource: connect.dragSource(),
    isDragging: monitor.isDragging()
  }
}

class CardDragContainer extends React.Component {
  render() {
    return this.props.connectDragSource(
      <div>
        <Card style= {{marginBottom: 2, opacity: this.props.isDragging ? 0 : 1}}  id={value.id} key={value.id}
                          onMouseOver={this.props.onMouseOver}
                          onMouseOut={this.props.onMouseOut}
                          zDepth={this.props.shadow}>
            <CardHeader
                title={props.title}
                actAsExpander={false}
                showExpandableButton={false}
            />
          </Card>
      </div>
    )
  }
}

export default DragSource(ItemTypes.<Your Item Type>, CardSource, collect)(CardDragContainer);

Then you would use this DragContainer in render of the higher level component like this:

render() {
  var Populate = this.props.mediaFiles.map((value) => {
      return(
        <div>
          <MuiThemeProvider>
              <CardDragContainer
                value={value}
                onMouseOver={this.onMouseOver}
                onMouseOut={this.onMouseOut}
                shadow={this.state.shadow}
              />
          </MuiThemeProvider>
        </div>
      )
  });

  return (
    <div>
      <MuiThemeProvider>
        <div className="mediaFilesComponent2">
           {Populate}    
        </div>
      </MuiThemeProvider>
    </div>
  );
}

That should give you a list of Cards, each of which will be individually draggable.

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