The new Data Grid component

This post is very old. The concepts it describes are still valid, but it’s worth adding that today rendering the forms in a repeating panel is much faster, the DataGrid in general works better and this custom component shows how to do the automatic scrolling: Auto Scroll - Automatically add content as the user scrolls the mouse wheel


Using the Data Grid can be slow for two reasons: retrieving the data can take too long with list comprehension and the creation of many row item forms can be slow when using long lists.

The first can be fixed by using SQL. The second by using Linear Panels and getting rid of the data binding.

Here is a quick description of my approach to the creation of a page with 25 items that can get longer by appending pages of 25 items. It loads many pages without slowing down the way Facebook and many other sites do when you scroll down.

When you insert a Data Grid component it comes with a Data Row Panel which contains many RowItem forms. The whole package uses the data binding to magically create one RowItem at a time from self.items. This works well when self.items is small enough.

My first attempt to speed it up with longer lists was to play with slicing (see here), but I didn’t go too far.

My second attempt works very well: I replaced the Data Row Panel with a Linear Panel and I added a Load more button with code similar to this:

  def load_more_click(self, **event_args):
    items = anvil.server.call('get_items', from_row=len(self.linear_panel.get_components()))
    for item in items:
      self.linear_panel.add_component(RowItem(item=contact))
    if len(new_contacts) < 25:
      self.load_more.enabled = False

The server side function get_items uses SQL with LIMIT and OFFSET to load the next 25 items. I am planning to replace the button with the javascript scroll event so the new items are loaded automatically without the need of any clicking.

I am not using the data binding because adding items to self.items does not trigger the refresh of the form. Doing self.items = self.items does, but it would remove and recreate the whole set of RowItem forms every time the data binding is refreshed and get slower and slower as the list grows.

By managing my own loop I add new items to the list of existing items, so adding 25 more items always takes the same amount of time, regardless of how many items are already displayed.

The nice thing is that the information about the columns are transferred from the Data Grid component to the RowItem form even after replacing the Data Row Panel with a Linear Panel. This detail is not documented (I think), so I hope it will keep working.

4 Likes