Am 25.06.2012 16:56, schrieb Alessandro Molina:
By the way, is anybody working on a TW2 version of the forms tutorial
(http://turbogears.org/2.1/docs/main/ToscaWidgets/forms.html) already? If
not, I'm volunteering to do it.

Should have been already updated in new doc
(http://turbogears-dev.readthedocs.org/en/latest/main/TwForms.html)
if you find anything wrong feel free to change it, it has been created
on TW2.0 and TW2.1 release might have changed something.

Oh, great. Hadnt' seen this yet. But the new tutorial does not cover as much ground as the old one, which explained various ways of displaying help texts, storing values and reading options with SQLAlchemy. The old one also had screen shots which is always important for newbies: You want to see how things should look like if you do everything right.

Yep, the current TG2.2 form documentation already has examples that
pass around the class itself.
In TW2 you are expected to always use the class of the widgets
wherever you used a widget instance before.
The class itself has the display staticmethod and so on.

We really need to elaborate on that in the docs. The TW2 tutorial recommends using an instance created with req(). The idea of TW2 is actually that you can change widget instances per request. If you pass only classes, you can't do that. Furthermore, passing parameters to widgets using child_args does not work any more in TW2, the only way to do that is to operate on the instance.

Here is a typical use case: How would you inject an options list dynamically in TW2? In our movie database example, assume that the "genre" options list depends on the user/request. As far as I understand, you must do it like this in TW2:

    @expose('.templates.new_form')
    def new(self, **kw):
        form = MovieForm.req()
        form.child.children.genre.options = enumerate([
            'Comedy', 'Drama', 'SciFi']) # something variable
        tmpl_context.form = form
        return dict(modelname='Movie', value=kw)

But then you run into the validation problem again: When the form is re-displayed as result of an error, the error messages won't show up.

One idea to solve this would be:

        if tmpl_context.form_errors:
            form = MovieForm
        else:
            form = MovieForm.req()
            form.child.children.genre.options = enumerate([
                'Comedy', 'Drama', 'SciFi'])
        tmpl_context.form = form

Now in case of an error, the request local instance created by the validation process will be picked up. That instance knows about the form values and errors, but it does not know about the genre.options. So in case of an error, the option list will not be populated-

The only proper workaround that comes to my mind is this one, which does not look very nice and accesses TW2 internal stuff:

        try:
            form = tw2.core.core.request_local()['validated_widget']
        except KeyError:
            form = MovieForm.req()
        form.child.children.genre.options = enumerate([
            'Comedy', 'Drama', 'SciFi'])
        tmpl_context.form = form

Do you have any better idea how to solve this use case? If not, I'll take this problem to the TW2 mailing list.

-- Christoph





--
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en.

Reply via email to