Skip to content

multistep forms

pkirlin edited this page Oct 11, 2016 · 7 revisions

Multistep forms - in two different ways!

In the previous section, you saw how to use hidden variables to save application state (basically, variables) across multiple webpage requests and responses. Now, we will use our new knowledge to re-write our random number generator using a multistep form. In other words, we will have one page that asks for the lower limit, then a separate page that asks for the upper limit, then a third page that generates the random number. In the real world, there's no particular reason to break it up this way, but you will see a new technique to manage what "step" of the form you are on.

When creating multistep forms, one way to break up the steps is to have a different route and/or HTML template for each step. Try making three HTML templates:

random1.html

<html>
  <head>
    <title>Random</title>
  </head>
<body>
  <h1>Random numbers are fun!</h1>  
  <form action="{{ url_for('random2') }}" method="post">
  Pick a lower limit: <input type="text" name="lowerlim"><br>
  <input type="submit" value="Next">
  </form>
</body>
</html>

random2.html

<html>
  <head>
    <title>Random</title>
  </head>
<body>
  <h1>Random numbers are fun!</h1>  
  <form action="{{ url_for('random3') }}" method="post">
  Thanks, you picked {{low}}.<br>
  Pick an upper limit: <input type="text" name="upperlim"><br>
  <input type="hidden" name="lowerlim" value="{{low}}">
  <input type="submit" value="Generate">
  </form>
</body>
</html>

random3.html

<html>
  <head>
    <title>Random</title>
  </head>
<body>
  <h1>Random numbers are fun!</h1>  
  Your random number is: {{number}}.<br>
</body>
</html>

Notice how instead of having a single HTML template handling all of the logic, we now have three templates, one for each step of the process:

  • random1.html displays the form for getting the lower limit. The form uses url_for to pass the submitted information to the random2 route in Flask.
  • random2.html displays the form for getting the upper limit, along with confirmation of the lower limit. Similarly to the previous page, the form passes the information along to the random3 route.
  • random3.html displays the final generated number

Now let's look at the Flask app:

from flask import Flask, render_template, request
import random
app = Flask(__name__)

@app.route('/')
def hello_world():
  return 'Hello, World!'
    
@app.route("/random", methods=['get', 'post'])
def random1():
  return render_template("random1.html")

@app.route("/random2", methods=['get', 'post'])
def random2():
  lower = int(request.form['lowerlim'])
  return render_template("random2.html", low=lower)

@app.route("/random3", methods=['get', 'post'])
def random3():
  print(request.form)
  lower = int(request.form['lowerlim'])
  upper = int(request.form['upperlim'])
  n = random.randint(lower, upper + 1)
  return render_template("random3.html", number=n)
  • Notice how the Flask routes are synchronized with both their corresponding function names and the HTML templates that generate them. This can be handy to keep everything straight. The one place the names are not synchronized is in the HTML templates themselves (see above) --- you will notice that random1.html passes the form information to random2.html which passes it to random3.html.

Use the main wiki page to navigate, not the list of pages directly above, because those are out of order.

Clone this wiki locally