问题
I need to render the content from this div:
<div class="col-sm-4">
<ul class="list-group">
<li class="list-group-item"><a href="#">File Reader</a></li>
<li class="list-group-item" ><a href="#">File Move</a></li>
<li class="list-group-item" ><a href="#">Data Base</a></li>
<li class="list-group-item"><a href="#">SAP R3</a></li>
<li class="list-group-item"><a href="#">FTP</a></li>
<li class="list-group-item"><a href="#">SOAP</a></li>
<li class="list-group-item"><a href="#">Rest</a></li>
<li class="list-group-item"><a href="#">Merge</a></li>
<li class="list-group-item"><a href="#">Filter</a></li>
<li class="list-group-item"><a href="#">Transform</a></li>
</ul>
</div>
Into a Drag and Drop, i tried a lot of examples but nothing seems to work.
Here is my code right now :
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { DragSource } from 'react-dnd';
import { ItemTypes } from './Constants';
import styles2 from './Styles.css'
import { render } from 'react-dom';
import {DragDropContext} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
const styles = {
fontFamily: 'sans-serif',
textAlign: 'center',
};
function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}
function _(id){
return document.getElementById(id);
}
var droppedIn = false;
function drag_start(event) {
_('app_status').innerHTML = "Dragging the "+event.target.getAttribute('id');
event.dataTransfer.dropEffect = "move";
event.dataTransfer.setData("text", event.target.getAttribute('id') );
}
function drag_enter(event) {
_('app_status').innerHTML = "You are dragging over the "+event.target.getAttribute('id');
}
function drag_leave(event) {
_('app_status').innerHTML = "You left the "+event.target.getAttribute('id');
}
function drag_drop(event) {
event.preventDefault(); /* Prevent undesirable default behavior while dropping */
var elem_id = event.dataTransfer.getData("text");
event.target.appendChild( _(elem_id) );
_('app_status').innerHTML = "Dropped "+elem_id+" into the "+event.target.getAttribute('id');
_(elem_id).removeAttribute("draggable");
_(elem_id).style.cursor = "default";
droppedIn = true;
}
function drag_end(event) {
if(droppedIn == false){
_('app_status').innerHTML = "You let the "+event.target.getAttribute('id')+" go.";
}
droppedIn = false;
}
function readDropZone(){
for(var i=0; i < _("drop_zone").children.length; i++){
alert(_("drop_zone").children[i].id+" is in the drop zone");
}
/* Run Ajax request to pass any data to your server */
}
const propTypes = {
text: PropTypes.string.isRequired,
// Injected by React DnD:
isDragging: PropTypes.bool.isRequired,
connectDragSource: PropTypes.func.isRequired
};
class BasicForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<div style={styles}>
<form onSubmit={this.handleSubmit}>
<div class="container">
<div class="row">
<div class="col-sm-4">
<ul class="list-group">
<li class="list-group-item"><a href="#">File Reader</a></li>
<li class="list-group-item" ><a href="#">File Move</a></li>
<li class="list-group-item" ><a href="#">Data Base</a></li>
<li class="list-group-item"><a href="#">SAP R3</a></li>
<li class="list-group-item"><a href="#">FTP</a></li>
<li class="list-group-item"><a href="#">SOAP</a></li>
<li class="list-group-item"><a href="#">Rest</a></li>
<li class="list-group-item"><a href="#">Merge</a></li>
<li class="list-group-item"><a href="#">Filter</a></li>
<li class="list-group-item"><a href="#">Transform</a></li>
</ul>
</div>
<h2 id="app_status">App status...</h2>
<h1>Drop Zone</h1>
<div id="drop_zone" onDragEnter="drag_enter(event)" onDrop="drag_drop(event)" onDragOver="return false" onDragLeave="drag_leave(event)" className={styles2.drop_zone} ></div>
</div>
</div>
<input type="submit" value="Submit" />
</form>
</div>
);
}
}export default DragDropContext(HTML5Backend)(BasicForm);
On my console i get this error : Expected onDragEnter listener to be a function, instead got a value of string type.
What i'm doing wrong?
PS: I'm new with React, i tried so many examples, so the code is a little bit big.
回答1:
This is a basic drag and drop example for list in react. Does not handle the dropping yet, only the dragging and the scroll.
const getWindowScroll = () => {
const doc = document.documentElement;
return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
}
class App extends React.Component {
setElemRef = ref => {
this.elemRef = ref;
}
initialiseDrag = event => {
const {target, clientY} = event;
const { offsetTop } = target;
const { top } = this.elemRef.getBoundingClientRect();
this.dragStartTop = top - offsetTop;
this.dragStartY = clientY;
window.addEventListener('mousemove', this.startDragging, false);
window.addEventListener('mouseup', this.stopDragging, false);
}
startDragging = ({ clientY }) => {
let newTop = this.dragStartTop + clientY - this.dragStartY + getWindowScroll();
if (newTop < 0) newTop = 0;
this.elemRef.style.transform = `translateY(${newTop}px)`;
this.scrollIfElementBottom(newTop);
}
stopDragging = () => {
window.removeEventListener('mousemove', this.startDragging, false);
window.removeEventListener('mouseup', this.stopDragging, false);
}
scrollIfElementBottom = newTop => {
if (newTop > 30) {
window.scroll({
top: newTop,
behavior: 'smooth'
});
}
if (newTop < 30) {
window.scroll({
top: 0,
behavior: 'smooth'
});
}
};
render(){
return (
<React.Fragment>
<div onMouseDown={this.initialiseDrag} ref={this.setElemRef}>DragMe</div>
<div>List elem</div>
<div>List elem</div>
<div>List elem</div>
<div>List elem</div>
<div>List elem</div>
<div>List elem</div>
<div>List elem</div>
<div>List elem</div>
</React.Fragment>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
#root div {
background: gray;
padding: 20px;
margin: 10px;
user-select: none;
cursor: pointer;
border: 1px solid lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
回答2:
https://github.com/peterh32/react-drag-drop-container is a pretty simple library. If I understand what you are trying to do (drag LIs into the "Drop Zone"), you'd do something like this for each LI:
<DragDropContainer onDrop={...} onDragStart={...} ...etc. >
<li class="list-group-item"><a href="#">File Reader</a></li>
</DragDropContainer>
...and then for your drop zone:
<DropTarget onHit={...} onDragEnter={...} ...etc.>
<div id="drop-target">...</div>
</DropTarget>
The events go right into the containers as you can see. It handles mouse and touch interfaces and also does stuff like scrolling when you get to the edge of the screen (so you can drag to destinations that are initially offscreen).
来源:https://stackoverflow.com/questions/48402808/how-to-drag-and-drop-content-with-react