I have a QQTable
functional component that contains 1 QQTableBody
. And the QQTableBody
functional component contains several QQRow
functional components. And each QQRow
functional components has several QQCell
functional components.
Here is the QQTable
snippnet:
import {useCallback,useContext,useEffect, useState} from 'react';
import QQTableBody from './QQTableBody';
import QQTableHeader from './QQTableHeader';
import Roster from '../../utils/Roster';
import RosterWebContext from '../../utils/RosterWebContext';
import SelectedRegion from '../../utils/SelectedRegion';
import SelectedRegionUtil from '../../utils/SelectedRegionUtil';
export default function QQTable(props){
const[activeShiftInfoList,setActiveShiftInfoList]=useState();
const [rosterData,setRosterData]=useState();
const [selectedRegion,setSelectedRegion]=useState(new SelectedRegion());
let componentList=[];
let systemParam=props.systemParam;
let mouseUp=useCallback(()=>{
console.log("mouse up");
console.log(selectedRegion.inSelectMode);
SelectedRegionUtil.endSelect(selectedRegion,setSelectedRegion);
},[selectedRegion]);
useEffect(()=>{
const getData = async () => {
console.log("getData() is triggered");
.................................
let roster = new Roster();
temp = await roster.getAllActiveShiftInfo();
setActiveShiftInfoList(temp);
temp= await roster.get(props.rosterMonth.getFullYear(),props.rosterMonth.getMonth()+1);
setRosterData (temp);
document.addEventListener('mouseup',mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp)
}
}
getData();
},[props.rosterMonth]);
let contextValue={}
if (rosterData){
contextValue={
activeShiftInfoList,
rosterData,
selectedRegion,
setHightLightCellIndex,
setRosterData,
setSelectedRegion,
}
..........
componentList.push(<QQTableBody key="body"/>);
}
return(
<RosterWebContext.Provider value={contextValue}>
<table id="rosterTable">
{componentList}
</table>
</RosterWebContext.Provider>
)
}
Here is the QQCell
snippet:
import {useContext} from 'react';
import RosterWebContext from '../../utils/RosterWebContext';
import SelectedRegionUtil from '../../utils/SelectedRegionUtil';
export default function QQCell(props){
let cssClassName="QQ";
let {
selectedRegion,
setSelectedRegion
} = useContext(RosterWebContext);
function mouseDownHandler(e){
SelectedRegionUtil.startSelect(e.target,selectedRegion,setSelectedRegion);
}
function mouseEnterHandler(e){
props.onMouseEnter(e);
SelectedRegionUtil.updateSelect(e.target, selectedRegion,setSelectedRegion);
}
return (
<td
className={cssClassName}
contentEditable={true}
onMouseDown={mouseDownHandler}
onMouseEnter={mouseEnterHandler}
suppressContentEditableWarning={true}>
{props.children}
</td>
)
}
And the snippet of SelectedRegionUtil
:
export default class SelectedRegionUtil{
.....................
static endSelect(selectedRegion,setSelectedRegion){
if (selectedRegion.inSelectMode){
let temp=JSON.parse(JSON.stringify(selectedRegion));
temp.inSelectMode=false;
setSelectedRegion(temp);
}
}
............................................
static startSelect(theCell,selectedRegion,setSelectedRegion){
let row=theCell.parentElement;
let temp=JSON.parse(JSON.stringify(selectedRegion));
temp.firstX=theCell.cellIndex;
temp.firstY=row.rowIndex;
temp.minX=theCell.cellIndex;
temp.minY=row.rowIndex;
temp.maxX=theCell.cellIndex;
temp.maxY=row.rowIndex;
temp.inSelectMode=true;
console.log("temp="+JSON.stringify(temp));
setSelectedRegion(temp);
}
..........................................................
static updateSelect(theCell,selectedRegion,setSelectedRegion){
if (selectedRegion.inSelectMode){
let cellIndex=theCell.cellIndex;
let isChanged=false;
let newMaxX=selectedRegion.maxX,newMinX=selectedRegion.minX;
let newMaxY=selectedRegion.maxY,newMinY=selectedRegion.minY;
let row=theCell.parentElement;
let rowIndex=row.rowIndex;
if (cellIndex<selectedRegion.firstX)
{
newMinX=cellIndex;
isChanged=true;
}
else
{
if (cellIndex>selectedRegion.firstX)
{
newMaxX=cellIndex;
isChanged=true;
}
else
{
newMinX=selectedRegion.firstX;
newMaxX=selectedRegion.firstX;
isChanged=true;
}
}
if (rowIndex>selectedRegion.firstY)
{
newMaxY=rowIndex;
isChanged=true;
}
else
{
if (rowIndex<selectedRegion.firstY)
{
newMinY=rowIndex;
isChanged=true;
}
else
{
newMinY=selectedRegion.firstY;
newMaxY=selectedRegion.firstY;
isChanged=true;
}
}
if (isChanged){
//console.log("isChanged=true");
let temp=JSON.parse(JSON.stringify(selectedRegion))
temp.minX=newMinX;
temp.maxX=newMaxX;
temp.minY=newMinY;
temp.maxY=newMaxY;
setSelectedRegion(temp);
}
}
}
}
Finally, the SelectedRegion
snippet:
export default class SelectedRegion{
constructor(){
this.firstX=-1;
this.firstY=-1;
this.inSelectMode=false;
this.minX=-1;
this.minY=-1;
this.maxX=-1;
this.maxY=-1;
}
}
The above snippet shows the QQCell functional component call SelectedRegionUtil to change the state variable selectedRegion.inSelectMode to true.
Unfortunately, the mouseUp function in QQTable
always shows the value of selectedRegion.inSelectMode
is false.
I have tried to move the mouseUp function into the useEffect
function, but the result is the same.
Would you how to fix it?
Or is there any package that can perform the select, copy and paste function in a region of a table only but not the whole table?
Finally, in the QQTable
component, I remove the following coding from useEffect
hook:
document.addEventListener('mouseup',mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp)
}
And then add another useEffect
hook in the QQTable
component:
useEffect(()=>{
document.addEventListener('mouseup',mouseUp);
return () => {
document.removeEventListener('mouseup', mouseUp)
}
},[mouseUp])
It works as I expected.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.