Widget Adapter

Captured

None

Code (show in context)

    @view_config(renderer='templates/form.pt', name='widget_adapter')
    @demonstrate('Widget Adapter')
    def widget_adapter(self):
        # Formish allows you to pair a widget against a type that
        # doesn't "natively" lend itself to being representible by the
        # widget; for example, it allows you to use a text area widget
        # against a sequence type.  To provide this feature, Formish
        # uses an adapter to convert the sequence data to text during
        # serialization and from text back to a sequence during
        # deserialization.
        #
        # Deform doesn't have such a feature out of the box.  This is
        # on purpose: the feature is really too complicated and
        # magical for civilians.  However, if you really want or need
        # it, you can add yourself as necessary using an adapter
        # pattern.
        #
        # In the demo method below, we adapt a "normal" text area
        # widget for use against a sequence.  The resulting browser UI
        # is the same as if we had used a TextAreaCSVWidget against
        # the sequence as in the "textareacsv" test method.
        #
        # N.B.: we haven't automated the lookup of the widget adapter
        # based on the type of the field and the type of the widget.
        # Instead, we just construct an adapter manually.  Adding an
        # abstraction to the lookup based on the widget and schema
        # types being adapted is easy enough, but trying to follow the
        # codepath of the abstraction becomes brainbending.
        # Therefore, we don't bother to show it.
        class Row(colander.TupleSchema):
            first = colander.SchemaNode(colander.Integer())
            second = colander.SchemaNode(colander.String())
            third = colander.SchemaNode(colander.Decimal())
        class Rows(colander.SequenceSchema):
            row = Row()
        class Schema(colander.Schema):
            csv = Rows()
        schema = Schema()
        form = deform.Form(schema, buttons=('submit',))
        inner_widget = deform.widget.TextAreaWidget(rows=10, cols=60)
        widget = SequenceToTextWidgetAdapter(inner_widget)
        form['csv'].widget = widget
        appstruct = {'csv':[ (1, 'hello', 4.5), (2, 'goodbye', 5.5) ]}
        return self.render_form(form, appstruct=appstruct)