Getting text from data table and providing check box options for each item

I am trying to build an app that asks respondents for certain outputs (from their projects) which I have now stored in a data table. This is done already.

For each of those outputs they now need to be asked for where they expect these outputs to make an impact. That is, I need to get all outputs from the table and provide 6 checkboxes underneath each output.

Lastly, for each of those checkboxes a new variable in the data table needs to be created and the check needs to be associated with the corresponding output.

My code for the page so far looks like this:

class Page2(Page2Template):
  def __init__(self, **properties):
    self.init_components(**properties)
    length_resp=len(app_tables.responses.search())
    for i in range(length_resp):
      self.item = app_tables.responses.search()[i]
  
  def button_1_click(self, **event_args):
    #needs to save information in the data table
    open_form('Page3')

So far I only get the last row from the data table and built the checkboxes through the UI, but I guess since beforehand I don’t know how many outputs there will be, this needs to be dynamic and built through code instead…

Thanks a lot in advance for any hints!

Best,
Julian

Using a repeating panel would probably work the best. The reason you’re only getting the last row is because you reset the item attr every loop and so at the end it is only the last row that remains. This isn’t a problem if you use a repeating panels and then set the items attribute to the return value of the server call

Hey Duncan,

Could you please be more precise on the repeating panel and perhaps suggest some code?

Drop a repeating panels in the form you want the components, then you put whatever components you want in each row in the template form that’s generated. Then, set the items of the repeating panels like this:

self.repeating_panel.items = app_tables.responses.search()

Then each row that’s returned is the item attribute of the template form that populates the repeating panels.

You can access that item in the template form like a dict to set the text/values of it’s components:

self.some_label.text = self.item["some_column"]

Here you are executing one search to count the lines, then you are executing the same search again to get the first item, then you are executing the same search again to get the second item, etc.

This code will be very slow, and become unusable when your search returns more than a handful of items.

A better way is to do the search only once, and not to count your items at all:

    for item in app_tables.responses.search():
      self.item = item

And now you have fast code, but you still have your original problem: you keep assigning each item returned by the search to the same variable self.item, so at the end self.item has the value of the last item.

Using a repeating panel as suggested by @duncan_richards12 would assign all the items returned by the search to the items (notice the “s”) member of the repeating panel. Then the repeating panel would take care of creating one instance of its template form for each item in its items, and assign that item to that instance item (notice no “s”). Notice that the repeating panel has items, plural, while the template form has item singular. Each item of the repeating panel is assigned to one instance of its template form.

Here is the summary of what happens (this is not code you need to write, this is just a summary of what happens under the hood):

  • the main form contains a repeating panel
  • the main form does a search and gets all the items (1)
  • the main form assigns the stuff returned by the search to the repeating panel (2)
  • the repeating panel iterates it (3) and:
    • creates one instance of its template form (4)
    • adds it to itself (5)
    • assigns the item it’s iterating to its template form (6)
1  stuff = items = app_tables.responses.search()
2  self.repeating_panel.items = stuff
3  for thing in stuff:
4      form = Template()
5      self.repeating_panel.add_component(form)
6      form.item = thing

Hey,

first of all thanks a lot for the response!

I have managed to solve the issue using a similar approach to the one you suggested. However I now struggle to add the check box and radio button content to my data table. That is, while I can create the buttons and check boxes I get errors when trying to use data bindings as suggested in the existing tutorials…

Please find attached a copy of my project: