Datagrids with dynamic columns

Hi both - i’ve taken a look at this and have a solution:

https://anvil.works/build#clone:PNJRSH2B64FS4WMR=CL2GIIGFXQHUBOX63B52WCBX

The main thing to think about here is RepeatingPanel.item_template

You have to set this to:

  • a string - which is a path to a Form "MyApp.RowTemplate1"
  • a component class - e.g. DataRowPanel

In the clone above with option 3 you were setting
self.repeating_panel_1.item_template = DataRowPanel()
which is neither of the options above - you are setting it to an instance rather than a class.

But I see in option 3 why DataRowPanel isn’t going to work because you have no control over how it is created…

What you could do is:

  1. Subclass from DataRowPanel
  2. Mimic a class with a function
    # defined inside self.button_click_3
    form_self = self
    class DataRowSubclass(DataRowPanel):
      def __init__(self, item, **properties):
        super().__init__(item=item, **properties) # DRP needs the item
        # first column for DELETE BUTTON
        # Question #1: how to pass the obj_id to the button?
        # all data_row panels have an item property so use it...
        row = item
        btn_delete = Button(icon='fa:minus-circle',tooltip='Delete this record', 
                            text=row['obj_id'],
                            tag={'obj_id': row['obj_id']},
                            align='center') 
   
        btn_delete.set_event_handler('click', form_self.btn_delete_click)      
        self.add_component(btn_delete, column=str(0))
        # dynamic columns follow
        column_id = 1
        for attribute in attributes:
          self.add_component(
            Label(text=row[attribute['attr_name']]),
            column=column_id
          )
          column_id += 1

    self.repeating_panel_1.item_template = DataRowSubclass


As an alternative - we can mimic this behaviour of a Component Class by writing a function that takes **properties as an argument and returns a component instance…

    def TemplateRowFunc(item, **properties): # we will get an item from RepeatingPanel
        drp = DataRowPanel(item=item, **properties) # pass the item to DRP
        row = item
        btn_delete = Button(icon='fa:minus-circle',tooltip='Delete this record',
                            text=row['obj_id'],
                            tag={'obj_id': row['obj_id']},
                            align='center')   
        btn_delete.set_event_handler('click',self.btn_delete_click)      
        drp.add_component(btn_delete, column=str(0))
        # dynamic columns follow
        column_id = 1
        for attribute in attributes:
          drp.add_component(
            Label(text=row[attribute['attr_name']]),
            column=column_id
          )
          column_id += 1

        return drp

    self.repeating_panel_1.item_template = TemplateRowFunc


Hope that helps

3 Likes