Skip to content

hidden values

pkirlin edited this page Oct 11, 2016 · 11 revisions

Maintaining state with hidden fields in forms

It is common to need to break a form up into multiple pieces from time-to-time. This is often done when the second page of the form depends on information submitted on the first page. For example, consider the schedule of classes that BannerWeb displays. The first form asks you to pick a semester, then you hit submit, then the next page asks for the department to list classes for, then you hit submit again, then you get a list of classes for that semester and department combination.

Here is the exchange of information between browser (the client) and the server:

Client                                                       Server
===================================================================

Client requests schedule of classes ----------------------->

        <-----------  Server sends back list of possible semesters,
                                         including blank HTML form.

Client fills out form (drop down of 
semester) and sends to server   ---------------------------->

         <----------  Server reads semester variable from form, 
                      sends list of departments for that semester.

Client picks from list of departments,
but when they submit the form, how do
they send the semester again?  The server
has forgotten it!  ----------------------------------------->

                      Server needs to know both semester and 
                      department here.

One solution to this problem is to have the server, in its first response to the client, send not only the list of departments back to the client, but also the semester that the client chose. Remember, both the client and server are very forgetful, so the client has already forgotten what semester was picked in the previous step. The server can remind them explicitly, however. This is done by having the server, when it generates the HTML form for the list of departments, also include a hidden field in the HTML form that includes the name of the semester. Hidden fields are invisible to the user of the website but they are submitted just like regular fields.

Sample use, part 1.

Try this code, which uses hidden fields to allow the user to resubmit the random number generator as many times in a row as they want, using the same values. Note that you don't need any changes to your Python code, only the HTML code.

<html>
  <head>
    <title>Random</title>
  </head>
<body>
  <h1>Random numbers are fun!</h1>
  <form action="{{ url_for('pick_number') }}" method="post">

  {% if number is not defined %}
    Pick a lower limit: <input type="text" name="lowerlim"><br>
    Pick an upper limit: <input type="text" name="upperlim"><br>
    <input type="submit" value="Generate Number">
  {% else %}
    Your random number is: {{number}}.<br>
    As a reminder, your desired range was [{{low}}, {{high}}].<br>
    <input type="submit" value="Generate another number with same range.">
    <input type="hidden" name="lowerlim" value="{{low}}">
    <input type="hidden" name="upperlim" value="{{high}}">
  {% endif %}

  </form>
</body>
</html>
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 pick_number():
  if "upperlim" not in request.form:
    return render_template("random.html")
  else:
    upper = int(request.form['upperlim'])
    lower = int(request.form['lowerlim'])
    n = random.randint(lower, upper + 1)
    return render_template("random.html", number=n, low=lower, high=upper)

Make sure you understand this code before continuing below.

You try it

Modify the code above so whenever a random number is generated, it also tells you how many times you have generated a number with those upper/lower limits in a row. In other words, when the user first comes to the webpage, they should be able to enter their upper/lower limits. Then they hit submit, it shows a random number, and also a message that says "You've generate 1 number." Then they hit submit again and it shows another random number, but the message has changed to 2. And so on.

How to do it:

  • We will use a variable called times in our HTML template to store the number of times a number has been generated.
  • Edit your HTML template first. Add a hidden field to the part of the template that runs before the user has picked their limits:
<input type="hidden" name="times" value="0">
  • This way, when the form is submitted for the first time, a variable called times is created whose value is zero.
  • In the second part of the template (the part that runs after limits have been picked), add this to the form:
<input type="hidden" name="times" value="{{times}}">
  • What this does is make it so the HTML template (1) expects Flask to send it a variable called times, and (2) the HTML template will pass the same times variable right back whenever the form is submitted.
  • What you should do is edit the Python program to make the following changes:
    • Make the second part of the program capture the times variable from the form.
    • Increment the variable and send it back to the HTML template through a keyword argument in render_template.

Try it out! If you give up, look below.

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

Clone this wiki locally