I have 3 handsontables in my React view. I need them to be synced when the user is scrolling both horizontally and vertically. I tried to use javascript to get horizontally working without any luck.
import React from 'react';
import ReactDOM from 'react-dom';
const handsontableData = Handsontable.helper.createSpreadsheetData(6, 50);
const Table1 = () => (
<div>
<Handsontable.react.HotTable
id="T1"
data={handsontableData}
colHeaders
rowHeaders
colWidths={[100]}
height={200}
width="100vw"
/>
</div>
);
const Table2 = () => (
<div>
<Handsontable.react.HotTable
id="T2"
data={handsontableData}
colHeaders
rowHeaders
colWidths={[100]}
height={200}
width="100vw"
/>
</div>
);
const Table3 = () => (
<div>
<Handsontable.react.HotTable
id="T3"
data={handsontableData}
colHeaders
rowHeaders
colWidths={[100]}
height={200}
width="100vw"
/>
</div>
);
const App = () => {
const T1Obj = document.getElementById('T1');
const T2Obj = document.getElementById('T2');
const T3Obj = document.getElementById('T3');
function getScroll(event) {
let elem;
if (event.type === 'scroll') {
elem = (event.srcElement) ? event.srcElement : event.target;
if (elem.id === 'T1') {
T2Obj.scrollLeft = elem.scrollLeft;
T3Obj.scrollLeft = elem.scrollLeft;
} else if (elem.id === 'T2') {
T1Obj.scrollLeft = elem.scrollLeft;
T3Obj.scrollLeft = elem.scrollLeft;
} else if (elem.id === 'T3') {
T1Obj.scrollLeft = elem.scrollLeft;
T2Obj.scrollLeft = elem.scrollLeft;
}
}
}
if (typeof addEventListener !== 'undefined') {
T1Obj && T1Obj.addEventListener('scroll', getScroll);
T2Obj && T2Obj.addEventListener('scroll', getScroll);
} else {
T1Obj && T1Obj.attachEvent('onscroll', getScroll);
T2Obj && T2Obj.attachEvent('onscroll', getScroll);
}
return (
<div>
<Table1 />
<br />
<Table2 />
<br />
<Table3 />
<br />
</div>
);
};
ReactDOM.render(<App />, document.getElementById('example1'));
<link href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@handsontable/react/dist/react-handsontable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
I couldn't get it run in the StackOverflow code editor. so here is link to jsfiddle link
Something like this?
function syncScroll(elements) {
function getScrollPositions() {
return elements.map((el) => ({
scrollLeft: el.scrollLeft,
scrollTop: el.scrollTop,
}));
}
let scrollPositions = getScrollPositions();
elements.forEach((el) =>
el.addEventListener("scroll", () => {
let currentPositions = getScrollPositions();
for (let [i, position] of currentPositions.entries()) {
for (let dim of ["scrollLeft", "scrollTop"]) {
if (position[dim] != scrollPositions[i][dim]) {
for (let element of elements) {
element[dim] = position[dim];
}
}
}
}
scrollPositions = currentPositions;
})
);
}
syncScroll([T1Obj, T2Obj, T3Obj]);
https://jsfiddle.net/xowvp3a9/
Also keep in mind the elements that are scrolling are not #T1
, #T2
, #T3
, but a div inside them. You can see it with the scroll tag.
For that reason:
const T1Obj = document.querySelector('#T1 .wtHolder');
const T2Obj = document.querySelector('#T2 .wtHolder');
const T3Obj = document.querySelector('#T3 .wtHolder');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With