The new Data Grid component

Brilliant piece of work Ian and Meredydd (and anyone else who worked on it)! So simple to configure, so powerful! I’ll be converting my existing forms that currently display lists of data to instead use the new Data Grid. I especially like the to-the-pixel column resize feature!

3 Likes

Amazing work Anvil devs!!! This is incredible. :exploding_head:

Feature request: give the page_control an alignment property (left, center, right). With my full width rows, the page_control is always to the far right, almost out of view by the user.

Feature request: make the DataRowPanel usable in a tree like structure.

One way would be by adding the indent property that will add an hidden column to the left and shrink only the first column, without modifying the other column positions and widths.

Another way would be by allowing to change the column’s width from code. Right now the columns seem to be reading their definition from a dictionary at creation time, and changing the width in the dictionary at a later time doesn’t affect the column.

Data Grid columns are updated when the columns attribute itself is set. So you can tell Anvil to update the columns by doing:

    self.data_grid_1.columns = self.data_grid_1.columns

So this is one way to change a column’s width:

    self.data_grid_1.columns[0]['width'] = 500
    self.data_grid_1.columns = self.data_grid_1.columns

https://anvil.works/ide#clone:OHUUBRJDH224V7WH=B7AIGBSM7AFVHQW4CR36ABEF

I’m not quite clear on what you mean about using DataRowPanels in a tree like structure. Would they use the same columns, but be indented, or would they use different columns?

You may be able to achieve what you want by putting a Data Grid in the RepeatingPanel of an outer Data Grid, as shown in this somewhat abstract example:

https://anvil.works/ide#clone:NBDAWQMAXMVGXYSX=7ZO55AO6KXZ3F45IRTSHUDP2

I’ve set the inner Data Grid to have no column headers or page controls - obviously whether or not you keep them depends on the specific application.

What about a leading label component, its width being a multiple of the row’s indent? (Width set via Data Binding, so it can automatically change per row.) Would this work?

Granted, that wouldn’t give you outline widgets (expand/collapse buttons, connecting lines, etc.). But those aren’t always needed.

@shaun
I had tried changing the width in the dictionary, but didn’t work. I didn’t think about re-assigning the dictionary. It works now, thanks.

@p.colbert
I will try with the first empty column, changing its width by re-assigning the dictionary as Shaun suggests.
I will add a link to the second column. The link will have the open/close icons.

The tree structure will be:

  • column 1 empty with variable width to set the indentation
  • column 2 with the link with the widget, the only one without set width
  • column 3+ all with fixed width

If this works out, I’d love to see i!!

I’m starting to explore moving from my existing (heavy) usage of the data grid preview (Building a rich table as a custom component) to the new Data Grid component, and at least so far, it seems like there is a bit of gloss over some specific challenges that came up in using the preview version as well.

  1. https://anvil.works/blog/data-grid-searching details adding search support with the exact same methodology (list comprehensions) as in the preview. This still does not address challenges with searching a large data set, since server timeouts will absolutely occur as python list comprehensions cannot take advantage of database indexes and are a poor substitute. This is an understandable tradeoff since SQL queries in a shared environment can lead to resource hogging. However, while the Anvil Dedicated Server plan grants direct access to the database and thus the potential for taking advantage of database indexing for search performance, attempting to use SQL query data set results with a data grid is not documented in any way. Is there a clean way to bridge using a row id (column: _id) from an SQL query result data set over to the object style of passing around rows/items used with the Data Tables service?

    My primary reason for moving to a Dedicated Server plan in this context is for search speed, especially with %LIKE% queries. Since in Anvil, every column in indexed, I really don’t expect to see any significant difference between adding/updating rows using Data Tables or with SQL.

  1. Quickly determining the size of the data set (number of records) while only retrieving/displaying the first X (10, 20, etc.) records doesn’t seem to be addressed.

  2. Since this seems to bear a lot of similarities to the preview version, I suspect that creating a selection grid (where the first column is a checkbox that creates or removes relationships in a one-to-many scenario, for example) is still possible, but a tutorial that walks through such a usage would make this more accessible for an extremely common pattern.

  3. When will we see the Data Tables service use the new Data Grid component in the development environment for both browsing and searching records as well as editing relationships? The current default of loading 100 records is way too much, there is no way to quickly get to record number 1000, for instance, and the relationship editing interface breaks as soon as the number of possible related records is over about 100 records. Ideally relationship editing would have a built-in filter (or search) that shows only selected records.

Thanks for all you guys do to make Anvil more awesome all the time, things like this make it easier and easier to not only choose Anvil for new projects, but increase the runway for either staying on Anvil longer before moving to “power tools” like MEAN/MERN stack (or others) as well as just leaving an app on Anvil indefinitely. Support for mobile apps (on even Progressive Web Apps, as support improves) will make even more possible.

3 Likes

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

Hey Stefano,

I am running into this same problem now with my app. Any chance you could share a copy of an app that uses the load more functionality? Or better yet if you have done the scroll implementation that would be awesome!

I figured out the infinite scroll!! Check it out here: https://anvil.works/build#clone:ZA7ENWHOVT7D7CQ3=6RUAT5ZZEQ3CEF6UFIP2BQ6B

1 Like