拖拽宽度功能上线

This commit is contained in:
jonyshi 2018-05-13 16:37:41 +08:00
commit 2f68f8c246
12 changed files with 54 additions and 526 deletions

View File

@ -163,12 +163,12 @@ import multiSelect from "bee-table/build/lib/multiSelect.js"
### filterColumn ### filterColumn
过滤表头列 过滤表头列[示例](https://github.com/tinper-bee/bee-table/tree/master/demo/demolist/Demo21.js)
### dragColumn ### dragColumn
拖拽表头交换顺序 拖拽表头交换顺序[示例](https://github.com/tinper-bee/bee-table/tree/master/demo/demolist/Demo22.js)
#### dragColumn新增参数 #### dragColumn新增参数
@ -179,7 +179,7 @@ import multiSelect from "bee-table/build/lib/multiSelect.js"
### 拖拽变更宽度 ### 拖拽变更宽度
建设中... 目前支持此功能只支持普通表格【注不支持tree结构的表头、不支持和表头拖拽交互列一起使用】[示例](https://github.com/tinper-bee/bee-table/tree/master/demo/demolist/Demo23.js)
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| ------ | ---------- | -------- | ---- | | ------ | ---------- | -------- | ---- |
@ -187,6 +187,7 @@ import multiSelect from "bee-table/build/lib/multiSelect.js"
## rendertype ## rendertype
在表格中提供了多种rendertype可以供选择比如下拉框输入框日期等 在表格中提供了多种rendertype可以供选择比如下拉框输入框日期等

View File

@ -1,7 +1,7 @@
/** /**
* *
* @title 动态调整列的宽度 * @title 拖拽调整列的宽度
* @description 点击列的表头进行左右拖拽 * @description 目前支持此功能只支持普通表格不支持tree结构的表头不支持和表头拖拽交互列一起使用
*/ */
import React, { Component } from 'react'; import React, { Component } from 'react';
import Table from '../../src'; import Table from '../../src';

File diff suppressed because one or more lines are too long

50
dist/demo.js vendored

File diff suppressed because one or more lines are too long

2
dist/demo.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -1,70 +0,0 @@
import React, { Component } from "react";
import Icon from "bee-icon";
import Checkbox from "bee-checkbox";
import ReactDOM from 'react-dom';
import Popover from 'bee-popover';
import {sortBy} from './util';
class ResizableTh extends Component {
constructor(props) {
super(props);
this.state = {
width:0
}
}
componentWillReceiveProps(nextProps){
if(nextProps.columns != this.props.columns){
}
}
onMouseDown=(event,data)=>{
this.mouse = true;
this.dragBorderObj.startScreenX = event.screenX;
}
onMouseMove=(event,data)=>{
if(!this.mouse)return;
let endx = (event.screenX-this.dragBorderObj.startScreenX);
let {columns:_columns} = this.state;
let columns = [];
Object.assign(columns,_columns);
// let currentIndex = columns.findIndex((_da,i)=>_da.key == data.key);
// currentIndex = currentIndex==0?currentIndex:(currentIndex-1);
let currObj = columns.find((_da,i)=>_da.key == data.key);
if(!currObj)return;
currObj.width = currObj.width?(currObj.width+endx):endx;
this.setState({
columns
});
}
getTarget=(evt)=>{
return evt.target || evt.srcElement;
}
onMouseUp=(event,data)=>{
let endx = (event.screenX-this.dragBorderObj.startScreenX);
this.mouse = false;
}
render() {
const {className} = this.props;
return (<th {...this.props} className={`${className} u-table-drag-border`}
// onDragStart={this.onDragStart} onDragOver={this.onDragOver} onDrop={this.onDrop}
// onDragEnter={this.onDragEnter}
// draggable={draggable}
onMouseDown={this.onMouseDown}
onMouseMove={this.onMouseMove}
onMouseUp={this.onMouseUp}
/>)
}
}

View File

@ -221,7 +221,7 @@ class Table extends Component{
getHeader(columns, fixed) { getHeader(columns, fixed) {
const { showHeader, expandIconAsCell, clsPrefix ,onDragStart,onDragEnter,onDragOver,onDrop,draggable, const { showHeader, expandIconAsCell, clsPrefix ,onDragStart,onDragEnter,onDragOver,onDrop,draggable,
onMouseDown,onMouseMove,onMouseUp,dragborder,onThMouseMove} = this.props; onMouseDown,onMouseMove,onMouseUp,dragborder,onThMouseMove,dragborderKey} = this.props;
const rows = this.getHeaderRows(columns); const rows = this.getHeaderRows(columns);
if (expandIconAsCell && fixed !== 'right') { if (expandIconAsCell && fixed !== 'right') {
rows[0].unshift({ rows[0].unshift({
@ -234,7 +234,8 @@ class Table extends Component{
const trStyle = fixed ? this.getHeaderRowStyle(columns, rows) : null; const trStyle = fixed ? this.getHeaderRowStyle(columns, rows) : null;
let drop = draggable?{onDragStart,onDragOver,onDrop,onDragEnter,draggable}:{}; let drop = draggable?{onDragStart,onDragOver,onDrop,onDragEnter,draggable}:{};
let dragBorder = dragborder?{onMouseDown,onMouseMove,onMouseUp,dragborder,onThMouseMove}:{}; let dragBorder = dragborder?{onMouseDown,onMouseMove,onMouseUp,dragborder,onThMouseMove,dragborderKey}:{};
return showHeader ? ( return showHeader ? (
<TableHeader <TableHeader
{...drop} {...drop}
@ -328,6 +329,7 @@ class Table extends Component{
indent={1} indent={1}
expandable={false} expandable={false}
store={this.store} store={this.store}
dragborderKey={this.props.dragborderKey}
/> />
); );
} }
@ -460,9 +462,10 @@ class Table extends Component{
} }
renderDragHideTable=()=>{ renderDragHideTable=()=>{
const {columns,} = this.props; const {columns,dragborder,dragborderKey} = this.props;
if(!dragborder)return null;
let sum = 0; let sum = 0;
return(<div id="u-table-drag-hide-table" className={`${this.props.clsPrefix}-hiden-drag`} > return(<div id={`u-table-drag-hide-table-${dragborderKey}`} className={`${this.props.clsPrefix}-hiden-drag`} >
{ {
columns.map((da,i)=>{ columns.map((da,i)=>{
sum += da.width?da.width:0; sum += da.width?da.width:0;
@ -537,9 +540,7 @@ class Table extends Component{
) : null; ) : null;
return ( return (
<table className={` ${tableClassName} table table-bordered `} style={tableStyle}> <table className={` ${tableClassName} table table-bordered `} style={tableStyle}>
{/* { {this.props.dragborder?null:this.getColGroup(columns, fixed)}
this.props.dragborder?"":this.getColGroup(columns, fixed)
} */}
{hasHead ? this.getHeader(columns, fixed) : null} {hasHead ? this.getHeader(columns, fixed) : null}
{tableBody} {tableBody}
</table> </table>
@ -562,7 +563,6 @@ class Table extends Component{
</div> </div>
); );
} }
let BodyTable = ( let BodyTable = (
<div <div
className={`${clsPrefix}-body`} className={`${clsPrefix}-body`}

View File

@ -17,10 +17,10 @@ class TableHeader extends Component{
this.state = { this.state = {
border:false border:false
} }
//拖拽宽度处理 //拖拽宽度处理
if(!props.dragborder)return; if(!props.dragborder)return;
this.border = false; this.border = false;
this.theadKey = new Date().getTime();
this.drag = { this.drag = {
initPageLeftX:0, initPageLeftX:0,
initLeft:0, initLeft:0,
@ -91,14 +91,17 @@ class TableHeader extends Component{
onThMouseMove=(event,data)=>{ onThMouseMove=(event,data)=>{
if(!this.border)return; if(!this.border)return;
const {dragborderKey} = this.props;
console.log(data);
let x = (event.pageX - this.drag.initPageLeftX) + this.drag.initLeft-0; let x = (event.pageX - this.drag.initPageLeftX) + this.drag.initLeft-0;
//设置hiden的left //设置hiden的left
let currentHideDom = document.getElementById("u-table-drag-hide-table").getElementsByTagName("div")[this.drag.currIndex]; //"u-table-drag-hide-table"
let currentHideDom = document.getElementById("u-table-drag-hide-table-"+dragborderKey).getElementsByTagName("div")[this.drag.currIndex];
currentHideDom.style.left = (this.drag.initPageLeftX+x-16)+"px"; currentHideDom.style.left = (this.drag.initPageLeftX+x-16)+"px";
//设置当前的宽度 //设置当前的宽度
let currentData = this.drag.data[this.drag.currIndex]; let currentData = this.drag.data[this.drag.currIndex];
currentData.width = this.drag.width + x; currentData.width = this.drag.width + x;
let currentDom = document.getElementById("u-table-drag-thead").getElementsByTagName("th")[this.drag.currIndex]; let currentDom = document.getElementById("u-table-drag-thead-"+this.theadKey).getElementsByTagName("th")[this.drag.currIndex];
currentDom.style.width = (currentData.width)+"px"; currentDom.style.width = (currentData.width)+"px";
this.drag.x = x; this.drag.x = x;
} }
@ -108,7 +111,7 @@ class TableHeader extends Component{
onMouseDown,onMouseMove,onMouseUp,dragborder,onMouseOut onMouseDown,onMouseMove,onMouseUp,dragborder,onMouseOut
} = this.props; } = this.props;
return ( return (
<thead className={`${clsPrefix}-thead`} id="u-table-drag-thead"> <thead className={`${clsPrefix}-thead`} id={`u-table-drag-thead-${this.theadKey}`}>
{ {
rows.map((row, index) => ( rows.map((row, index) => (
<tr key={index} style={rowStyle}> <tr key={index} style={rowStyle}>

View File

@ -1,144 +0,0 @@
import React, { Component } from "react";
import Icon from "bee-icon";
import Checkbox from "bee-checkbox";
import ReactDOM from 'react-dom';
import Popover from 'bee-popover';
import {sortBy} from './util';
import createColResizable from '../resiztable'
// import Table from './Table';
/**
* 参数: 列拖拽
* @param {*} Table
*/
export default function dragColumn(Table) {
return class dragColumn extends Component {
constructor(props) {
super(props);
const {columns} = props;
this.dragBorderObj = {startScreenX:0,endScreenX:0};
this.mouse = false;
this.setColumOrderByIndex(columns);
}
componentWillReceiveProps(nextProps){
if(nextProps.columns != this.props.columns){
this.setColumOrderByIndex();
}
}
componentDidMount() {
const domElemTableList = document.querySelectorAll('table');
createColResizable(domElemTableList[0], {
liveDrag: true
});
createColResizable(domElemTableList[1], {
liveDrag: false,
headerOnly: false
});
}
setColumOrderByIndex = (columns)=>{
let _column = [];
Object.assign(_column,columns);
_column.forEach((da,i) => {
da.dragIndex = i;
da.drgHover = false;
});
this.state = {
columns:_column
};
}
onDragStart=(event,data)=>{
}
onDragOver=(event,data)=>{
}
onDragEnter=(event,data)=>{
const {columns:_columns} = this.state;
let columns = [];
Object.assign(columns,_columns);
columns.forEach((da)=>da.drgHover = false)
let current = columns.find((da)=>da.key == data.key);
current.drgHover = true;
this.setState({
columns
})
}
onDrop=(event,data)=>{
let {columns} = this.state;
const id = event.dataTransfer.getData("Text");
let objIndex = columns.findIndex((_da,i)=>_da.key == id);
let targetIndex = columns.findIndex((_da,i)=>_da.key == data.key);
columns.forEach((da,i)=>{
da.drgHover = false;
if(da.key == id){//obj
da.dragIndex = targetIndex
}
if(da.key == data.key){//targetObj
da.dragIndex = objIndex;
}
});
let _columns = sortBy(columns,(da)=>da.dragIndex);
this.setState({
columns:_columns,
});
}
onMouseDown=(event,data)=>{
this.mouse = true;
this.dragBorderObj.startScreenX = event.screenX;
}
onMouseMove=(event,data)=>{
if(!this.mouse)return;
let endx = (event.screenX-this.dragBorderObj.startScreenX);
let {columns:_columns} = this.state;
let columns = [];
Object.assign(columns,_columns);
// let currentIndex = columns.findIndex((_da,i)=>_da.key == data.key);
// currentIndex = currentIndex==0?currentIndex:(currentIndex-1);
let currObj = columns.find((_da,i)=>_da.key == data.key);
if(!currObj)return;
currObj.width = currObj.width?(currObj.width+endx):endx;
this.setState({
columns
});
}
getTarget=(evt)=>{
return evt.target || evt.srcElement;
}
onMouseUp=(event,data)=>{
let endx = (event.screenX-this.dragBorderObj.startScreenX);
this.mouse = false;
}
render() {
const {data,dragborder,draggable,className} = this.props;
const {columns} = this.state;
return (<Table {...this.props} columns={columns} data={data} className={`${className} u-table-drag-border`}
onDragStart={this.onDragStart} onDragOver={this.onDragOver} onDrop={this.onDrop}
onDragEnter={this.onDragEnter}
draggable={draggable}
dragborder={true}
onMouseDown={this.onMouseDown}
onMouseMove={this.onMouseMove}
onMouseUp={this.onMouseUp}
/>)
}
};
}

View File

@ -1,8 +1,6 @@
import React, { Component } from "react"; import React, { Component } from "react";
import Icon from "bee-icon"; import Icon from "bee-icon";
import Checkbox from "bee-checkbox";
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import Popover from 'bee-popover';
import {sortBy} from './util'; import {sortBy} from './util';
/** /**
* 参数: 列拖拽 * 参数: 列拖拽
@ -84,13 +82,15 @@ export default function dragColumn(Table) {
render() { render() {
const {data,dragborder,draggable,className} = this.props; const {data,dragborder,draggable,className} = this.props;
let key = new Date().getTime();
const {columns} = this.state; const {columns} = this.state;
return (<Table {...this.props} columns={columns} data={data} className={`${className} u-table-drag-border`} return (<Table {...this.props} columns={columns} data={data} className={`${className} u-table-drag-border`}
onDragStart={this.onDragStart} onDragOver={this.onDragOver} onDrop={this.onDrop} onDragStart={this.onDragStart} onDragOver={this.onDragOver} onDrop={this.onDrop}
onDragEnter={this.onDragEnter} onDragEnter={this.onDragEnter}
draggable={draggable} draggable={draggable}
dragborder={true} dragborder={true}
dragborderKey={key}
/>) />)
} }
}; };

View File

@ -1,254 +0,0 @@
import isFunction from 'lodash/isFunction';
import isArray from 'lodash/isArray';
import {
tryParseInt,
removeClass,
addClass
} from '../utils';
export default class ColResizable {
static defaults = {
liveDrag: true,
defaultMinWidth: 30,
headerOnly: true,
disabledColumns: [],
onResizing: null,
onResized: null
};
constructor(domElmTable, options = {}) {
this.options = { ...ColResizable.defaults, ...options };
this.domElmTable = domElmTable;
this.onGripMouseDown = this.onGripMouseDown.bind(this);
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
this.init();
}
init() {
addClass(this.domElmTable, 'table-col-resizer');
this.domElmHandleList = [];
this.domElmTableTheadThList = [];
this.tableWidth = `${this.domElmTable.offsetWidth}px`;
this.cellSpacing = tryParseInt(getComputedStyle(this.domElmTable).getPropertyValue('border-spacing'));
this.borderLeftWidth = tryParseInt(getComputedStyle(this.domElmTable).getPropertyValue('border-left-width'));
this.createGrips();
}
createGrips() {
const thList = this.domElmTable.querySelectorAll('thead th');
const domElmThList = [];
this.domElmHandleContainer = this.domElmTable.previousSibling;
const hasHandleContainer = this.domElmHandleContainer && this.domElmHandleContainer.className === 'col-resize-container';
if (!hasHandleContainer) {
this.domElmTable.insertAdjacentHTML('beforebegin', '<div class="col-resize-container"/>');
this.domElmHandleContainer = this.domElmTable.previousSibling;
} else {
Array.prototype.push.apply(this.domElmHandleList, this.domElmHandleContainer.childNodes);
}
Array.prototype.push.apply(domElmThList, thList);
this.thLength = domElmThList.length;
this.lastThIndex = this.thLength - 1;
let { disabledColumns } = this.options;
if (!isArray(disabledColumns)) {
disabledColumns = [];
}
domElmThList.forEach((domElmTh, index) => {
const disabledColumn = disabledColumns.indexOf(index) !== -1;
let domElmHandle;
if (!hasHandleContainer) {
this.domElmHandleContainer.insertAdjacentHTML('beforeend',
`<div class="drag-handle">
<i class="icon icon-caret-right"></i>
<div class="col-resizer"></div>
<i class="icon icon-caret-left"></i>
</div>`
);
domElmHandle = this.domElmHandleContainer.lastChild;
} else {
domElmHandle = this.domElmHandleList[index];
}
if (index === this.lastThIndex && !hasHandleContainer) {
addClass(domElmHandle, 'last-handle');
}
if (!disabledColumn && !hasHandleContainer) {
domElmHandle.addEventListener('mousedown', this.onGripMouseDown);
} else if (disabledColumn && !hasHandleContainer) {
addClass(domElmHandle, 'disabled-drag');
}
domElmHandle.index = index;
domElmTh.w = domElmTh.offsetWidth;
domElmTh.style.width = `${domElmTh.offsetWidth}px`;
if (!hasHandleContainer) {
this.domElmHandleList.push(domElmHandle);
}
this.domElmTableTheadThList.push(domElmTh);
});
this.syncGrips();
}
syncGrips() {
const { headerOnly } = this.options;
const theadHight = this.domElmTableTheadThList[0].offsetHeight;
let height;
if (headerOnly) {
height = theadHight;
} else {
height = this.domElmTable.offsetHeight;
}
for (let i = 0; i < this.thLength; i += 1) {
const domElmTh = this.domElmTableTheadThList[i];
let left;
if (i === 0) {
left = domElmTh.offsetWidth + (this.cellSpacing / 2);
} else {
const handleColLeft = this.domElmHandleList[i - 1].style.left + (this.cellSpacing / 2);
left = tryParseInt(handleColLeft) + domElmTh.offsetWidth;
}
this.domElmHandleList[i].style.left = `${left}px`;
this.domElmHandleList[i].style.height = `${height}px`;
}
const domElmIconList = [];
const iconHeight = this.domElmHandleContainer.querySelector('.col-resize-container .icon').offsetHeight;
const domElemIcons = this.domElmHandleContainer.querySelectorAll('.col-resize-container .icon');
Array.prototype.push.apply(domElmIconList, domElemIcons);
domElmIconList.forEach((el) => {
const marginTopNumber = (theadHight - iconHeight) / 2;
el.style.marginTop = `${tryParseInt(marginTopNumber)}px`;
});
}
onGripMouseDown(e) {
e.preventDefault();
const { index } = e.currentTarget;
const domElmHandle = this.domElmHandleList[index];
addClass(domElmHandle, 'active-drag');
domElmHandle.initPageLeftX = e.pageX;
domElmHandle.initLeft = tryParseInt(domElmHandle.style.left);
domElmHandle.x = domElmHandle.initLeft;
this.drag = domElmHandle;
document.addEventListener('mousemove', this.onMouseMove);
document.addEventListener('mouseup', this.onMouseUp);
return false;
}
onMouseMove(e) {
e.preventDefault();
if (!this.drag) {
return false;
}
const { defaultMinWidth } = this.options;
const index = this.drag.index;
const minWidth = defaultMinWidth;
const pageLeftX = e.pageX;
let x = (pageLeftX - this.drag.initPageLeftX) + this.drag.initLeft;
const l = (this.cellSpacing * 1.5) + minWidth + this.borderLeftWidth;
const min = index ? tryParseInt(this.domElmHandleList[index - 1].style.left)
+ this.cellSpacing + minWidth : l;
const max = tryParseInt(this.domElmHandleList[index + 1].style.left)
- this.cellSpacing - minWidth;
x = Math.max(min, Math.min(max, x));
const inc = x - this.drag.initLeft;
const domElmThNow = this.domElmTableTheadThList[index];
const domElmThElmNext = this.domElmTableTheadThList[index + 1];
const w = domElmThNow.w + inc;
const w2 = domElmThElmNext.w - inc;
const minWidthOne = tryParseInt(this.domElmTableTheadThList[index].getAttribute('data-min-width'));
const minWidthTwo = tryParseInt(this.domElmTableTheadThList[index + 1].getAttribute('data-min-width'));
if (minWidthOne > w) {
x = (minWidthOne - domElmThNow.w) + this.drag.initLeft;
} else if (minWidthTwo > w2) {
x = (domElmThElmNext.w - minWidthTwo) + this.drag.initLeft;
}
this.drag.x = x;
this.drag.style.left = `${x}px`;
if (this.options.liveDrag) {
this.syncCols(index);
this.syncGrips();
const { onResizing } = this.options;
if (isFunction(onResizing)) {
onResizing(e);
}
}
return false;
}
syncCols(i, isOver) {
const inc = this.drag.x - this.drag.initLeft;
const domElmThNow = this.domElmTableTheadThList[i];
const domElmThNext = this.domElmTableTheadThList[i + 1];
const w = domElmThNow.w + inc;
const w2 = domElmThNext.w - inc;
domElmThNow.style.width = `${w}px`;
domElmThNext.style.width = `${w2}px`;
if (isOver) {
domElmThNow.w = w;
domElmThNext.w = w2;
}
}
onMouseUp(e) {
document.removeEventListener('mouseup', this.onMouseUp);
document.removeEventListener('mousemove', this.onMouseMove);
if (!this.drag) {
return false;
}
removeClass(this.drag, 'active-drag');
if (!(this.drag.x - this.drag.initLeft === 0)) {
const index = this.drag.index;
this.syncCols(index, true);
this.syncGrips();
const { onResized } = this.options;
if (isFunction(onResized)) {
onResized(e);
}
}
this.drag = null;
return true;
}
}

View File

@ -1,14 +0,0 @@
import isElement from 'lodash/isElement';
import ColResizable from './colResizable';
// import '../style/index.less';
const createColResizable = (domEleTable, options) => {
if (isElement(domEleTable) && domEleTable.nodeName === 'TABLE') {
return domEleTable.__resizable ||
(domEleTable.__resizable = new ColResizable(domEleTable, options));
}
return null;
};
export default createColResizable;