ListDrag.js
import React, { Component } from 'react';
import { Form, Input, Tag } from 'antd';
class ListDrag extends Component {
state = {
dataNew: [],
dataTemp: [],
pointerMove: false,
};
change = (dataNew, temp, callback) => {
const a = [];
temp.map(e => {
a.push(e);
return a;
});
dataNew.map(e => {
a.push(e);
return a;
});
callback(a);
};
deleteParamRule = (item, dataNew, temp) => {
const index = dataNew.indexOf(item);
if (index > -1) {
dataNew.splice(index, 1);
dataNew.map((e, i) => {
e.sort = i + 1;
return e;
});
temp.push(item);
temp.map(e => {
e.status = true;
return e;
});
}
this.setState({ dataNew });
};
handleMouseMove = e => {
const { pointerMove } = this.state;
if (e.target.classList[0] !== 'ant-tag') {
return;
}
if (pointerMove) {
e.target.draggable = 'true';
return;
}
if (
document.activeElement.id !== undefined &&
document.activeElement.id !== null &&
document.activeElement.id !== ''
) {
e.target.draggable = 'false';
} else {
e.target.draggable = 'true';
this.setState({ pointerMove: false });
}
console.log(pointerMove, 'pointerMove');
console.log(e.target.draggable, 'e.target.draggable move');
};
handlePointerMove = e => {
if (e.target.classList[0] === 'ant-input') {
this.setState({ pointerMove: true });
}
};
dragStart(e) {
this.dragged = e.currentTarget;
}
dragEnd(e) {
const { data, callback } = this.props;
const { dataNew } = this.state;
let { dataTemp } = this.state;
this.dragged.style.display = 'block';
if (this.over === undefined || this.over === null) {
return;
}
if (dataTemp.length === 0 && dataNew.length === 0) {
if (data.length !== 0) {
dataTemp = data;
}
} else {
dataTemp = dataNew;
}
const from = Number(this.dragged.id) - 1;
const to = Number(this.over.id);
console.log(from, 'from');
console.log(to, 'to');
console.log(this.over.classList, 'this.over.classList');
if (from === to) {
if (this.over.classList.contains('drag-up')) {
dataTemp.splice(to === 0 ? to : to - 1, 0, dataTemp.splice(from, 1)[0]);
} else if (this.over.classList.contains('drag-down')) {
dataTemp.splice(to === dataTemp.length ? to : to - 1, 0, dataTemp.splice(from + 1, 1)[0]);
}
} else if (from !== to) {
if (this.over.classList.contains('drag-down')) {
dataTemp.splice(to === dataTemp.length ? to : to - 1, 0, dataTemp.splice(from, 1)[0]);
} else {
dataTemp.splice(to, 0, dataTemp.splice(from, 1)[0]);
}
}
e.target.classList.remove('drag-up');
this.over.classList.remove('drag-up');
e.target.classList.remove('drag-down');
this.over.classList.remove('drag-down');
for (let i = 0; i < dataTemp.length; i += 1) {
dataTemp[i].sort = i + 1;
}
this.setState({ dataNew: dataTemp });
this.change(dataTemp, [], callback);
console.log(dataTemp, 'dateNew 1');
}
dragOver(e) {
this.dragged.style.display = 'none';
if (e.target.classList[0] !== 'ant-tag') {
return;
}
const dgIndex = JSON.parse(this.dragged.id);
const taIndex = JSON.parse(e.target.id);
const animateName = dgIndex > taIndex ? 'drag-up' : 'drag-down';
if (this.over && e.target.id !== this.over.id) {
this.over.classList.remove('drag-up', 'drag-down');
}
if (!e.target.classList.contains(animateName)) {
e.target.classList.add(animateName);
this.over = e.target;
}
}
render() {
const {
form: { getFieldDecorator },
data,
callback,
} = this.props;
let { dataNew } = this.state;
const temp = [];
if (data.length !== 0) {
if (dataNew.length === 0 || data.length !== dataNew.length) {
dataNew = [];
data.map(item => {
dataNew = dataNew.filter(e => e.id !== item.id);
dataNew.push(item);
return item;
});
dataNew = dataNew.filter(e => e.status !== true);
}
} else {
dataNew = [];
}
console.log(dataNew, 'dataNew');
const listItems = dataNew.map((item, index) => (
<Tag
id={index + 1}
key={item.id}
closable={false}
style={{
backgroundColor: '#e3e3e3',
height: 110,
width: '100%',
marginBottom: 10,
}}
draggable={e => (!e ? 'true' : e.target.draggable)}
onDragEnd={e => this.dragEnd(e)}
onDragStart={e => this.dragStart(e)}
onMouseMove={e => this.handleMouseMove(e)}
onPointerMove={e => this.handlePointerMove(e)}
>
<Form.Item
label="条件"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
style={{ marginBottom: 10 }}
>
{getFieldDecorator(`condition${item.id}`, {
initialValue: item.rule,
rules: [{ required: true, message: '请输入条件' }],
})(
<Input
allowClear
placeholder="请输入条件"
maxLength={300}
style={{ width: 500 }}
onChange={input => {
dataNew[index].rule = input.target.value;
}}
/>
)}
<span style={{ marginLeft: 10 }}>(请使用SPEL表达式)</span>
<span
style={{ marginLeft: 50 }}
onClick={() => {
this.deleteParamRule(item, dataNew, temp);
this.change(dataNew, temp, callback);
}}
>
X
</span>
</Form.Item>
<Form.Item
label="返回"
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
style={{ marginBottom: 10 }}
>
{getFieldDecorator(`content${item.id}`, {
initialValue: item.result,
rules: [{ required: true, message: '请输入返回内容' }],
})(
<Input.TextArea
allowClear
placeholder="请输入返回内容"
type="textarea"
autosize={{ minRows: 2, maxRows: 2 }}
maxLength={300}
style={{ width: 650 }}
onChange={input => {
dataNew[index].result = input.target.value;
}}
/>
)}
</Form.Item>
</Tag>
));
return (
<div
style={{ width: '100%' }}
onDragOver={e => this.dragOver(e)}
onChange={() => this.change(dataNew, temp, callback)}
>
{listItems}
</div>
);
}
}
export default Form.create()(ListDrag);
main.js
<Form layout="horizontal" hideRequiredMark={isEdit}>
<ListDragger
data={keys}
isEdit={isEdit}
callback={e => {
this.callback(e);
}}
/>
</Form>
keys数据格式:
keys.push({ id: (id += 1), sort: keys.length + 1, result: '', rule: '', status: false });
效果图如下:
参照文章:http://www.cnblogs.com/jhonyoung/p/8954512.html
遗留问题:输入时左右选择会导致左右拖动。。(已解决,添加onPointerMove方法)