Disclaimer: This page is entirely static and does not interact with any server, all client-server interactions are purely simulated


HTML Forms



The source code of this HTML form looks like:

1
2
3
4
5
<form>
  <input type="text" name="name" placeholder="What's your name?" />
  <input type="number" name="age" placeholder="How old are you?" />
  <button type="submit">Submit</button>
</form>

Try It!

Write your name and age into the above form.
When you press the Submit button, have a look at the URL!



Forms using GET

Have a look at the address bar - We can see the data that we just submitted.
This type of form submission uses a GET request

Great, or is it…

Try It!

Modify the ?name=&age= portion of the URL and change the name!

Submitting form data via a GET request is somewhat insecure, as it allows the client to easily tamper with the data. (It also makes the URL look yucky!)

 

Instead, what we can do is change our form to use the POST request method!!!



Forms using POST



The HTML code follows the standard form convention, but with a method="POST" attribute in the <form> tag:

1
2
3
4
5
<form method="POST">
  <input type="text" name="name" placeholder="What's your name?" />
  <input type="number" name="age" placeholder="How old are you?" />
  <button type="submit">Submit via POST</button>
</form>

Try It!

Write your name and age into the above form.
Then press the Submit button!

This time, there’s no data in the URL - rather the data was sent to the server via a POST request!



Forms and Flask

Handling GET

To retrieve the query arguments in Flask

1) Import the request proxy
from flask import request

2) Access the data
request.args

Example

1
2
3
4
5
@app.route("/hello/", methods=["GET"])
def greetingGET():
  # validate(request.args) # Check that the arguments are valid
  return f"""Hey there, {request.args['name']}!<br>
             You are supposedly {request.args['age']} years old!"""

Handling POST

To retrieve the post data in Flask

1) Import the request proxy
from flask import request

2) Access the data
request.data
(Make sure your route decorator has POST in its method scope!)

Example

1
2
3
4
5
@app.route("/hello/", methods=["POST"])
def greetingPOST():
  # validate(request.data) # Check that the data is valid
  return f"""Hey there, {request.data['name']}!<br>
             You are supposedly {request.data['age']} years old!"""



Use Cases

Keeping submitted data

If you noticed in the above forms…
When you pressed the Submit button, after the page loaded with the response - your form was empty!

This is because HTTP is a stateless protocol, each request doesn’t know about any other request.
As a result, the response webpage will not be able to know the submitted data… unless we make it so

This can easily be done with Flask’s render_template function, where we can pass the submitted form data back into the webpage!

Refer to this file from the week 7 / 8 lab

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from flask import request, render_template # ...
###

@app.route("/hello", methods=["GET", "POST"])
def helloMULTI():
  if (request.method == "GET"):
    data = request.args
  else: # request.method == "POST"
    data = request.data

  name = data["name"]
  age = int(data["age"])
  ageIsEven = age % 2 == 0

  return render_template("hello.html", name = name, age = age, isEven = ageIsEven, formData = data)
1
2
3
4
5
6
<form>
  <input name="name" {% if formData["name"] %}value={{formData["name"]}}{% endif %}>
  <input age="age" {% if formData["age"] %}value={{formData["age"]}}{% endif %}>
</form>
Hey there, {{name}}!!
You are {{age}} years old, which is an {{"even" if isEven else "odd"}} age!


Demo



Client-side validation

It is good practice to also validate form data on the client-side as well as on the server-side!

(Note: Server-side validation is a MUST, regardless if you have client-side validation or not)

To do such, you can add the required attribute to your <input> tags.
For example: <input type="number" name="age" required>

This prevents the browser from submitting the form unless the input is filled, and has valid content corresponding to the input type

(In fact, all the forms on this page already have this attribute added!)