增加行拖拽交换顺序,表头拖拽事件多次绑定优化 等问题

This commit is contained in:
jonyshi 2019-04-25 13:53:39 +08:00
parent 7c5c52b985
commit 0eaee06a5d
5 changed files with 273 additions and 15 deletions

68
demo/demolist/Demo1201.js Normal file
View File

@ -0,0 +1,68 @@
/**
*
* @title 拖拽改变行顺序
* @parent 拖拽改变行顺序
* @description 拖拽改变行顺序
* Demo1201
*/
import React, { Component } from "react";
import {Button,Tooltip} from "tinper-bee";
import Table from "../../src";
const columns = [
{
title: "员工编号", dataIndex: "a", key: "a", width: 120, className: "rowClassName",
fixed:'left',
render: (text, record, index) => {
return (
<Tooltip inverse overlay={text}>
<span tootip={text} style={{
display: "inline-block",
width: "80px",
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
verticalAlign: "middle",
}}>{text}</span>
</Tooltip>
);
}
},
{ title: "员工姓名", dataIndex: "b", key: "b", width:200 },
{ title: "性别", dataIndex: "c", key: "c", width: 500 },
{ title: "部门", dataIndex: "d", key: "d", width: 100 },
{ title: "职级", dataIndex: "e", key: "e", width: 100,fixed:'right'}
];
const data = [
{ a: "ASVAL_201903280005", b: "小张", c: "男", d: "财务二科", e: "M1", key: "1001" },
{ a: "ASVAL_201903200004", b: "小明", c: "男", d: "财务一科", e: "T1", key: "1002" },
{ a: "ASVAL_201903120002", b: "小红", c: "女", d: "财务一科", e: "T2", key: "1003" }
];
class Demo1201 extends Component {
constructor(props) {
super(props);
this.state = {
data: data
}
}
handleClick = () => {
console.log('这是第' , this.currentIndex , '行');
console.log('内容:' , this.currentRecord);
}
render() {
return (
<Table
columns={columns}
data={data}
rowDraggAble={true}
/>
);
}
}
export default Demo1201;

View File

@ -70,6 +70,8 @@ import 'bee-table/build/Table.css';
| height | 自定义表格行高 | number | - | | height | 自定义表格行高 | number | - |
| headerHeight | 自定义表头行高 | number | - | | headerHeight | 自定义表头行高 | number | - |
| size | 表格大小 | `sm | md | lg` | 'md' | | size | 表格大小 | `sm | md | lg` | 'md' |
| rowDraggAble | 是否增加行交换顺序功能 | boolean| false
> 快捷键部分参考示例 (快捷键在table中的简单使用应用) > 快捷键部分参考示例 (快捷键在table中的简单使用应用)

View File

