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 (Jinja, Mako, Genshi) will recognize as not needing to be auto-escaped.

Built-in widgets

class wtforms.widgets.ColorInput(input_type=None)[source]

Renders an input with type “color”.

class wtforms.widgets.CheckboxInput(input_type=None)[source]

Render a checkbox.

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

class wtforms.widgets.DateTimeInput(input_type=None)[source]

Renders an input with type “datetime”.

class wtforms.widgets.DateTimeLocalInput(input_type=None)[source]

Renders an input with type “datetime-local”.

class wtforms.widgets.DateInput(input_type=None)[source]

Renders an input with type “date”.

class wtforms.widgets.EmailInput(input_type=None)[source]

Renders an input with type “email”.

class wtforms.widgets.FileInput(multiple=False)[source]

Render a file chooser input.


multiple – allow choosing multiple files

class wtforms.widgets.HiddenInput(*args, **kwargs)[source]

Render a hidden input.

class wtforms.widgets.Input(input_type=None)[source]

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.ListWidget(html_tag='ul', prefix_label=True)[source]

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.MonthInput(input_type=None)[source]

Renders an input with type “month”.

class wtforms.widgets.NumberInput(step=None, min=None, max=None)[source]

Renders an input with type “number”.

class wtforms.widgets.PasswordInput(hide_value=True)[source]

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.RadioInput(input_type=None)[source]

Render a single radio button.

This widget is most commonly used in conjunction with ListWidget or some other listing, as singular radio buttons are not very useful.

class wtforms.widgets.RangeInput(step=None)[source]

Renders an input with type “range”.

class wtforms.widgets.SubmitInput(input_type=None)[source]

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.SearchInput(input_type=None)[source]

Renders an input with type “search”.

class wtforms.widgets.Select(multiple=False)[source]

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) or (value, label, selected, render_kw). It also must provide a has_groups() method which tells whether choices are divided into groups, and if they do, the field must have an iter_groups() method that yields tuples of (label, choices), where choices is a iterable of (value, label, selected) tuples.

class wtforms.widgets.TableWidget(with_table_tag=True)[source]

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.TelInput(input_type=None)[source]

Renders an input with type “tel”.

class wtforms.widgets.TextArea[source]

Renders a multi-line text area.

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

class wtforms.widgets.TextInput(input_type=None)[source]

Render a single-line text input.

class wtforms.widgets.TimeInput(input_type=None)[source]

Renders an input with type “time”.

class wtforms.widgets.URLInput(input_type=None)[source]

Renders an input with type “url”.

class wtforms.widgets.WeekInput(input_type=None)[source]

Renders an input with type “week”.

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- and aria- attributes, if the name of the attribute begins with data_ or aria_, then every underscore will be replaced with a hyphen in the generated attribute.

>>> html_params(data_attr='user.name', aria_labeledby='name')
'data-attr="user.name" aria-labeledby="name"'
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"'

Changed in version 3.0: aria_ args convert underscores to hyphens like data_ args.

Changed in version 2.2: data_ args convert all underscores to hyphens, instead of only the first one.

WTForms uses MarkupSafe to escape unsafe HTML characters before rendering. You can mark a string using markupsafe.Markup to indicate that it should not be escaped.

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='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'] = '%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 = ['<ul %s>' % html_params(id=field_id, class_=ul_class)]
    for value, label, checked, render_kw in field.iter_choices():
        choice_id = '%s-%s' % (field_id, value)
        options = dict(kwargs, name=field.name, value=value, id=choice_id)
        if checked:
            options['checked'] = 'checked'
        html.append('<li><input %s /> ' % html_params(**options))
        html.append('<label for="%s">%s</label></li>' % (choice_id, label))
    return ''.join(html)

class TestForm(Form):
    tester = SelectMultipleField(choices=my_choices, widget=select_multi_checkbox)