Closed lordenaar closed 5 years ago
Here is an example of an interview that shows a table of a list, where the list is embedded in a dictionary.
objects:
- food: DADict.using(there_are_any=True)
- food[i]: DAList.using(there_are_any=True)
---
question: |
Give me a type of food.
fields:
Type of food: food.new_item_name
---
table: food[i].table
rows: food[i]
columns:
- "#": row_index
- "Type of ${ i }": row_item
delete buttons: True
---
question: |
Give me the ${ ordinal(j) } ${ i }.
fields:
- "Name of a ${ i }": food[i][j]
---
question: |
Are there any more ${ i } you would like to mention?
yesno: food[i].there_is_another
---
question: |
Are there any more food types you would like to mention?
yesno: food.there_is_another
---
question: |
What type of food would you like to review?
field: food_type
choices:
code: |
food.keys()
---
mandatory: True
question: |
Summary of ${ food_type }
subquestion: |
${ food[food_type].table }
${ food[food_type].add_action() }
i
is a special variable, so you cannot set it yourself. You will run into problems if you try to set it yourself. It is set and reset internally by the group-gathering system.
When a DAObject
is initialized, it needs to be initialized in such a way that it is aware of its own variable name. If it does not know its name, or it knows the wrong name, systems like list-gathering and question
-asking when there is an undefined name will not work. Python is a very good general-purpose programming language but it does not have a feature for variables being self-aware of their own names. Thus I had to hack it a bit and use an attribute called instanceName
to store the variable name, and then trap all of the AttributeError
, NameError
, and IndexError
exceptions
In your first example, you had:
example_dict['exlist'] = DAList()
There is some very ugly code that is run when Python does DAList()
that attempts to figure out what is on the left side of the equals sign. However, this code is not reliable and it can get confused in certain contexts and by certain variable types. To be safe you should write:
example_dict['exlist'] = DAList("example_dict['exlist']")
(The first parameter to every object initializer is the instanceName
.)
It may work in some contexts to nest a DAList
inside of an ordinary Python dict
, if you can set the instanceName
appropriately. But in other contexts you might run into problems because docassemble's dependency satisfaction system and group gathering systems depend on objects being DAObject
s, which have special properties.
I always initialize objects using the objects
block, which takes care of setting the instanceName
.
When a DAList is contained within a dictionary, the standard list gathering does not work. We tried a range of options to get a similar concept to work, but it seems like DA can potentially not 'find' the name of a DAList if it is contained within a dictionary, DADict or python dictionary regardless (the error is often, 'instanceName is not defined', despite the instance name existing in the developer variables and values view).
This example below uses the standard DA addition and removal methods, and crashes on run:
We can instead add a custom addition function, which works, but the DA table delete button will then not work: (Throwing the name error as discussed above, despite the name being findable inside the variables and values log)
To handle this situation, should we just create custom add and delete buttons ourselves?