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
elementa 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. Thename
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 theterm
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
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. Thename="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:
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', '')
andrequest.args.get('score', '')
retrieve the values of thegenre
andscore
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.
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
).