Warn user of validation error before they click submit

hi all,

so ive done a flask-wtf form but instead of warning users after they click the “submit button” i want it to warn them before ie as soon as they click out of a box to show them the error, heres my code

from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, DecimalField, RadioField, SelectField, TextAreaField, FileField, SubmitField
from wtforms.validators import InputRequired, Length, DataRequired, EqualTo, Regexp, ValidationError

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secretkey'


class PasswordForm(FlaskForm):
    un = StringField('Username', [InputRequired(message='please enter your Username')])
    op = PasswordField('Old Password', [InputRequired(message='please enter your current password')])
    np = PasswordField('New Password', [InputRequired(message='please enter your new password'), EqualTo('cnp', message='must match confirm new password'), Length(min=12)])
    cnp = PasswordField('Confirm New Password')
    dom = SelectField('domain', choices=[('prod', 'prod'), ('corp', 'corp')])
    
@app.route('/password', methods=['GET', 'POST'])
def password():
    form = PasswordForm()
    if request.method == 'POST' and form.validate():
        return "form submitted successfully"
    return render_template('password.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)
{% block content %}
    <h1>Change Password</h1>
    <form method="post" novalidate>
		{{form.hidden_tag()}}
		
		<p>{{ form.un.label }}</p>
		<p>{{ form.un}}</p>
		
		{% if form.un.errors %}
		<ul>
			{% for error in form.un.errors %}
			<li>
				{{error}}
			</li>
			{% endfor %}
		</ul>
		{% endif %}
		
		<p>{{ form.op.label }}</p>
		<p>{{ form.op}}</p>
		
		{% if form.op.errors %}
		<ul>
			{% for error in form.op.errors %}
			<li>
				{{error}}
			</li>
			{% endfor %}
		</ul>
		{% endif %}
		
		<p>{{ form.np.label }}</p>
		<p>{{ form.np}}</p>
		
		{% if form.np.errors %}
		<ul>
			{% for error in form.np.errors %}
			<li>
				{{error}}
			</li>
			{% endfor %}
		</ul>
		{% endif %}
		
		<p>{{ form.cnp.label }}</p>
		<p>{{ form.cnp}}</p>
		
		{% if form.cnp.errors %}
		<ul>
			{% for error in form.cnp.errors %}
			<li>
				{{error}}
			</li>
			{% endfor %}
		</ul>
		{% endif %}
		
		<p>{{ form.dom.label }}</p>
		<p>{{ form.dom}}</p>
		
		<input type="submit" value="Submit">
    </form>
{%endblock%}

thanks,
rob

Hi Rob,

What you want is “client side validation”. You will need to add JavaScript in order to do this. I am not personally familiar with wtforms - it’s possible it has some helpers for this? Otherwise, the general approach is to add event listeners to your form fields for the “on blur” event, which is the event that is triggered when focus leaves a form field.

I would check the docs for wtform to see if they have any support for client side validation. If not, search for JavaScript examples and libraries for client side validation. (Technically no extra libraries are required, but it can be tedious to write all the listeners and validators by hand.)

Although before reaching for JavaScript, it’s worth checking to see if you can define the validation rules in a way that the browser itself can comprehend.

2 Likes