Widgets are classes whose purpose are to render a field to its usable representation, usually XHTML. When a field is called, the default behaviour is to delegate the rendering to its widget. This abstraction is provided so that widgets can easily be created to customize the rendering of existing fields.

Note All built-in widgets will return upon rendering a “HTML-safe” unicode string subclass that many templating frameworks (Jinja2, Mako, Genshi) will recognize as not needing to be auto-escaped.

Built-in widgets

class wtforms.widgets.ListWidget(html_tag='ul', prefix_label=True)

Renders a list of fields as a ul or ol list.

This is used for fields which encapsulate many inner fields as subfields. The widget will try to iterate the field to get access to the subfields and call them to render them.

If prefix_label is set, the subfield’s label is printed before the field, otherwise afterwards. The latter is useful for iterating radios or checkboxes.

class wtforms.widgets.TableWidget(with_table_tag=True)

Renders a list of fields as a set of table rows with th/td pairs.

If with_table_tag is True, then an enclosing <table> is placed around the rows.

Hidden fields will not be displayed with a row, instead the field will be pushed into a subsequent table row to ensure XHTML validity. Hidden fields at the end of the field list will appear outside the table.

class wtforms.widgets.Input(input_type=None)

Render a basic <input> field.

This is used as the basis for most of the other input fields.

By default, the _value() method will be called upon the associated field to provide the value= HTML attribute.

class wtforms.widgets.TextInput

Render a single-line text input.

class wtforms.widgets.PasswordInput(hide_value=True)

Render a password input.

For security purposes, this field will not reproduce the value on a form submit by default. To have the value filled in, set hide_value to False.

class wtforms.widgets.HiddenInput

Render a hidden input.

class wtforms.widgets.CheckboxInput

Render a checkbox.

The checked HTML attribute is set if the field’s data is a non-false value.

class wtforms.widgets.FileInput

Renders a file input chooser field.

class wtforms.widgets.SubmitInput

Renders a submit button.

The field’s label is used as the text of the submit button instead of the data on the field.

class wtforms.widgets.TextArea

Renders a multi-line text area.

rows and cols ought to be passed as keyword args when rendering.

class wtforms.widgets.Select(multiple=False)

Renders a select field.

If multiple is True, then the size property should be specified on rendering to make the field useful.

The field must provide an iter_choices() method which the widget will call on rendering; this method must yield tuples of (value, label, selected).

Custom widgets

Widgets, much like validators, provide a simple callable contract. Widgets can take customization arguments through a constructor if needed as well. When the field is called or printed, it will call the widget with itself as the first argument and then any additional arguments passed to its caller as keywords. Passing the field is done so that one instance of a widget might be used across many field instances.

Let’s look at a widget which renders a text field with an additional class if there are errors:

class MyTextInput(TextInput):
    def __init__(self, error_class=u'has_errors'):
        super(MyTextInput, self).__init__()
        self.error_class = error_class

    def __call__(self, field, **kwargs):
        if field.errors:
            c = kwargs.pop('class', '') or kwargs.pop('class_', '')
            kwargs['class'] = u'%s %s' % (self.error_class, c)
        return super(MyTextInput, self).__call__(field, **kwargs)

In the above example, we extended the behavior of the existing TextInput widget to append a CSS class as needed. However, widgets need not extend from an existing widget, and indeed don’t even have to be a class. For example, here is a widget that renders a SelectMultipleField as a collection of checkboxes:

def select_multi_checkbox(field, ul_class='', **kwargs):
    kwargs.setdefault('type', 'checkbox')
    field_id = kwargs.pop('id', field.id)
    html = [u'<ul %s>' % html_params(id=field_id, class_=ul_class)]
    for value, label, checked in field.iter_choices():
        choice_id = u'%s-%s' % (field_id, value)
        options = dict(kwargs, name=field.name, value=value, id=choice_id)
        if checked:
            options['checked'] = 'checked'
        html.append(u'<li><input %s /> ' % html_params(**options))
        html.append(u'<label for="%s">%s</label></li>' % (field_id, label))
    return u''.join(html)