Luis Milanese
Luis Milanese

Reputation: 1286

How to empty a numeric value from a form built with WTForm

I have this small Flask program. It expects the name and age of the user, and then it prints a message. Really easy, for I'm just getting started with Python and Flask.

from flask import Flask, render_template
from flask.ext.bootstrap import Bootstrap 
from flask.ext.wtf import Form 
from wtforms import StringField, IntegerField, SubmitField
from wtforms.validators import Required, Length, NumberRange

app = Flask(__name__)
app.config['SECRET_KEY'] = 'top secret!'
bootstrap = Bootstrap(app)

class NameForm(Form):
    name = StringField('What is your name?', validators = [Required(), Length(1, 16)])
    age  = IntegerField('How old are you?', validators = [Required(), NumberRange(min=1, max=99, message="Should be between 1 and 99")])

    submit = SubmitField('Submit')

@app.route('/', methods=['GET', 'POST'])
def index():
    name = None
    age  = None
    form = NameForm()
    if form.validate_on_submit():
        name = form.name.data
        age  = form.age.data
        form.age.raw_data = None
        form.name.data = ''

    return render_template('index.html', form = form, name = name, age = age)

if __name__ == '__main__':
    app.run(debug = True)

And, for the HTML template, I have: {% extends "bootstrap/base.html" %}

{% block title %}Form Example{% endblock %}

{% block navbar %}
    <nav class="navbar navbar-inverse" role="navigation">
        <div class="container">
            <a href="{{ url_for('index') }}" class="navbar-brand">Hello</a>
        </div>
    </nav>
{% endblock %}

{% block content %}
    <div class="container">
        <form method="POST" action="">
            {{ form.name.label }} {{ form.name(size=16, class='name-field') }}
            {% for error in form.name.errors %}
                {{ error }}
            {% endfor %}

            <br>

            {{ form.age.label }} {{ form.age(class='age-field') }}
            {% for error in form.age.errors %}
                {{ error }}
            {% endfor %}

            <br />
            {{ form.submit() }}
            {{ form.hidden_tag() }}
        </form>
        {% if name %}
            <h1>Hello, {{ name.capitalize() }}</h1>
            <h2>You're {{ age }} years old.</h2>
        {% endif %}
    </div>
{% endblock %}

My question is, after I submit the form, the name input is emptied but the age input is not. Why? How can I empty a numeric field?

Thanks.

Upvotes: 4

Views: 2245

Answers (1)

Doobeh
Doobeh

Reputation: 9440

Thanks for the clear question-- the easiest way I can think of to blank the form is just to create it and tell it to ignore the request form data.

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()  # Auto-populates from request data.
    name = None
    age = None
    if form.validate_on_submit():
        name = form.name.data
        age  = form.age.data

        # Lets now create a form, but ignore the request data, so it's empty:
        form = NameForm(formdata=None)
    return render_template('index.html', form = form, name = name, age = age)

Also, I notice you're using Required() that's in the progress of being replaced by DataRequired() and will disappear in WTF v3 so you might want to start using it now, your future self will thank you!

Upvotes: 6

Related Questions