@ -54,6 +54,7 @@ const propTypes = {
tabIndex:PropTypes.string, tabIndex:PropTypes.string,
hoverContent:PropTypes.func, hoverContent:PropTypes.func,
size: PropTypes.oneOf(['sm', 'md', 'lg']), size: PropTypes.oneOf(['sm', 'md', 'lg']),
rowDraggAble: PropTypes.bool,
}; };
const defaultProps = { const defaultProps = {
@ -88,7 +89,8 @@ const defaultProps = {
setRowParentIndex:()=>{}, setRowParentIndex:()=>{},
tabIndex:'0', tabIndex:'0',
heightConsistent:false, heightConsistent:false,
size: 'md' size: 'md',
rowDraggAble:false
}; };
class Table extends Component { class Table extends Component {
@ -523,9 +525,24 @@ class Table extends Component {
expandable={false} expandable={false}
store={this.store} store={this.store}
dragborderKey={this.props.dragborderKey} dragborderKey={this.props.dragborderKey}
rowDraggAble={props.rowDraggAble}
onDragRow={this.onDragRow}
/> />
); );
} }
onDragRow = (currentIndex,targetIndex)=>{
let {data} = this.state,
currentObj = data[currentIndex],
targetObj = data[targetIndex];
console.log(currentIndex+" ----------onRowDragEnd-------- "+targetIndex);
data.splice(targetIndex, 0, data.splice(currentIndex, 1).shift());
console.log(" _data---- ",data);
this.setState({
data: data,
});
}
/** /**
* *
* *
@ -660,6 +677,9 @@ class Table extends Component {
rootIndex = {rootIndex} rootIndex = {rootIndex}
syncHover = {props.syncHover} syncHover = {props.syncHover}
bodyDisplayInRow = {props.bodyDisplayInRow} bodyDisplayInRow = {props.bodyDisplayInRow}
rowDraggAble={props.rowDraggAble}
onDragRow={this.onDragRow}
contentTable={this.contentTable}
/> />
); );
this.treeRowIndex++; this.treeRowIndex++;

View File

@ -30,6 +30,7 @@ class TableHeader extends Component {
this.minWidth = 80;//确定最小宽度就是80 this.minWidth = 80;//确定最小宽度就是80
this.table = null; this.table = null;
this._thead = null;//当前对象 this._thead = null;//当前对象
this.event = false;//避免多次绑定问题
} }
static defaultProps = { static defaultProps = {
@ -103,13 +104,21 @@ class TableHeader extends Component {
* 事件初始化 * 事件初始化
*/ */
initEvent(){ initEvent(){
let {dragborder,draggable} = this.props;
if(!this.event){ //避免多次绑定问题。
this.event = true;
if(dragborder){
this.dragBorderEventInit();//列宽 this.dragBorderEventInit();//列宽
}
if(dragborder){
this.dragAbleEventInit();//交换列 this.dragAbleEventInit();//交换列
}
if(this.table && this.table.tr){ if(this.table && this.table.tr){
this.eventListen([{key:'mousedown',fun:this.onTrMouseDown}],'',this.table.tr[0]);//body mouseup this.eventListen([{key:'mousedown',fun:this.onTrMouseDown}],'',this.table.tr[0]);//body mouseup
} }
this.eventListen([{key:'mouseup',fun:this.bodyonLineMouseUp}],'',document.body);//body mouseup this.eventListen([{key:'mouseup',fun:this.bodyonLineMouseUp}],'',document.body);//body mouseup
} }
}
/** /**
* 拖拽列宽事件的监听 * 拖拽列宽事件的监听
@ -398,6 +407,7 @@ class TableHeader extends Component {
}; };
onDragOver = (e) => { onDragOver = (e) => {
let event = Event.getEvent(e);
event.preventDefault(); event.preventDefault();
}; };

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Event,EventUtil} from "./utils";
import TableCell from './TableCell'; import TableCell from './TableCell';
import ExpandIcon from './ExpandIcon'; import ExpandIcon from './ExpandIcon';
@ -29,6 +30,8 @@ const propTypes = {
expandIconAsCell: PropTypes.bool, expandIconAsCell: PropTypes.bool,
expandRowByClick: PropTypes.bool, expandRowByClick: PropTypes.bool,
store: PropTypes.object.isRequired, store: PropTypes.object.isRequired,
rowDraggAble: PropTypes.bool,
onDragRow: PropTypes.func,
}; };
const defaultProps = { const defaultProps = {
@ -39,7 +42,9 @@ const defaultProps = {
expandRowByClick: false, expandRowByClick: false,
onHover() {}, onHover() {},
className:'', className:'',
setRowParentIndex:()=>{} setRowParentIndex:()=>{},
rowDraggAble:false,
// onDragRow:()=>{}
}; };
class TableRow extends Component{ class TableRow extends Component{
@ -54,11 +59,12 @@ class TableRow extends Component{
this.onMouseEnter = this.onMouseEnter.bind(this); this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this); this.onMouseLeave = this.onMouseLeave.bind(this);
this.expandHeight = 0; this.expandHeight = 0;
this.event = false;
} }
componentDidMount() { componentDidMount() {
const { store, hoverKey,treeType } = this.props; const { store, hoverKey,treeType,rowDraggAble } = this.props;
this.unsubscribe = store.subscribe(() => { this.unsubscribe = store.subscribe(() => {
if (store.getState().currentHoverKey === hoverKey) { if (store.getState().currentHoverKey === hoverKey) {
this.setState({ hovered: true }); this.setState({ hovered: true });
@ -71,23 +77,174 @@ class TableRow extends Component{
if(treeType){ if(treeType){
this.setRowParentIndex(); this.setRowParentIndex();
} }
}
/**
* 事件初始化
*/
initEvent=()=>{
let events = [
{key:'dragstart',fun:this.onDragStart},//用户开始拖动元素时触发
{key:'dragover', fun:this.onDragOver},//当某被拖动的对象在另一对象容器范围内拖动时触发此事件
{key:'drop', fun:this.onDrop}, //在一个拖动过程中,释放鼠标键时触发此事件
{key:'dragenter', fun:this.onDragEnter},
{key:'dragleave', fun:this.onDragLeave},
];
this.eventListen(events,'',this.element);
}
/**
* 事件移除提供性能以及内存泄漏等问题
*/
removeDragAbleEvent=()=>{
let events = [
{key:'dragstart',fun:this.onDragStart},
{key:'dragover', fun:this.onDragOver},
{key:'drop', fun:this.onDrop},
{key:'dragenter', fun:this.onDragEnter},
{key:'dragleave', fun:this.onDragLeave},
];
this.eventListen(events,'remove',this.element);
} }
/**
* 事件绑定和移除函数
*/
eventListen(events,type,eventSource){
for (let i = 0; i < events.length; i++) {
const _event = events[i];
if(type === "remove"){
EventUtil.removeHandler(eventSource,_event.key,_event.fun);
}else{
EventUtil.addHandler(eventSource,_event.key,_event.fun);
}
}
}
/**
* 开始调整交换列的事件
*/
onDragStart = (e) => {
if (!this.props.rowDraggAble) return;
let event = Event.getEvent(e) ,
target = Event.getTarget(event);
this.currentIndex = target.getAttribute("data-row-key");
this._dragCurrent = target;
event.dataTransfer.effectAllowed = "move";
event.dataTransfer.setData("Text", this.currentIndex);
}
onDragOver = (e) => {
let event = Event.getEvent(e);
event.preventDefault();
};
/**
* 在一个拖动过程中释放鼠标键时触发此事件目标事件
* @memberof TableHeader
*/
onDrop = (e) => {
let {rowDraggAble,onDragRow} = this.props;
let event = Event.getEvent(e) ,
_target = Event.getTarget(event),target = _target.parentNode;
let currentIndex = target.getAttribute("data-row-key");
if(!currentIndex || currentIndex === this.currentIndex)return;
if(target.nodeName.toUpperCase() === "TR"){
this.synchronizeTableTr(this.currentIndex,null);
// target.setAttribute("style","");
// this.synchronizeTrStyle(this.currentIndex,false);
}
let _currentIndex = event.dataTransfer.getData("text");
onDragRow && onDragRow(parseInt(this.currentIndex--),parseInt(currentIndex--));
};
/**
* 同步自己,也需要同步当前行的行显示
*/
synchronizeTableTr = (currentIndex,type)=>{
let {contentTable} = this.props;
let _table_trs = contentTable.querySelector('.u-table-scroll table tbody'),
_table_fixed_left_trs = contentTable.querySelector('.u-table-fixed-left table tbody'),
_table_fixed_right_trs = contentTable.querySelector('.u-table-fixed-right table tbody');
this.synchronizeTrStyle(_table_trs,currentIndex,type);
if(_table_fixed_left_trs){
this.synchronizeTrStyle(_table_fixed_left_trs,currentIndex,type);
}
if(_table_fixed_right_trs){
this.synchronizeTrStyle(_table_fixed_right_trs,currentIndex,type);
}
}
/**
* 设置同步的style
*/
synchronizeTrStyle = (_elementBody,id,type)=>{
let {contentTable} = this.props,
trs = _elementBody.getElementsByTagName("tr"),
currentObj;
for (let index = 0; index < trs.length; index++) {
const element = trs[index];
if(element.getAttribute("data-row-key") == id){
currentObj = element;
}
}
if(type){
currentObj && currentObj.setAttribute("style","border-bottom:2px dashed rgba(5,0,0,0.25)");
}else{
currentObj && currentObj.setAttribute("style","");
}
}
onDragEnter = (e) => {
let event = Event.getEvent(e) ,
_target = Event.getTarget(event),target = _target.parentNode;
let currentIndex = target.getAttribute("data-row-key");
if(!currentIndex || currentIndex === this.currentIndex)return;
if(target.nodeName.toUpperCase() === "TR"){
this.synchronizeTableTr(currentIndex,true);
// target.setAttribute("style","border-bottom:2px dashed rgba(5,0,0,0.25)");
// // target.style.backgroundColor = 'rgb(235, 236, 240)';
}
}
onDragLeave = (e) => {
let event = Event.getEvent(e) ,
_target = Event.getTarget(event),target = _target.parentNode;
let currentIndex = target.getAttribute("data-row-key");
if(!currentIndex || currentIndex === this.currentIndex)return;
if(target.nodeName.toUpperCase() === "TR"){
this.synchronizeTableTr(currentIndex,null);
}
}
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
const { rowDraggAble } = this.props;
if(!this.event){
this.event = true;
if(rowDraggAble){
this.initEvent();
}
}
if(this.props.treeType){ if(this.props.treeType){
this.setRowParentIndex(); this.setRowParentIndex();
} }
this.setRowHeight() this.setRowHeight()
} }
componentWillUnmount() { componentWillUnmount() {
const { record, onDestroy, index } = this.props; const { record, onDestroy, index,rowDraggAble } = this.props;
onDestroy(record, index); onDestroy(record, index);
if (this.unsubscribe) { if (this.unsubscribe) {
this.unsubscribe(); this.unsubscribe();
} }
if(rowDraggAble){
this.removeDragAbleEvent();
}
} }
@ -98,7 +255,6 @@ class TableRow extends Component{
} }
setRowParentIndex(){ setRowParentIndex(){
const {index,setRowParentIndex,fixedIndex,rootIndex} = this.props; const {index,setRowParentIndex,fixedIndex,rootIndex} = this.props;
// console.log('rootIndex',rootIndex<0?index:rootIndex,'index',fixedIndex);
setRowParentIndex(rootIndex<0?index:rootIndex,fixedIndex); setRowParentIndex(rootIndex<0?index:rootIndex,fixedIndex);
} }
@ -163,7 +319,7 @@ class TableRow extends Component{
render() { render() {
const { const {
clsPrefix, columns, record, height, visible, index, clsPrefix, columns, record, height, visible, index,
expandIconColumnIndex, expandIconAsCell, expanded, expandRowByClick, expandIconColumnIndex, expandIconAsCell, expanded, expandRowByClick,rowDraggAble,
expandable, onExpand, needIndentSpaced, indent, indentSize,isHiddenExpandIcon,fixed,bodyDisplayInRow expandable, onExpand, needIndentSpaced, indent, indentSize,isHiddenExpandIcon,fixed,bodyDisplayInRow
} = this.props; } = this.props;
let showSum = false; let showSum = false;
@ -171,7 +327,6 @@ class TableRow extends Component{
if (this.state.hovered) { if (this.state.hovered) {
className += ` ${clsPrefix}-hover`; className += ` ${clsPrefix}-hover`;
} }
// console.log('className--'+className,index);
//判断是否为合计行 //判断是否为合计行
if(className.indexOf('sumrow')>-1){ if(className.indexOf('sumrow')>-1){
showSum = true; showSum = true;
@ -223,14 +378,17 @@ class TableRow extends Component{
if (!visible) { if (!visible) {
style.display = 'none'; style.display = 'none';
} }
return ( return (
<tr <tr
draggable={rowDraggAble}
onClick={this.onRowClick} onClick={this.onRowClick}
onDoubleClick={this.onRowDoubleClick} onDoubleClick={this.onRowDoubleClick}
onMouseEnter={this.onMouseEnter} onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave} onMouseLeave={this.onMouseLeave}
className={`${clsPrefix} ${className} ${clsPrefix}-level-${indent}`} className={`${clsPrefix} ${className} ${clsPrefix}-level-${indent}`}
style={style} style={style}
data-row-key={record.key}
// key={hoverKey} // key={hoverKey}
ref={this.bindElement} ref={this.bindElement}
> >