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

Render a file chooser input.

Parameters:multiple – allow choosing multiple files
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).

Widget-Building Utilities

These utilities are used in WTForms widgets to help render HTML and also in order to work along with HTML templating frameworks. They can be imported for use in building custom widgets as well.


Generate HTML attribute syntax from inputted keyword arguments.

The output value is sorted by the passed keys, to provide consistent output each time this function is called with the same parameters. Because of the frequent use of the normally reserved keywords class and for, suffixing these with an underscore will allow them to be used.

In order to facilitate the use of data- attributes, the first underscore behind the data-element is replaced with a hyphen.

>>> html_params(data_any_attribute='something')
In addition, the values True and False are special:
  • attr=True generates the HTML compact output of a boolean attribute, e.g. checked=True will generate simply checked
  • attr=False will be ignored and generate no output.
>>> html_params(name='text1', id='f', class_='text')
'class="text" id="f" name="text1"'
>>> html_params(checked=True, readonly=False, name="text1", abc="hello")
'abc="hello" checked name="text1"'
class wtforms.widgets.HTMLString

This is an “HTML safe string” class that is returned by WTForms widgets.

For the most part, HTMLString acts like a normal unicode string, except in that it has a __html__ method. This method is invoked by a compatible auto-escaping HTML framework to get the HTML-safe version of a string.


HTMLString('<input type="text" value="hello">')

Give an HTML-safe string.

This method actually returns itself, because it’s assumed that whatever you give to HTMLString is a string with any unsafe values already escaped. This lets auto-escaping template frameworks know that this string is safe for HTML rendering.

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)