I'm new to WTForms, and from what I've learned so far, I find the validation error handling a bit tricky.
First off, I can't implement the native HTML <input required >
;
Secondly, when the form failed validation, I have to rerender the page template where the form is at, and if my form is placed on bottom of a page, the user will see the page 'refreshed' and have no idea what is going on.
Does anyone have suggestions on how to integrate WTForms more seamlessly? Any comments, resources, urls, code samples are welcomed, thanks!
Here are some of my related codes:
# /forms.py
from wtforms import Form, BooleanField, StringField, PasswordField, validators
class RegistrationForm(Form):
email = StringField('Email Address', [
validators.required(),
validators.Email(message='Please enter a valid email address'),
validators.length(min=6, max=35)
])
password = PasswordField('New Password', [
validators.required(),
validators.DataRequired(),
validators.length(min=6, max=35)
])
# /views.py
from flask import Flask, Blueprint, flash, render_template, redirect, request, url_for
from forms import RegistrationForm, LoginForm
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
form = RegistrationForm()
context = {
"form": form
}
if request.method == 'POST' and form.validate():
submitted_form = request.form
return redirect('/welcome')
else:
return render_template('form.html', context = context)
# /form.html
<form class="form" action="" method="POST" name="register">
{% for field_name, field_errors in context.reg_form.errors|dictsort if field_errors %}
{% for err in field_errors %}
<li class="error">{{ context.reg_form[field_name].label }}: {{ err }}</li>
{% endfor %}
{% endfor %}
<ul class="form-fields center">
<li class="form-field">
{{ context.form.email(class='email', placeholder='email') }}
</li>
<li class="form-field">
{{ context.form.password(class='password', placeholder='password') }}
</li>
</ul>
</form>
As far as I understand, WTForm will always have to refresh the page in order to show the errors. I worked this out is by letting the front-end to validate the form for me. Do not know if it possible on your case, but I've used AngularJS to do the trick. It's quite easy, not a single line of code is required if you need simple validation like email format, password length and etc, it's all done by html attributes. You can even disable the submit button until your form is ready to go. Check out this CodePen
You can scroll to the bottom to the page using this, if still needed:
If you need a more robust solution, you might come up with a API that return true or false to whatever field you want to validate. Then make angular make a http request to check it as you type, this way you are 100% sure you form is going to validate. But depending on what you are checking, you might expose a security hole. There is an excellent blog post about this on Ng-Newsletter