Section 16.3. Compound Widgets


16.3. Compound Widgets

The form widget is made up of references to other widgets, and it's the most common case for one widget containing another, but there are lots of other cases where one widget contains another. We've already seen that the WhatWhat Status project has a NotesWidget that displays all the notes for a particular project, by calling the note_widget to display each individual project note.

So, rather than keeping all of the logic for maintaining Compound Widgets in the Form itself, the TurboGears widgets package maintains an abstract base class for Compound Widgets.

Having a CompoundWidget base class means that you can create your own Compound Widgets through subclassing. Here's the NotesWidget from the WhatWhat Status project:

class NotesWidget(CompoundWidget):     template        = 'whatwhat.widgets.templates.notes'     params          = ['notes', 'read_only']     member_widgets  = ['note_widget'     note_widget     = note_widget     read_only       = False


The member_widgets declaration is the key element that is specific to a CompoundWidget. The NotesWidget contains note_widgets.

In addition to the standard CompoundWidget, TurboGears also provides a CompoundFormField that can make your life easier when you want to create a set of form fields that are grouped together for some reason.

One popular example might be a form that allows you to type in the first portion of an email address and then select the remainder from a drop down list. If you don't understand the initialization setup, feel free to skip over it for the moment; we'll come back to it and explain what's happening in section 16.6, "Creating Custom Widgets."

class CompoundEmailField(CompoundFormField):     member_widgets = ["usename", "domain"]     template = """     <div xmlns:py="http://purl.org/kid/ns#" >         ${display_field_for(username)}         ${display_field_for(domain)}     </div>     """     def __init__(self, tfield_params={}, sel_params={}, *args, **kw):         # Call super to set params and bind them to the proper         # widget instance         super(CompoundEmailField, self).__init__(*args, **kw)         # initialize the username and domain child widgets         self.username = TextField("username", **tfield_params)         sel_params.setdefault('validator', validators.Int())         self.domain = SingleSelectField("domain",                                          validator=validators.Int(),                                          **sel_params)


As you can see, CompoundFormField templates can use the same display_field_for function that we used earlier when creating a custom form. This makes designing and styling compound form field widgets pretty easy. The above example is pretty simple, but you can easily see how it could be expanded to separate large forms, into separate reusable sub-forms.

If you aren't expecting to use your widgets in a form, you won't need all the validation bells and whistles of the CompoundFormField, so you'll be better off using the standard CompoundFieldWidget. And that brings us to our next topicValidation.




Rapid Web Applications with TurboGears(c) Using Python to Create Ajax-Powered Sites
Rapid Web Applications with TurboGears: Using Python to Create Ajax-Powered Sites
ISBN: 0132433885
EAN: 2147483647
Year: 2006
Pages: 202

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net