Problems creating a table (or something equivalent)

I am trying to create a table that looks like this:

But this is the closest thing that I could get:

I used a Repeating Panel with the template containing 13 labels, most are the visible fields, some are the vertical bars and the last two are not visible (because the table may require 2 more columns and I didn’t know how to add them dynamically, so I added them on the designer and I just hide them if not required.) I was not able to add the last 2 vertical bars because no matter where I drop them, they go at the end after the last label.

This should look like a table regardless of the device size, instead it was difficult to create, looks ugly on a computer, worse on a cell phone.

Is there a better way to create this table?

I recommend using the borders and colors to make it more aesthetically pleasing. If you do not need this application to output data for a mobile device, I recommend making the file downloadable.

Maybe putting the table number as a column and putting a first name last name column will make the width much smaller, ( In data wrangling this is called melting a data frame.)

The table must look like a table both on phone and PC, and cannot be downloaded.

I’m playing around with Anvil just to learn what it can do, and I started with remaking this old site based on Google sheets.

If I start using anvil seriously, I will need to make many large tables, but this first attempt is very disappointing. It looks ugly, it’s difficult to design (drag and drop starts having problems after 12 labels) and I wasn’t able to make a variable number of columns.

I thought about using the borders, but I don’t have the control of which border to show. I want alternating border thicknesses like on the first snapshot, one thick and one thin.

I tried, but here is the best I came up with (the colors are there just to highlight what’s going on):

Here are some of the problems:

  1. Always 12 columns, so if I need 11 I have to pick one and make it wider, and if I need 13 I’m stuck
  2. All the columns have the same width
  3. No control over margins
  4. Limited control over borders (I need some borders thicker and some thinner)
  5. On a cell phone it looks worse than my previous attempt with labels
  6. No control over wrapping

I don’t want a responsive table, I want a scroll bar if it’s wider than the screen and a little control over the borders.

I can’t use Google sheets, I need it to be dynamically generated because I want to be able to filter and sort on demand, and show different content to different users.

If I had control over html I could make a table with all the rows with the same height (no wrapping) and automatic width, or allow the wrapping on some of them and set the width of each column programmatically.

A more Anvillista way would be something like:

tp = TablePanel()
tr = TableRow()
tr.add_component(Label("Hello"))
tr.add_component(Label("World"), col_span=2, border_style="solid solid dotted solid"))
tp.add_component(tr)

Are you saying that it is possible to use HTML?
How do I do that?
Would using HTML allow me to create a table wider than the screen?
Are you talking about the custom HTML templates?

It is indeed! I have a simple HTML-based table example nearly ready for you, but I have calls scheduled all afternoon!

I’ll try to have it with you by tomorrow.

1 Like

I was about to suggest a Canvas, but for most purposes, HTML is far, far simpler.

Instead of using a Canvas I tried with an XYPanel, and I got something almost decent:

This is the function that adds a cell to the table:

def add_label(x, y, text, width, border):
  if border:
    c = Canvas(height=self.row_height, border='solid gray thin')
    self.xy_panel_1.add_component(c, x=x - 5, y=y - 5, width=width + 1)

  if text:
    l = Label(text=text, spacing_above='none', spacing_below='none')
    self.xy_panel_1.add_component(l, x=x, y=y)
    
  return x + width, y

Good: the table is readable and scrollable on a cell phone.

Bad: the XYPanel is responsive and I have no control over its width. I can force the table to have a fixed width (automatically set by the number of labels added) but the table will be floating over the responsive panel.

Hi Stefano,

As promised, I’ve built a simple table for you as an example. Click here to clone it:
https://anvil.works/ide#clone:Y6ETUZGJWRPHVDXV=IEI2O2RMYKI7IEUCHFC2LGIC

It’s a custom component, and you use it like this:

    self.table_1.columns = ["Name", "Age"]
    self.table_1.data = [{'Name': 'Alice', 'Age': 2}, {'Name': 'Bob', 'Age': 8}]

And it looks like this:

image


PS: Yes, this is a preview of what our data grid API is going to look like. Let us know how you get on!

2 Likes

While @meredydd was working on the custom component (thank you Meredydd!) I was creating my own custom table using an XYPanel.

My target is to create a table dynamically, that is not responsive and looks the same on any device, that allows to insert any component on any cell, that allows to merge cells (similar to rowspan and colspan) and allows to add an “unlimited” number of columns.

Here is a little demo: https://anvil.works/ide#clone:X22PK3OAPDPQRDPE=4MBFG57N5HBHWVWPEUN4PUW2

I have not used it yet, I’m still playing around with Anvil to understand what it is. I don’t know if this can ever be production ready, but I think it is rapid prototyping ready.

I created an XYTable class (which is not a component, it’s just an helper class) that allows to:

  • add_component to add any component to the next cell of the current row
  • start_new_row to get the next component at the beginning of the next row instead of next to the last one
  • add_header to add a header cell with a label
  • add_cell to add a cell with a label

Implementation notes:

  • I use an XYPanel so I can add the components at specific positions
  • I use an Image on the XYPanel in order to hide anything below (I wasn’t able to get rid of some borders generated on a DashBoard, so I hide them with an image with white background; but in some cases something annoying is still visible)
  • I use one Canvas under each component being inserted in order to manage the border and the background (because I have no control over the height of labels and other components, and using border or background of a label would only work if the row height is exactly the same as the label)
  • I place the background canvas and the component on the same position with the exception of the label; the label is shifted to the right and a little narrower otherwise the text is too close to its edge.

To do:

  • I expose some of the attributes like border and background; more attributes should be exposed
  • Set the background canvases height to the maximum cell height of each row (after all the cells have been added to a row)
  • Manage horizontal lines between rows
  • Better management of merged cells (rather than direct access to x and y members)

Snapshots from the little demo:
image

2 Likes