Reputation: 781
I am trying to create a dynamic form (within a python Flask application) using WTForms.
WTForms includes a FieldList field for lists of fields. I'd like to use this to make a form where users can add or remove items, e.g. specify different phone numbers.
Here is an example of a WTF solution using Ajax with WTForms and related question. These clone an existing form, and hence only work if there is at least one instance of the form already. I would like to remove this constraint to also allow an initially empty form.
I would like to use a javascript form plugin called SheepIt to dynamically add/remove widgets which does allow this, using a "form template" in the html.
Question is how to replace custom html in the "form template" such as:
<input id="phoneForm_#index#_number"
name="user[phones][#index#][number]" type="text"
with a WTF form field such as:
{% for phone in form.phones %}
{{ phone.number }}
{% endfor %}
that allows the WTF goodies such as printing of form validation errors, etc. Problem here is I do not know if/where to place the above for loop when using a "template form" as done in SheepIt.
Upvotes: 3
Views: 3413
Reputation: 708
Flask's documentation suggests the following jinja2 macro for rendering WTForms fields:
{% macro render_field(field) %}
<dt>{{ field.label }}
<dd>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endmacro %}
To render subfields in a fieldlist, I use a slightly different version of this macro:
{% macro render_multi_field(field,field_name) %}
<div class="form-group">
{{ field_name }}
{% for subfield in field %}
<div class="base_class{% if subfield.errors %} error_class{% endif %}" id="{{subfield.name}}-group">
{{ subfield(**kwargs)|safe }}
<button data-field="{{ subfield.name }}-group">Remove Entry</button>
</div>
{% if subfield.errors %}
{% for error in subfield.errors %}
<p class="error_class">{{ error }}</p>
{% endfor %}
{% endif %}
{% endfor %}
<br/>
<button type="button">Add entry</button>
</div>
{% endmacro %}
I use this macro to render Fields with 0 to any number of entries. It allows error rendering, populating with default values and anything else you'd do with WTForms.
In my case, widgets are added / removed by javascript via the button in the macro.
Upvotes: 2