virtualized-table-for-antd icon indicating copy to clipboard operation
virtualized-table-for-antd copied to clipboard

Is there a way to scroll to a specific row, not y position?

Open dcfranca opened this issue 4 years ago • 20 comments

The height of my rows vary, so it is hard to be accurate while trying to scroll to it Is there a way to specify the row to scroll to? Or a way to figure out the y value on that position so I can pass the correct value to scrollTo?

At the moment I'm doing something like: ref.current.scrollTo(index * avgRowSize);

But it is highly inaccurate, and more often than not it leads to a totally different place

dcfranca avatar Apr 05 '21 17:04 dcfranca

anyone?

dcfranca avatar Apr 09 '21 17:04 dcfranca

the height for each row will dependents on the 1st of row if it hasn't been rendered,

If every tr has been rendered (scroll the table from top to bottom... ), then calling scrollTo will accurately scroll to the specified position.

wubostc avatar Apr 14 '21 12:04 wubostc

@wubostc Sorry, didn't get it... could you elaborate (or post some example?)

How would I do if I want to scroll, for example, to row 625?

dcfranca avatar Apr 14 '21 16:04 dcfranca

https://github.com/wubostc/virtualized-table-for-antd/blob/master/test/reload.tsx https://github.com/wubostc/virtualized-table-for-antd/blob/master/test/scroll-to.tsx

like following...

const ctx  = {};

...
    useVT(() => ({  onScroll: ({ top }) => { ctx.top = top } }))

// then use ref.current.scrollTo(ctx.top)

wubostc avatar Apr 15 '21 09:04 wubostc

@wubostc but those examples still use y position, not the row index, or am I missing something?

ex: if I have 5 rows

row 0: height: 50 row 1: height: 100 row 2: height: 30 row 3: height: 50 row 4: height : 70

the average row height is 60, but if try to locate the y position of the row based on an average I get an inaccurate position let's say I want the row 3 position: 60 * 3 = 240, but the actual position would be: 230... as the table increase in size the difference gap gets bigger.

I want a way to say something like: scrollToRow(4) and it scrolls to the right row

dcfranca avatar Apr 15 '21 12:04 dcfranca

that is the correct scrolling behavior , a correct value ...

          top(y)

0 : 50 -> 50 1 : 100 -> 150 2: 30 -> 180 3: 50 -> 230

wubostc avatar Apr 15 '21 13:04 wubostc

and these 300-305 to calculate the top value.

you can see it, and you will know ...

wubostc avatar Apr 15 '21 13:04 wubostc

the height for each row will dependents on the 1st of row if it hasn't been rendered,

If every tr has been rendered (scroll the table from top to bottom... ), then calling scrollTo will accurately scroll to the specified position.

@dcfranca

VT is rendered based on simulated events. currently, it cannot be rendered based on rowIndex...

to achieve what you said requires some changes that are not too difficult. . .

wubostc avatar Apr 15 '21 13:04 wubostc

Hi! Any news on this? The API proposed by @dcfranca looks interesting, i have a similiar usecase on my table. After some data is loaded, if the table was scrolled to the bottom by the user, on the next request, the scroll position persists and stays at the bottom or the last position the user scrolled to. I'm trying to make the scroll to allways be on the top of the table after each request, so this way, i'm always at the first item when the data is loaded, as said item needs to be highlighted on our case.

Thanks!

eduardobalbo avatar Jun 28 '21 17:06 eduardobalbo

@eduardobalbo you can use ref.current.scrollTo(0) to scroll to the top of table after each request example scroll-to

and then the first item you said needs to be highlighted, you can reference both https://ant.design/components/table/#components-table-demo-edit-cell and https://github.com/wubostc/virtualized-table-for-antd/blob/master/test/CustomRows%20Hooks.jsx

wubostc avatar Jun 30 '21 03:06 wubostc

Thank you @wubostc! I managed to achieve it, but now, a weird interaction is hapenning, sometimes when the table has many rows, above 100 or so, the scroll works flawlessly, but them if i load any new data, that has less rows, like 5 or 10, the scroll stays on the previous size, and i can scroll trough a bunch of blank rows.

My ANTD table is set as follows:

<Table
        data-testid='label-table-stock'
        size='small'
        components={VT}
        scroll={{ y: 250 }}
        rowKey='recno'
        bordered
        pagination={false}
        dataSource={data}
        sticky={true}
        showSorterTooltip={false}
        className={Styles.labelTable}
        loading={useLoadState.isLoading}
      >
// colums goes here
</ Table>

