I load an external dictionary of information via an API & I would like to modify existing fields dynamically. However I find myself repeating code. In the below example you’ll notice the code repeating 3 times.
For every instance, it checks if a relevant field is disabled, and if so, makes it invisible.
If it is Required, it changes the background color. Or else it assures that it is visible & that the background color is white.
The problem is that this quickly gets overwhelming. As I add new traits it becomes impossible to manage. Is there a way to access all of the components by passing a dictionary? Or even if I have to reference each field individually could I do the work in dictionary form & just pass the finalized dictionary rather than addressing each trait of that component inline?
for row in self.CONFIG['report_data']['report_list']:
if row['Name'] == new_report:
new_report_data = row
break
if new_report_data.get('days_older_than','Disabled') != 'Disabled':
self.text_days_older_than.visible = True
if new_report_data.get('days_older_than','Required') == 'Required':
self.text_days_older_than.background = "#d0f1fe"
else:
self.text_days_older_than.background = "white"
else:
self.text_days_older_than.visible = False
if new_report_data.get('template_id','Disabled') != 'Disabled':
self.drop_down_template_id.visible = True
if new_report_data.get('template_id','Required') == 'Required':
self.drop_down_template_id.background = "#d0f1fe"
else:
self.text_days_older_than.background = "white"
else:
self.drop_down_template_id.visible = False
if new_report_data.get('min_qty','Disabled') != 'Disabled':
self.text_min_qty.visible = True
if new_report_data.get('min_qty','Required') == 'Required':
self.text_min_qty.background = "#d0f1fe"
else:
self.text_days_older_than.background = "white"
else:
self.text_min_qty.visible = False
I do get your point. The code that I’ve displayed isn’t great. Given your suggestion it would look like this. And I agree that it would be less ugly. But it still leaves me writing one function for each trait (visible/background/etc) and manually mapping it to each field.
If it is not possible to do it otherwise in Anvil, then that’s the approach I will take. but I don’t want to misinterpret your response. Are you saying that it is not possible to update fields with a single dictionary?
for row in self.CONFIG['report_data']['report_list']:
if row['Name'] == new_report:
new_report_data = row
break
self.text_days_older_than.visible = someFunctionForVisible()
self.text_days_older_than.background = someFunctionForBackground()
self.drop_down_template_id.visible = someFunctionForVisible()
self.drop_down_template_id.background = someFunctionForBackground()
self.text_min_qty.visible = someFunctionForVisible()
self.text_min_qty.background = someFunctionForBackground()
I was actually thinking that you would pass the components themselves into the function. You can test for their type or pass in another variable that indicates the information you need so that you can deal with them accordingly.
You could even put them all into a list (or dict) and pass that structure to the general function (and loop through the structure as needed).
Oh, and yes, you can update properties with a dictionary (although that alone wouldn’t solve the duplication issue completley from what I can tell). Like so:
Oh, and yes, you can update properties with a dictionary (although that alone wouldn’t solve the duplication issue completley from what I can tell). Like so:
I also thought that this would work, however I get an error message stating the following. It is apparently trying to create new fields rather than update existing ones.
AttributeError: Cannot set attribute ‘text_box’ on ‘Report’ form. There is already a component with this name.
For my purposes, creating entirely new fields dynamically would be even better than enabling hidden fields. However, I am not clear on how to do this. It seems they are being created somewhere, but nowhere that I can see.
I’m a python novice but would be tempted to try some combination of a eval() with a ternary expression for each new_report_data.get(‘key’,'value) (if I understand correctly). Then maybe it can be table driven so each field can have an expression to evaluate as a set of update/formatting rules.
Hi @dev01, here is the link to create component dymatically:
You can add a component by creating an instance of the component class (e.g. calling `Button()` ), and then calling `add_component()` on a container to add it to your page. For example:
self.button_1 = Button(text="Click me")
self.content_panel.add_component(self.button_1)
Good luck @dev01 , I struggle to find that information in the first place as well.
If you have further issue, please feel free to reply or post another topic