2020-06-09 07:02:13 +00:00
|
|
|
import React from "react";
|
|
|
|
import styled from "styled-components";
|
|
|
|
import PropTypes from "prop-types";
|
|
|
|
|
|
|
|
const StyledFrame = styled.div`
|
|
|
|
height: 100%;
|
|
|
|
display: contents;
|
|
|
|
|
|
|
|
.selectFrame {
|
|
|
|
display: block;
|
|
|
|
line-height: 0;
|
|
|
|
border: 1px dotted #5c6a8e;
|
|
|
|
background-color: #6582c9;
|
|
|
|
position: fixed;
|
|
|
|
z-index: 100;
|
|
|
|
visibility: hidden;
|
|
|
|
opacity: 0.4;
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
class SelectedFrame extends React.Component {
|
|
|
|
state = {
|
|
|
|
mouseDown: false,
|
|
|
|
top: 0,
|
|
|
|
left: 0
|
|
|
|
};
|
|
|
|
|
|
|
|
refFrame = React.createRef();
|
|
|
|
container = null;
|
|
|
|
offsetTopStart = 185;
|
|
|
|
offsetTopEnd = 135;
|
|
|
|
|
|
|
|
getCoords = e => {
|
|
|
|
const posX = e.pageX;
|
|
|
|
const posY = e.pageY;
|
|
|
|
return [posY, posX];
|
|
|
|
};
|
|
|
|
|
|
|
|
onMouseDown = e => {
|
2020-06-17 08:40:20 +00:00
|
|
|
const mouseButton = e.which ? e.which !== 1 : e.button ? e.button !== 0 : false;
|
2020-06-09 07:02:13 +00:00
|
|
|
this.container = document.getElementById("rowContainer");
|
2020-06-17 08:40:20 +00:00
|
|
|
if(mouseButton || !this.container || e.target.tagName !== "DIV") {
|
2020-06-10 09:09:02 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-06-09 07:02:13 +00:00
|
|
|
const mouseYX = this.getCoords(e);
|
|
|
|
const top = mouseYX[0];
|
|
|
|
const left = mouseYX[1];
|
2020-06-11 06:54:33 +00:00
|
|
|
let needUpdate = true;
|
2020-06-09 07:02:13 +00:00
|
|
|
|
|
|
|
for (let childItem in this.container.childNodes) {
|
|
|
|
if (this.container.childNodes[childItem].nodeType === 1) {
|
|
|
|
const item = this.container.childNodes[childItem];
|
2020-06-11 06:54:33 +00:00
|
|
|
const currentItem = item.childNodes[0];
|
|
|
|
const itemHeight = currentItem.offsetHeight;
|
2020-06-09 07:02:13 +00:00
|
|
|
|
|
|
|
const topStart = top - this.offsetTopStart - itemHeight;
|
|
|
|
const topEnd = mouseYX[0] - this.offsetTopEnd - itemHeight;
|
2020-06-11 07:16:14 +00:00
|
|
|
const offsetScroll = this.props.scrollRef.current.viewScrollTop || 0;
|
2020-06-09 07:02:13 +00:00
|
|
|
|
2020-06-11 06:54:33 +00:00
|
|
|
if (item.offsetTop - offsetScroll >= topStart && item.offsetTop - offsetScroll <= topEnd) {
|
2020-06-17 14:15:15 +00:00
|
|
|
const value = currentItem.getAttribute("value");
|
|
|
|
if (value && value.split("_")[2]) {
|
2020-06-11 06:54:33 +00:00
|
|
|
needUpdate = false;
|
2020-06-09 07:02:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 06:54:33 +00:00
|
|
|
if (needUpdate) {
|
2020-06-09 07:02:13 +00:00
|
|
|
document.addEventListener("mousemove", this.onMouseMove, false);
|
|
|
|
this.setState({ mouseDown: true, top, left });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
onMouseMove = e => {
|
|
|
|
const { mouseDown, left, top } = this.state;
|
|
|
|
|
|
|
|
if (mouseDown) {
|
|
|
|
const mouseYX = this.getCoords(e);
|
|
|
|
const frame = this.refFrame.current;
|
|
|
|
let currentLeft = left;
|
|
|
|
let currentTop = top;
|
|
|
|
let nextTop = mouseYX[0];
|
|
|
|
let nextLeft = mouseYX[1];
|
|
|
|
|
|
|
|
if (currentLeft === nextLeft || currentTop === nextTop) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentLeft > nextLeft) {
|
|
|
|
currentLeft = currentLeft + nextLeft;
|
|
|
|
nextLeft = currentLeft - nextLeft;
|
|
|
|
currentLeft = currentLeft - nextLeft;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (currentTop > nextTop) {
|
|
|
|
currentTop = currentTop + nextTop;
|
|
|
|
nextTop = currentTop - nextTop;
|
|
|
|
currentTop = currentTop - nextTop;
|
|
|
|
}
|
|
|
|
|
|
|
|
const width = nextLeft - currentLeft;
|
|
|
|
const height = nextTop - currentTop;
|
|
|
|
|
|
|
|
frame.style.top = `${currentTop}px`;
|
|
|
|
frame.style.left = `${currentLeft}px`;
|
|
|
|
frame.style.width = `${width}px`;
|
|
|
|
frame.style.height = `${height}px`;
|
|
|
|
frame.style.visibility = "visible";
|
|
|
|
|
|
|
|
const selectedItems = [];
|
|
|
|
for (let childItem in this.container.childNodes) {
|
|
|
|
if (this.container.childNodes[childItem].nodeType === 1) {
|
|
|
|
const item = this.container.childNodes[childItem];
|
2020-06-11 06:54:33 +00:00
|
|
|
const currentItem = item.childNodes[0];
|
2020-06-09 07:02:13 +00:00
|
|
|
|
2020-06-11 06:54:33 +00:00
|
|
|
const itemHeight = currentItem.offsetHeight;
|
2020-06-09 07:02:13 +00:00
|
|
|
const topStartUp = top - this.offsetTopStart - itemHeight;
|
|
|
|
const topEndUp = mouseYX[0] - this.offsetTopEnd - itemHeight;
|
|
|
|
|
|
|
|
const topEndDown = mouseYX[0] - this.offsetTopStart - itemHeight;
|
|
|
|
const topStartDown = top - this.offsetTopEnd - itemHeight;
|
2020-06-11 07:16:14 +00:00
|
|
|
const offsetScroll = this.props.scrollRef.current.viewScrollTop || 0;
|
2020-06-09 07:02:13 +00:00
|
|
|
|
|
|
|
if (
|
2020-06-11 06:54:33 +00:00
|
|
|
(item.offsetTop - offsetScroll >= topStartUp && item.offsetTop - offsetScroll <= topEndUp) ||
|
|
|
|
(item.offsetTop - offsetScroll <= topStartDown && item.offsetTop - offsetScroll >= topEndDown)
|
2020-06-09 07:02:13 +00:00
|
|
|
) {
|
2020-06-11 06:54:33 +00:00
|
|
|
const value = currentItem.getAttribute("value");
|
2020-06-09 07:02:13 +00:00
|
|
|
selectedItems.push(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.props.setSelections(selectedItems);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-06-17 08:40:20 +00:00
|
|
|
onMouseUp = e => {
|
|
|
|
const mouseButton = e.which ? e.which !== 1 : e.button ? e.button !== 0 : false;
|
|
|
|
if(mouseButton) { return; }
|
2020-06-09 07:02:13 +00:00
|
|
|
const frame = this.refFrame.current;
|
|
|
|
frame.style.visibility = "hidden";
|
|
|
|
document.removeEventListener("mousemove", this.onMouseMove);
|
|
|
|
this.setState({ mouseDown: false });
|
|
|
|
};
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
window.addEventListener("mouseup", this.onMouseUp);
|
|
|
|
}
|
|
|
|
|
2020-06-10 09:09:02 +00:00
|
|
|
componentWillUnmount() {
|
|
|
|
window.removeEventListener("mouseup", this.onMouseUp);
|
|
|
|
}
|
|
|
|
|
2020-06-09 07:02:13 +00:00
|
|
|
render() {
|
|
|
|
const { children, ...rest } = this.props;
|
|
|
|
return (
|
|
|
|
<StyledFrame onMouseDown={this.onMouseDown} {...rest}>
|
|
|
|
<div className="selectFrame" ref={this.refFrame} />
|
|
|
|
{children}
|
|
|
|
</StyledFrame>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SelectedFrame.propTypes = {
|
|
|
|
children: PropTypes.any,
|
2020-06-11 06:54:33 +00:00
|
|
|
scrollRef: PropTypes.any,
|
2020-06-09 07:02:13 +00:00
|
|
|
setSelections: PropTypes.func
|
|
|
|
};
|
|
|
|
|
|
|
|
export default SelectedFrame;
|