Styles as follows:

 .labelTable {
    table {
      th {
        font-weight: bold !important;
      }
    }

And my VT declaration is as follows:

const tableRef = useRef<{ scrollTo: (y: number) => void }>()

const [VT] = useVT(() => {
  return {
    ref: tableRef,
    scroll: {
      y: 250
    },
    debug: true
  }
}, [])

There are no errors on the console even with debug set to true.

It's kinda weird since there are some times that i have almost 2000 rows, and sometimes i have like 10 or so, but with the blanks still there as if i still had 2000 rows. It dosnt allways happens, but it's quite often.

Any idea why?

eduardobalbo avatar Jul 06 '21 14:07 eduardobalbo

@eduardobalbo You can see the prop "CLICK~DIAGNOSIS" in the debug info (click it to expand), then click it, everything is okay if that shows "normal".

wubostc avatar Jul 07 '21 08:07 wubostc

Hello @wubostc ! It worked fine, but well, i have another issue. I have a Antd tab component, that has 2 tabs, in each one of this tabs i have a table.

When i load data on "table A", it works fine, all the rows are rendered and the scroll is also rendered when the table gets to it's maxHeight, i also can scroll the whole table normally.

When i load data on "table B", it also works fine, but, if "table B" has a maxHeight smaller than "table A", it sets table A height to just one row, or sometimes to the same height as the maxHeight on the smaller table ("B").

Both tables are using different VT declarations with distinct 'id' properties. It also happens if we invert the logic and make "table B" maxHeight bigger than "table A", thus making "table B" have only one row when "table A" content is smaller than "table B" maxHeight.

Right now table A is set as follows:

<Table
    data-testid='shard-table'
    size='small'
    components={VT}
    scroll={{ y: 350 }}
    rowKey='keyShard'
    pagination={false}
    dataSource={data}
>
// colums goes here
</ Table>

const [VT] = useVT(() => {
  return {
    id: 1,
    ref: tableShardRef,
    scroll: {
      y: 350
    },
    debug: true
  }
}, [])

And table B as follows:

<Table
    data-testid='fragment-table'
    size='small'
    components={VT}
    scroll={{ y: 225 }}
    rowKey='keyFragment'
    pagination={false}
    dataSource={data}
>
// colums goes here
</ Table>

const [VT] = useVT(() => {
  return {
    id: 2,
    ref: tableFragmentRef,
    scroll: {
      y: 225
    }
  }
}, [])

I hope it doesnt sound that confusing, but this is the only issue i'm having now. Do you have any idea why?

Thanks!

balboFK avatar Aug 11 '21 17:08 balboFK

Hello @wubostc ! It worked fine, but well, i have another issue. I have a Antd tab component, that has 2 tabs, in each one of this tabs i have a table.

When i load data on "table A", it works fine, all the rows are rendered and the scroll is also rendered when the table gets to it's maxHeight, i also can scroll the whole table normally.

When i load data on "table B", it also works fine, but, if "table B" has a maxHeight smaller than "table A", it sets table A height to just one row, or sometimes to the same height as the maxHeight on the smaller table ("B").

Both tables are using different VT declarations with distinct 'id' properties. It also happens if we invert the logic and make "table B" maxHeight bigger than "table A", thus making "table B" have only one row when "table A" content is smaller than "table B" maxHeight.

Right now table A is set as follows:

<Table
    data-testid='shard-table'
    size='small'
    components={VT}
    scroll={{ y: 350 }}
    rowKey='keyShard'
    pagination={false}
    dataSource={data}
>
// colums goes here
</ Table>

const [VT] = useVT(() => {
  return {
    id: 1,
    ref: tableShardRef,
    scroll: {
      y: 350
    },
    debug: true
  }
}, [])

And table B as follows:

<Table
    data-testid='fragment-table'
    size='small'
    components={VT}
    scroll={{ y: 225 }}
    rowKey='keyFragment'
    pagination={false}
    dataSource={data}
>
// colums goes here
</ Table>

const [VT] = useVT(() => {
  return {
    id: 2,
    ref: tableFragmentRef,
    scroll: {
      y: 225
    }
  }
}, [])

I hope it doesnt sound that confusing, but this is the only issue i'm having now. Do you have any idea why?

Thanks!

Hello @wubostc ! It worked fine, but well, i have another issue. I have a Antd tab component, that has 2 tabs, in each one of this tabs i have a table.

When i load data on "table A", it works fine, all the rows are rendered and the scroll is also rendered when the table gets to it's maxHeight, i also can scroll the whole table normally.

When i load data on "table B", it also works fine, but, if "table B" has a maxHeight smaller than "table A", it sets table A height to just one row, or sometimes to the same height as the maxHeight on the smaller table ("B").

Both tables are using different VT declarations with distinct 'id' properties. It also happens if we invert the logic and make "table B" maxHeight bigger than "table A", thus making "table B" have only one row when "table A" content is smaller than "table B" maxHeight.

Right now table A is set as follows:

<Table
    data-testid='shard-table'
    size='small'
    components={VT}
    scroll={{ y: 350 }}
    rowKey='keyShard'
    pagination={false}
    dataSource={data}
>
// colums goes here
</ Table>

const [VT] = useVT(() => {
  return {
    id: 1,
    ref: tableShardRef,
    scroll: {
      y: 350
    },
    debug: true
  }
}, [])

And table B as follows:

<Table
    data-testid='fragment-table'
    size='small'
    components={VT}
    scroll={{ y: 225 }}
    rowKey='keyFragment'
    pagination={false}
    dataSource={data}
>
// colums goes here
</ Table>

const [VT] = useVT(() => {
  return {
    id: 2,
    ref: tableFragmentRef,
    scroll: {
      y: 225
    }
  }
}, [])

I hope it doesnt sound that confusing, but this is the only issue i'm having now. Do you have any idea why?

Thanks!

You'd better reproduce your issue in codesandbox😂, i need the debugging info includes both tables

I guess it may not trigger rerendering……

wubostc avatar Aug 12 '21 03:08 wubostc

Guys, could you, please, open a new issue about that? This is totally unrelated with the original issue

dcfranca avatar Aug 12 '21 07:08 dcfranca

Will do! Sorry about that @dcfranca

balboFK avatar Aug 12 '21 11:08 balboFK

@dcfranca I have added func scrollToIndex

wubostc avatar Oct 09 '21 10:10 wubostc

@wubostc Awesome! Thanks! is it already on its latest version?

dcfranca avatar Oct 09 '21 15:10 dcfranca

@dcfranca

@wubostc Awesome! Thanks! is it already on its latest version?

yes

wubostc avatar Oct 09 '21 22:10 wubostc

Thanks! I'll check it out!

dcfranca avatar Oct 10 '21 12:10 dcfranca