Widgets¶
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]¶
Render an <input type=”color”>.
- class wtforms.widgets.Button(input_type=None)[source]¶
Render a
<button>element.Pass
label=when rendering to override the visible button text. The label is HTML-escaped; pass amarkupsafe.Markupinstance to embed HTML (icons, formatted text) in the button content.
- class wtforms.widgets.CheckboxInput(input_type=None)[source]¶
Render an <input type=”checkbox”>.
The
checkedHTML attribute is set if the field’s data is a non-false value.
- class wtforms.widgets.DateTimeInput(input_type=None)[source]¶
Render an
<input type="datetime">control.This is a legacy HTML input type. For modern browser support, prefer
DateTimeLocalInput.
- class wtforms.widgets.DateTimeLocalInput(input_type=None)[source]¶
Render an <input type=”datetime-local”>.
- class wtforms.widgets.DateInput(input_type=None)[source]¶
Render a <input type=”date”>.
- class wtforms.widgets.EmailInput(input_type=None)[source]¶
Render an <input type=”email”>.
- class wtforms.widgets.FileInput(multiple=False)[source]¶
Render an <input type=”file”>.
- Parameters:
multiple – allow choosing multiple files
- class wtforms.widgets.HiddenInput(*args, **kwargs)[source]¶
Render an <input type=”hidden”>.
- 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]¶
Render a list of fields as a <ul> or <ol>.
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]¶
Render an <input type=”month”>.
- class wtforms.widgets.NumberInput(step=None, min=None, max=None)[source]¶
Render an <input type=”number”>.
- class wtforms.widgets.PasswordInput(hide_value=True)[source]¶
Render an <input type=”password”>.
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 <input type=”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, min=None, max=None)[source]¶
Render an <input type=”range”>.
- class wtforms.widgets.SubmitInput(input_type=None)[source]¶
Renders an <input type=”submit”>.
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]¶
Render an <input 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
Choice.
- class wtforms.widgets.TableWidget(with_table_tag=True)[source]¶
Render a list of fields as a <table>.
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]¶
Render an <input type=”tel”>.
- class wtforms.widgets.TextArea[source]¶
Renders a multi-line <textarea>.
rows and cols ought to be passed as keyword args when rendering.
- class wtforms.widgets.TextInput(input_type=None)[source]¶
Render a single-line <input type=”text”>.
- class wtforms.widgets.TimeInput(input_type=None)[source]¶
Render a <input type=”time”>.
- class wtforms.widgets.URLInput(input_type=None)[source]¶
Render an <input type=”url”>.
- class wtforms.widgets.WeekInput(input_type=None)[source]¶
Render an <input 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.
- wtforms.widgets.html_params(**kwargs)[source]¶
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-andaria-attributes, if the name of the attribute begins withdata_oraria_, 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
TrueandFalseare special: attr=Truegenerates the HTML compact output of a boolean attribute, e.g.checked=Truewill generate simplycheckedattr=Falsewill 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"'
Changelog
Changed in version 3.0:
aria_args convert underscores to hyphens likedata_args.Changed in version 2.2:
data_args convert all underscores to hyphens, instead of only the first one.- In addition, the values
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.
The widget contract¶
A widget is any callable with the signature widget(field, **kwargs) that
returns the rendered HTML. The return value should be a
markupsafe.Markup instance; otherwise templating engines with
autoescape enabled will escape the markup and the user will see the raw HTML
tags instead of the rendered widget.
Inside the widget, the following field attributes are commonly used:
field.idandfield.name— the renderedid/nameattributes.field.label— aLabelinstance, callable to render a<label>tag.field.errors— list of validation errors afterform.validate().field._value()— the string representation of the current value, used for thevalue=attribute of inputs.field.iter_choices()— forSelectFieldand similar; yieldsChoiceobjects withvalue,label,selectedandrender_kw.
To assemble the HTML, use html_params() for attribute
strings, markupsafe.Markup to mark the result as safe, and
markupsafe.escape() for any user-supplied content interpolated into the
HTML:
from markupsafe import Markup, escape
from wtforms.widgets import html_params
Subclassing a built-in widget¶
The lightest customization is to extend an existing widget and post-process its output or its kwargs. Here is a widget that renders a text field with an extra CSS class when the field has errors:
class MyTextInput(TextInput):
def __init__(self, error_class='has_errors'):
super().__init__()
self.error_class = error_class
def __call__(self, field, **kwargs):
if field.errors:
existing = kwargs.pop('class', '') or kwargs.pop('class_', '')
kwargs['class'] = f'{self.error_class} {existing}'.strip()
return super().__call__(field, **kwargs)
Writing a widget from scratch¶
A widget does not have to be a class — any callable will do. Here is a widget
that renders a SelectMultipleField as a collection of
<input type=”checkbox”> controls:
from markupsafe import Markup, escape
from wtforms.widgets import html_params
def select_multi_checkbox(field, ul_class='', **kwargs):
kwargs.setdefault('type', 'checkbox')
field_id = kwargs.pop('id', field.id)
html = [f'<ul {html_params(id=field_id, class_=ul_class)}>']
for choice in field.iter_choices():
choice_id = f'{field_id}-{choice.value}'
options = dict(
kwargs,
name=field.name,
value=choice.value,
id=choice_id,
checked=choice._selected,
)
html.append(f'<li><input {html_params(**options)}> ')
html.append(f'<label for="{choice_id}">{escape(choice.label)}</label></li>')
html.append('</ul>')
return Markup(''.join(html))
class TestForm(Form):
tester = SelectMultipleField(choices=my_choices, widget=select_multi_checkbox)
widget versus option_widget¶
For fields that wrap a collection of options (such as
SelectField, RadioField and
their multiple-choice variants), two extension points exist:
widgetrenders the whole field at once (the<select>element, the<ul>of radios, etc.).option_widgetrenders a single option when the field is iterated. This is useful when you want to keep the default container but change how each option is displayed. See Solving Specific Problems for an example usingListWidgettogether withCheckboxInputas theoption_widget.