Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite scroll for Ant Table #5904

Closed
kappa-gooner opened this issue Apr 26, 2017 · 18 comments
Closed

Infinite scroll for Ant Table #5904

kappa-gooner opened this issue Apr 26, 2017 · 18 comments

Comments

@kappa-gooner
Copy link
Contributor

What problem does this feature solve?

As great as ant's pagination is, it is also something that is not very modern. I'd like to wrap the table in a infinite scroll that would make ajax request and fetch more rows upon scrolling (Refer here).
This is a simple example of creating such a table.

What does the proposed API look like?

To be honest, am not too sure at this point.

For a start we could wrap the Table in an InfiniteLoader HOC and have a event handler prop on the table onScroll that is triggered when the table is scrolled. The purpose of the InfiniteLoader would be to help break large data sets down into chunks that could be just-in-time loaded as they were scrolled into view.

I'll be happy to send forth a PR if you think this might be useful. If not, please feel free to close this item.

@kappa-gooner
Copy link
Contributor Author

Any comments @afc163 @benjycui?

@benjycui
Copy link
Contributor

benjycui commented May 3, 2017

I don't think this feature should be included in antd. For it's hard to decide that which element's scroll events we should listen to.

And you can implement this in your own component easily.

@kappa-gooner
Copy link
Contributor Author

Ok, since that's the case... I'm closing this issue for now.

@EduardoAC
Copy link

I would like this feature too or at least the capability to render more data dynamically.

@burubur
Copy link

burubur commented Oct 3, 2017

Wohoo, it is very easy to implement dynamic rows loading/infinite scrolling on antd table, I can chunk the httpRequest with this code:

componentDidMount() {
...
var tableContent = document.querySelector('.ant-table-body')
    tableContent.addEventListener('scroll', (event) => {
      // checking whether a selector is well defined
      console.log('yes, I am listening')
      let maxScroll = event.target.scrollHeight - event.target.clientHeight
      let currentScroll = event.target.scrollTop
      if (currentScroll === maxScroll) {
         // load more data
      }
    })
...
}

@kappa-gooner
Copy link
Contributor Author

@burhanmubarok , thanks for the snippet.
Better to use refs to access the element and add the scroll listener though! 😸

@hosembafer
Copy link

hosembafer commented Mar 28, 2018

@burhanmubarok thank you for a nice example, I'm starting to use this, but there are problems in some cases.

For example, if my window height is 1000px, and I want to load 10 items per page/scroll, and height of each item is 50px, your example will not be working. Because scrollbar of tbody will not be rendered, I will be not able to scroll more.

@afc163 this feature is very important, I think you need to implement it. I'm starting my third project with ant.design and have the same issue with this.

@hudidit
Copy link

hudidit commented Jan 18, 2019

@burubur Nice implementation. But it's actually a bad practice to get element with a css selector that's not in your control.

@benjycui

I don't think this feature should be included in antd.

It's rational for a Table/List component to have a onscroll interface.

For it's hard to decide that which element's scroll events we should listen to.

I don't understand.

And you can implement this in your own component easily.

And don't just kick a feature request back to your user just because it's easy to implement.

@burubur
Copy link

burubur commented Mar 3, 2019

@hudidit
yes we knew, it's bad practice one, it could be just a temporary solution 😃

@akaguny
Copy link
Contributor

akaguny commented Mar 5, 2019

@kappa-gooner maybe any suggestions for the case in ant examples?

@MandyMeindersma
Copy link

With @burubur's suggestion it does work but there are a couple user experience errors:

  • The antd table automatically scrolls to top when I load new data so it makes the user jump all over the page
  • It also still displays incorrect pagination numbers at the bottom (why should there be pages if we have infinite scroll?)
  • The the scroll is on the table instead of being on the page (minor) - this is also causing my columns to be misaligned but no biggy

It would be great if the antd team would listen to this feature request.

@Suresh-R-S
Copy link

@burhanmubarok , thanks for the snippet.
Better to use refs to access the element and add the scroll listener though! 😸

Any example on how to do this?

@willyou
Copy link

willyou commented Jun 27, 2020

  • The antd table automatically scrolls to top when I load new data so it makes the user jump all over the page

should be a good workaround if set scrollToFirstRowOnChange to false. I can implement an infinite scroll.

@afbarbaro
Copy link

Can you provide an example of how to use the ref attribute within the Table component? The Typescript typings do not expose have a ref attribute.

image

@xorander00
Copy link

@afbarbaro

You can't, for now. There's no mechanism, as of yet, in antd to attach a ref to the Table component. It's hacky, but here's what I did...

Query for the element and attach the scroll event listener

useEffect(() => {
  const node = document.querySelector<HTMLElement>(".table .ant-table-body");
  if (node) {
    node.addEventListener("scroll", () => {
      const perc = (node.scrollTop / (node.scrollHeight - node.clientHeight)) * 100;
      if (perc >= 100) {
        console.log("TODO: Scrolling has reached bottom, load more data, or do whatever...");
      }
    });
  }
});

Tell the table to NOT automatically reset the scroll position on dataSource change

<Table
  className="table"
  scroll={{ scrollToFirstRowOnChange: false }}
  ...
/>

A few things to note:

  • Querying the DOM by the .ant-table-body CSS class isn't a good idea. At the very least, wrap the table with a unique className so that it's at least isolated. It's just a stop-gap approach until a proper way to attach a ref is implemented in antd.

  • The way perc is calculated may need adjustment based on the use-case. More specifically, using either clientHeight vs. offsetHeight.

  • I didn't run into any issues with the scroll event listener being added more than once, but that doesn't mean that's the case every time. Test thoroughly to be sure.

@mayuri2307
Copy link

@xorander00 This is not working for me. Could you please help me with this?

@sa1mann
Copy link

sa1mann commented Nov 3, 2021

For those who are not able to get ref or find element by querySelector

Try putting ref to upper <div> in which we have <Table> and do querySelector
if Unable to get ref

Created a component to return ref:

export class RefWrap extends React.Component {
  constructor(props) {
    super(props);
  }
  componentDidMount() {
    const { setRef } = this.props;
    // eslint-disable-next-line react/no-find-dom-node
    if (setRef) setRef(ReactDOM.findDOMNode(this));
  }
  render() {
    const { children } = this.props;
    return React.Children.only(children);
  }
}

and in our component

<RefWrap setRef={setRef} >
<Table
...
</Table>
</RefWrap>
const setRef = (ref) =>{
 if(ref){
      const tbody = ref.querySelector('.ant-table-body');
      if(tbody)
        tbody.addEventListener('scroll',() =>{console.log("Scrolling bro")},false);
    }
}

@Fauzdar1
Copy link

Fauzdar1 commented Oct 3, 2022

This infinite load is required and Pagination is not possible when data source is something like Firebase Firestore where the total number of documents is not known. In such case, either there should be this functionality of Infinite scroll-to-load or at least a "Load More" at the bottom like the Ant List. In current one, I've to implement a "Load more" feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests