拖拽排序

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 });

效果图如下:


2885354-f388433744f79bab.gif
1.gif

参照文章:http://www.cnblogs.com/jhonyoung/p/8954512.html
遗留问题:输入时左右选择会导致左右拖动。。(已解决,添加onPointerMove方法)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值