6.6. Forms - Part 1#

HTML forms are essential for collecting user input on webpages. In this section we will learn how to create forms with HTML, how to send the form data to a webserver using a HTTP GET request using query strings and handle the request on a web server.

We’ll use these form submissions to filter movie reviews in our case study as an example.

6.6.1. HTML Forms#

A HTML form consists of

  • a form element

  • a set of input elements inside the form element.

Here’s an example of a form

<!DOCTYPE html>
<html>
<head>
    <title>Search Form</title>
</head>
<body>
    <h1>Search</h1>
    <form>
        <label for="query">Enter your search:</label>
        <input type="text" id="term" name="term"><br><br>

        <input type="submit" value="Search">
    </form>
</body>
</html>

Explanation

  • <form> specifies the start of a form and encapsulates all the inputs that are to be submitted with the form.

  • <input type="text" id="term" name="term"> creates a text input for the user’s search term. The name attribute will become the key in the query string.

  • <input type="submit" value="Search"> creates a button to submit the form data.

6.6.2. Form Inputs#

The HTML specification defines a number of valid input types. Common examples are:

  • checkbox

  • number

  • radio

  • text

There is also a special type called submit, which creates a button that submits the form when clicked.

A full list of valid input types can be found here https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input

6.6.3. Forms over HTTP#

When a form is submitted, the browser sends the form data to the server using HTTP. The two most common methods are:

  • GET: Sends data as part of the URL, typically used for retrieving data.

  • POST: Sends data in the body of the request, used for submitting data such as forms or file uploads.

We will focus on submititng forms using GET requests on this page.

Note

Forms using POST requests are described in Forms - Part 2.

For forms using GET the data is encoded in the URL itself, making them ideal for:

  • Search queries

  • Filters for content (e.g., filtering movies by genre)

  • Bookmarkable URLs (since the data is visible in the URL, users can save and share the link)

Everyday examples include search bars on websites (e.g., Google) and filters on e-commerce sites (e.g., filtering by price or category).

6.6.4. Query Strings#

When using the GET, the data is sent in the URL as a query string. Query strings consist of key-value pairs appended to the URL, and they follow this format:

http://example.com/search?key1=value1&key2=value2
  • Key: The name of the input field in the form.

  • Value: The value entered by the user.

6.6.5. Example Form#

Here’s an example of a form using GET where users can search by name:

 1<!DOCTYPE html>
 2<html>
 3<head>
 4    <title>Search Form</title>
 5</head>
 6<body>
 7    <h1>Search</h1>
 8    <form action="/search" method="GET">
 9        <label for="term">Enter your search:</label>
10        <input type="text" id="term" name="term"><br><br>
11
12        <input type="submit" value="Search">
13    </form>
14</body>
15</html>

Explanation

  • <form action="/search" method="GET"> creates a form that submits data to the /search URL using the GET method. This means the input will appear in the URL after submission.

When the form is submitted with “Flask” as the search term, the URL will look like this:

6.6.6. Handling Query Strings#

Here’s how you can handle the query string data in Flask:

from flask import Flask, request

app = Flask(__name__)

@app.route('/search', methods=['GET'])
def search():
    # Access the query string data
    term = request.args.get('term', '')

    if term:
        return f"You searched for: {term}"
    else:
        return "No search term provided."

app.run(debug=True, port=5000)

Explanation

  • The /search route listens for GET requests.

  • request.args.get('term', '') is used to retrieve the value of the term parameter from the URL. The request.args dictionary contains all the query string data. If no value is provided, it defaults to an empty string ('').

  • The server returns a message that displays what the user searched for.

6.6.7. Example: Filter Reviews#

Let’s create an example where we filter the movies in the “Movie Reviews” database by attributes like genre or review score. The user will select filters using a form, and the results will be displayed based on the selected filters.

Project structure:

├── app.py
├── movies.db
└── templates/
    └── search.html
    └── filter.html
app.py#
 1from flask import Flask, request, render_template
 2from sqlalchemy import create_engine, text
 3
 4app = Flask(__name__)
 5
 6# Connect to the database
 7engine = create_engine('sqlite:///movies.db')
 8
 9@app.route('/search')
10def filter_movies():
11    return render_template('search.html')
12
13@app.route('/filter', methods=['GET'])
14def filter_movies():
15    # Get filter parameters from the query string
16    genre = request.args.get('genre', '')
17    score = request.args.get('score', '')
18
19    conditions = []
20    if genre:
21        conditions.append("genre={}".format(genre))
22    if score:
23        conditions.append("score>={}".format(score))
24
25    condition_str = " and ".join(conditions)
26
27    # Get the movie review that match the conditions
28    query = text("SELECT * FROM reviews WHERE {}".format(condition_str))
29    result = connection.execute(query).fetchall()
30
31    return render_template('movie_list.html', movies=filtered_movies)
32
33app.run(debug=True, port=5000)

Explanation

  • <form action="/filter" method="GET"> creates a form that submits the selected filters to the /filter URL using the GET method.

  • <select id="genre" name="genre"> creates a dropdown list of genres. The name="genre" attribute ensures that the selected genre is sent as a query string parameter.

  • <input type="number" id="score" name="score"> allows users to specify a minimum review score. The name=”score” attribute ensures this value is sent as a query string parameter.

  • <input type="submit" value="Filter Movies"> sends the selected filter options to the server when clicked.

When the form is submitted with “Action” as the genre and “8” as the minimum score, the URL will look like this:

search.html#
 1<!DOCTYPE html>
 2<html>
 3    <head>
 4        <title>Search Reviews</title>
 5    </head>
 6    <body>
 7        <h1>Filter Movies</h1>
 8        <form action="/filter" method="GET">
 9            <label for="genre">Genre:</label>
10            <select id="genre" name="genre">
11                <option value="">Any</option>
12                <option value="Action">Action</option>
13                <option value="Comedy">Comedy</option>
14                <option value="Drama">Drama</option>
15                <option value="Animation">Animation</option>
16            </select><br><br>
17
18            <label for="score">Minimum Review Score:</label>
19            <input type="number" id="score" name="score" min="1" max="10"><br><br>
20
21            <input type="submit" value="Filter Movies">
22        </form>
23    </body>
24</html>

Explanation

  • The /filter route listens for GET requests with query string parameters for filtering movies.

  • request.args.get('genre', '') and request.args.get('score', '') retrieve the values of the genre and score parameters from the URL. If no value is provided, they default to an empty string ('').

  • The reviews` table is queried to retrieve reviews that match the conditions.

  • The filtered list of movies is passed to the movie_list.html template, which displays the movies.

filter.html#
 1<!DOCTYPE html>
 2<html>
 3    <head>
 4        <title>Movie List</title>
 5    </head>
 6    <body>
 7        <h1>Filtered Movies</h1>
 8        <ul>
 9            {% for movie in movies %}
10                <li>{{ movie[1] }} ({{ movie[2] }}) - Score: {{ movie[5] }}</li>
11            {% endfor %}
12        </ul>
13    </body>
14</html>

Explanation

  • This template loops through the filtered movies and displays each movie’s title, genre, and review score in a list.

6.6.8. Glossary#

Query String#

A query string is the part of a URL that contains additional information or parameters that a web server can use to process a request, often appearing after a “?” in the URL (e.g., ?search=books).