bee-table
Version:
Table ui component for react
352 lines (294 loc) • 16.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
var _utils = require("./lib/utils");
var _reactDom = require("react-dom");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); }
var CAN_TOUCH = _utils.Event.isSupportTouch(); //是否支持触摸
/***
* @author Dio.Zhu
* 提供表格拖拽行排序的能力,显示拖拽行的尺标线
*/
var DragRowLine = function (_Component) {
_inherits(DragRowLine, _Component);
function DragRowLine(props) {
_classCallCheck(this, DragRowLine);
var _this = _possibleConstructorReturn(this, _Component.call(this, props));
_this.getTableRowDoms = function () {
var _this$props = _this.props,
container = _this$props.container,
clsPrefix = _this$props.clsPrefix;
if (!container || !clsPrefix) return;
var domElem = (0, _reactDom.findDOMNode)(container);
var centerBody = domElem.querySelector("." + clsPrefix + "-scroll table tbody");
if (!centerBody) {
//非固定表头的情况下
centerBody = domElem.querySelector("." + clsPrefix + "-body table tbody");
}
var leftBody = domElem.querySelector("." + clsPrefix + "-fixed-left table tbody");
var rightBody = domElem.querySelector("." + clsPrefix + "-scroll table tbody");
var centerTrs = centerBody && centerBody.getElementsByTagName("tr");
var leftTrs = leftBody && leftBody.getElementsByTagName("tr");
var rightTrs = rightBody && rightBody.getElementsByTagName("tr");
return { centerTrs: centerTrs, leftTrs: leftTrs, rightTrs: rightTrs };
};
_this.initEvent = function () {
var _this$getTableRowDoms = _this.getTableRowDoms(),
centerTrs = _this$getTableRowDoms.centerTrs,
leftTrs = _this$getTableRowDoms.leftTrs,
rightTrs = _this$getTableRowDoms.rightTrs;
var allTrs = [].concat(centerTrs, leftTrs, rightTrs);
// Event.addHandler(document.body,'drop',this.onBodyDrop);
allTrs.forEach(function (trs) {
_utils.Event.addHandlerArray(trs, 'dragstart', _this.onDragStart);
_utils.Event.addHandlerArray(trs, 'dragenter', _this.onDragEnter);
_utils.Event.addHandlerArray(trs, 'dragover', _this.onDragOver);
_utils.Event.addHandlerArray(trs, 'dragend', _this.onDragEnd);
//触屏下支持
if (CAN_TOUCH) {
_utils.Event.addHandlerArray(trs, 'touchstart', _this.onTouchStart); //手指触摸到一个 DOM 元素时触发
_utils.Event.addHandlerArray(trs, 'touchmove', _this.onTouchMove); //手指在一个 DOM 元素上滑动时触发
_utils.Event.addHandlerArray(trs, 'touchend', _this.onTouchEnd); //手指从一个 DOM 元素上移开时触发
}
});
};
_this.removeEvent = function (container) {
var _this$getTableRowDoms2 = _this.getTableRowDoms(),
centerTrs = _this$getTableRowDoms2.centerTrs,
leftTrs = _this$getTableRowDoms2.leftTrs,
rightTrs = _this$getTableRowDoms2.rightTrs;
var allTrs = [].concat(centerTrs, leftTrs, rightTrs);
allTrs.forEach(function (trs) {
_utils.Event.removeHandlerArray(trs, 'dragstart', _this.onDragStart);
_utils.Event.removeHandlerArray(trs, 'dragenter', _this.onDragEnter);
_utils.Event.removeHandlerArray(trs, 'dragover', _this.onDragOver);
_utils.Event.removeHandlerArray(trs, 'dragend', _this.onDragEnd);
//触屏下支持
if (CAN_TOUCH) {
_utils.Event.removeHandlerArray(trs, 'touchstart', _this.onTouchStart); //手指触摸到一个 DOM 元素时触发
_utils.Event.removeHandlerArray(trs, 'touchmove', _this.onTouchMove); //手指在一个 DOM 元素上滑动时触发
_utils.Event.removeHandlerArray(trs, 'touchend', _this.onTouchEnd); //手指从一个 DOM 元素上移开时触发
}
});
// Event.removeHandler(document.body,'drop',this.onBodyDrop);
};
_this.onDragStart = function (e, touchTarget) {
var _this$props2 = _this.props,
onRowDragStart = _this$props2.onRowDragStart,
container = _this$props2.container;
var contentTable = container.contentTable;
var event = _utils.Event.getEvent(e);
var target = touchTarget ? touchTarget : _utils.Event.getTarget(event); //支持触屏目标对象
if (target.nodeName.toUpperCase() == 'TD') target = target.parentNode; //如果是TD,则找到TR
if (target.nodeName.toUpperCase() !== "TR") return; //如果不是TR则终止
var dragStartKey = target.getAttribute("data-row-key");
var dragStartIndex = target.getAttribute("data-row-index");
// console.log("AAA---row-1--onDragStart"+dragStartKey)
if (!touchTarget) {
//非触摸屏
event.dataTransfer.effectAllowed = "move";
event.dataTransfer.setData("Text", JSON.stringify({ dragStartKey: dragStartKey, dragStartIndex: dragStartIndex }));
} else {
//目前触屏下没有提供抓取的阴影副本对象
}
if (contentTable) {
contentTable.dragStartKey = dragStartKey;
contentTable.dragStartIndex = dragStartIndex;
}
onRowDragStart && onRowDragStart({ dragStartKey: dragStartKey, dragStartIndex: dragStartIndex });
};
_this.onDragEnter = function (e, touchTarget) {
var container = _this.props.container;
var contentTable = container.contentTable;
var event = _utils.Event.getEvent(e),
_target = _utils.Event.getTarget(event);
var target = touchTarget ? touchTarget : _target.parentNode; //支持触屏目标对象
if (target.nodeName.toUpperCase() == 'TD') target = target.parentNode; //如果是TD,则找到TR
if (target.nodeName.toUpperCase() !== "TR") return; //如果不是TR则终止
if (!contentTable) return;
var dragEnterKey = target.getAttribute("data-row-key");
var dragEnterIndex = target.getAttribute("data-row-index");
if (!dragEnterKey) return;
var dropAlign = parseInt(dragEnterIndex) >= parseInt(contentTable.dragStartIndex) + 1 ? 'bottom' : 'top';
if (contentTable.dragStartKey && dragEnterKey !== contentTable.dragStartKey) {
contentTable.dragEnterKey = dragEnterKey;
contentTable.dragEnterIndex = dragEnterIndex;
// onRowDragEnter && onRowDragEnter(dragEnterKey,dropAlign,target);
// console.log("AAAA---1.1--enter-->"+contentTable.dragStartIndex+"->"+dragEnterIndex)
_this.setLinePosition(contentTable, target, dropAlign); //显示行拖拽的尺表线
} else {
contentTable.dragEnterKey = null;
contentTable.dragEnterIndex = null;
// console.log("AAAA---1.1--enter-hidden-->"+contentTable.dragStartIndex+"->"+dragEnterIndex)
// onRowDragEnter && onRowDragEnter(dragEnterKey,null,null);
_this.setLinePosition(contentTable, null, null); //隐藏行拖拽的尺表线
}
};
_this.onDragEnd = function (e, touchTarget) {
var _this$props3 = _this.props,
onRowDragDrop = _this$props3.onRowDragDrop,
container = _this$props3.container;
var contentTable = container.contentTable;
if (!contentTable) return;
var _ref = contentTable || {},
dragStartKey = _ref.dragStartKey,
dragStartIndex = _ref.dragStartIndex,
dragEnterKey = _ref.dragEnterKey,
dragEnterIndex = _ref.dragEnterIndex;
// console.log("AAA---row-3--onDragEnd:"+dragStartKey+"->"+dragEnterKey)
onRowDragDrop && onRowDragDrop({ dragTargetKey: dragStartKey, dragTargetIndex: dragStartIndex, dropTargetKey: dragEnterKey, dropTargetIndex: dragEnterIndex });
contentTable.dragStartKey = null;
contentTable.dragStartIndex = null;
contentTable.dragEnterKey = null;
contentTable.dragEnterIndex = null;
_this.setLinePosition(null, null, null); //隐藏行拖拽的尺表线
};
_this.onDragOver = function (e) {
var event = _utils.Event.getEvent(e);
event.preventDefault();
};
_this.onTouchStart = function (e) {
e.stopPropagation();
var event = _utils.Event.getEvent(e),
_target = _utils.Event.getTarget(event);
var target = _target;
var maxCount = 0; //向上查找最多层级数
while (target.tagName !== 'TR') {
target = target.parentNode;
maxCount++;
if (target.tagName == 'TABLE' || target.tagName == 'BODY' || maxCount > 10) {
break;
}
}
if (target.tagName === 'TR') {
_this.isTouchDragRow = true;
_this.onDragStart(e, target);
} else {
_this.isTouchDragRow = false;
}
};
_this.onTouchMove = function (e) {
if (!_this.isTouchDragRow) return;
e.stopPropagation();
var event = _utils.Event.getEvent(e);
event.preventDefault();
var touchTarget = _this.getTouchDom(event),
target = touchTarget.parentNode;
_this.onDragEnter(e, target);
};
_this.onTouchEnd = function (e) {
if (!_this.isTouchDragRow) return;
e.stopPropagation();
var event = _utils.Event.getEvent(e),
touchTarget = _this.getTouchDom(event),
//当前触摸的DOM节点
target = touchTarget.parentNode; //目标位置的行
_this.onDragEnd(e, target);
_this.isTouchDragRow = false;
};
_this.getTouchDom = function (event) {
var currentLocation = event.changedTouches[0];
var realTarget = document.elementFromPoint(currentLocation.clientX, currentLocation.clientY);
return realTarget;
};
_this.setLinePosition = function (targetContainer, targetDom, targetAlign) {
var clsPrefix = _this.props.clsPrefix;
if (!targetContainer || !targetDom) {
_this.setState({ left: 0, top: 0, width: 0, visible: false });
} else {
var contRect = targetContainer.getBoundingClientRect();
var centerBodyDom = targetContainer.querySelector("." + clsPrefix + "-content ." + clsPrefix + "-body");
var centerBodyRect = centerBodyDom.getBoundingClientRect();
var headerHeight = centerBodyRect.top - contRect.top;
var targetRect = targetDom.getBoundingClientRect();
var top = headerHeight + targetRect.top - centerBodyRect.top - 1;
if (['bottom', 'down'].includes(targetAlign)) {
top = top + targetRect.height;
}
_this.setState({ left: 0, width: contRect.width, top: top, visible: true });
}
};
_this.state = {
visible: false,
top: 0,
left: 0,
width: 0
};
return _this;
}
DragRowLine.prototype.componentDidMount = function componentDidMount() {
if (!this.props.bigData) {
//非大数据场景则直接初始化事件一次节省性能开销
this.initEvent(this.props.container);
}
};
DragRowLine.prototype.componentWillUnmount = function componentWillUnmount() {
this.removeEvent();
};
DragRowLine.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState, snapshot) {
if (this.props.bigData) {
//大数据场景则每次更新都需要重新初始化绑定事件
this.removeEvent();
this.initEvent();
} else if ((prevProps.data || []).toString() !== (this.props.data || []).toString()) {
this.removeEvent();
this.initEvent();
}
};
//获取左、中、右三个区域的全部行dom元素
//初始化绑定相关事件
//移除相关事件
/* 会导致单元格内自定义onDrop冒泡失效,所以body上不阻止冒泡。
//拖放到body区域时触发,解决Firefox下拖放会新打开浏览器窗口的问题
onBodyDrop(e){
// console.log("AAA--->2",e.dataTransfer.getData('Text'))
Event.stopPropagation(e);
}*/
/**
* 【交换行】开始拖拽
*/
/**
* 【交换行】拖拽经过目标行
*/
/**
* 【交换行】结束拖拽
*/
//触屏-手指点击时触发
//触屏-手指滑动时触发
//触屏-手指移开时触发
//获取当前触摸的Dom节点
/**
* 设置尺标线显示的位置
* @param targetContainer
* @param targetDom
* @param targetAlign
*/
DragRowLine.prototype.render = function render() {
var clsPrefix = this.props.clsPrefix;
var _state = this.state,
left = _state.left,
width = _state.width,
top = _state.top,
visible = _state.visible;
var style = { position: 'absolute', left: left + 'px', top: top + 'px', height: '2px', width: width + 'px', background: '#02B1FD', zIndex: 'auto', display: visible ? 'block' : 'none' };
return _react2["default"].createElement("div", { style: style, className: clsPrefix + "-drag-row-line", dangerouslySetInnerHTML: { __html: ' ' } });
};
return DragRowLine;
}(_react.Component);
DragRowLine.defaultProps = {
clsPrefix: '', //样式名前缀
container: null, //所属容器组件
onRowDragStart: null, //拖拽开始的回调
onRowDragDrop: null, //拖拽放置完成的回调
rowDraggAble: true, //是否启用行拖拽
bigData: false //是否大数据场景
};
exports["default"] = DragRowLine;
module.exports = exports["default"];