If this worked with TG1 it was pure luck that you didn't run into
concurrency issues. TW tries to lock-down widgets after instantiation
time. This obviously has it's limits, but in this case it caught the
"abuse".
By modifying widgets like that at runtime, you modified a single
instance which was used to render concurrent requests. If the load is
not to heavy, that works. If it ramps up, errors will creep in when two
requests modify the widget before it is rendered.
So, the answer is: it isn't possible, and it wasn't really a good idea
in TG1 as well :)
Now the question is: what kind of dynamic alterations did you actually
need? Can you please give an example of that, then we can think about a
conformant solution.
Diez
The below works for me - albeit I admit it is not really obvious.
And I haven't tested this with validation:
--------------------
import tw.api as tw
import tw.forms as twf
# takes a fields-parameter with one widget as element.
class ToggleWidget(twf.ContainerMixin, twf.FormField):
params = dict(enabled="Is the child widget enabled")
enabled = True
engine_name = "genshi"
template = """<div py:strip="True"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/" py:if="enabled"
>${display_child(fields[0])}</div>"""
form = twf.ListForm("form", fields=[
ToggleWidget("names", fields=
[twf.CheckBoxList("name", options=["Peter", "Paul",
"Mary"])]
),
ToggleWidget("pets", fields=
[twf.CheckBoxList("name", options=["Lassie", "Flipper"])]
),
])
print form.display(child_args=dict(names=dict(enabled=True,
child_args=dict(name=dict(options=["Foo", "Bar"]))),
pets=dict(enabled=False)
)
)
---------------------
A similar approach might work with your use-case #1
> So, I figure the solution here would be just to create a new form
> widget per request that initializes the fields it needs. Is there
> another route? It just seems like creating variable field forms
> shouldn't be so difficult; unless I'm not understanding something here
> and just need to arrive at the, doh! moment! with TW.
It will cause a memory-leak. This is because to fix a bug I had to
create a global registry that will hold a reference to every widget that
is created.
Instead, I would recommend that you create a widget that simply renders
the whole form. And that is parametrized by the values you need.
I will try and dig deeper into tw.forms to see if there isn't a better
option, but currently the best I can offer is the above widget.
Diez