Wrapping up Module 3 material
HW3 Milestone is due tonight (lock date also tonight)
Exploration Session Today!
GET
POST
These POST examples are commonly used with forms!
There are two ways you'll commonly see forms used with POST
<form id="input-form" method="post" action="submitter.php">
City: <input name="city" type="text"/ >
State: <input name="state" type="text" />
ZIP: <input name="zip" type="number" />
<button id="submit-btn">Submit!</button>
</form>
As soon as the submit button is clicked on this page, the data is sent to the web service (submitter.php) and the page is refreshed with the response (sometimes redirecting).
This is becoming less common because we lose the asynchronous features of requests.
<form id="input-form">
City: <input name="city" type="text"/ >
State: <input name="state" type="text" />
ZIP: <input name="zip" type="number" />
<button id="submit-btn">Submit!</button>
</form>
let url = "submitter.php";
let data = new FormData(id("input-form"));
fetch(url, { method : "POST", body : data })
.then(checkStatus)
.then(...)
.catch(...)
Compare this new submit behavior here.
What do you think are the trade-offs between the two approaches?
When an input is in a form along with a button, clicking the button automatically verifies the input and does a POST request. If you are not sending a POST form, you may find it helpful to use preventDefault to override default form submission behavior (used in previous example).
function init() {
id("input-form").addEventListener("submit", function(e) {
// Fires when submit event happens on form
// If we've gotten in here, all HTML5 validation checks have passed
e.preventDefault(); // prevent default behavior of submit (page refresh)
submitRequest(); // do more validation with JS and then fetch with FormData
});
// rest of code
Many websites offer features that allow users to interact with the page and request/submit data to servers. Unfortunately, not all users will behave as expected.
Take a look at your handout and talk with your neighbors to answer the questions (handout also provided here).
User input validation is the process of ensuring that any user input is well-formed and correct (valid).
Q: What are some examples of input validation you came up with?
Validation can be performed:
Prioritizing validation is important for building websites that are:
If you're interested in learning more, MDN has a good quick introduction to web security, and OWASP is a fantastic resource for all things related to web security. You can also find a good article on how to write user-friendly form UIs here.
The takeaway? There are many ways to perform validation, but MDN/OWASP both are great resources to refer to based on the context of your websites
Most importantly, don't trust that users will provide correct/safe input!
<form>
<label for="city-input">City: </label>
<input name="city" type="text" />
<label for="state-input">State: </label>
<input name="state" type="text" />
<label for="zip-input">ZIP: </label>
<input name="zip" type="number" />
<button id="submit-btn">Submit!</button>
</form>
We can validate this input in a few different ways:
We've already seen some ways to use HTML5 tags to require certain types of input by
adding attributes to your <input>
tags to help with validation
<input type="number">
We can limit the up and down arrows with min
(and max
if we choose)
<input type="number" min=0>
To insist that there is a value in the input field we can add required
<input type="number" required>
To prevent a user from being able to type in erroneous values, we can add a
regular expression to the required
attribute
<input type="number" required="\d+">
form
<form>
<label for="city-input">City: </label>
<input name="city" type="text" required/>
<label for="state-input">State: </label>
<input name="state" type="text" size="2" maxlength="2" required/>
<label for="zip-input">ZIP: </label>
<input name="zip" type="number" size="5" min=10000 max=99999 required/>
<button id="submit-btn">Submit!</button>
</form>
Forms are HTML elements that can be used to "package" user input values baesd on the name attribute, often used with POST requests. There are many neat ways to perform validation with the right choice of form elements!
The label is important when building forms (especially today) to aid assistive technology in reading the form elements. Each text label should be wrapped in a label tag, and include the "for" attribute with the id of the labeled element.
<label for="name-input">Name:
<input type="text" id="name-input" name="student-name" />
</label>
This is read by most screenreaders as "Name, edit text"
More information here.
You can also get the ChromeVox Chrome Extension to test what screenreaders would say on your webpages!
Solution code (try adding more validation methods on your own!):
<form id="input-form">
<div>
<label for="name-input">Name: </label>
<input id="name-input" name="student-name" type="text" required/>
</div>
<div>
<label for="email-input">E-mail (@uw.edu): </label>
<input id="email-input" name="email" type="email" required/>
</div>
<div>
<label for="sid-input">Student Number: </label>
<!--
A valid student number is 7 digits; demo considering students between 2010 (min) and 2019
(max) to demonstrate min/max
-->
<input id="sid-input" name="sid" type="number" min=1000000 max=1999999 />
</div>
<div id="minute-options">
<label>2-Minute Question <input type="radio" name="minutes" value=2 /></label>
<label>10-Minute Question <input type="radio" name="minutes" value=10 /></label>
</div>
<textarea name="question" minlength=20 rows=10 placeholder="Enter your question..."></textarea>
<button id="submit-btn" type="submit">Enter Queue!</button>
</form>
/**
* Override the default submission behavior for the form's submit event.
*/
function initialize() {
id("input-form").addEventListener("submit", function(e) {
// if we've gotten in here, all HTML5 validation checks have passed
e.preventDefault();
submitRequest();
});
}
/**
* Send form data to the WPL web service. Note that this function
* is called only after all HTML5 validation constraints
* (e.g. required attributes) have passed!
*/
function submitRequest() {
// Solution 1: Can use form DOM element as parameter to FormData!
let formData = new FormData(id("input-form"));
// Note that unlike GET requests, no url parameters passed in a POST request!
fetch(URL, { method : "POST", body : formData })
.then(checkStatus) // The wpl.php will return text for this demo, no JSON
.then(showResponse)
.catch(handleError);
}
This submitRequest()
function is called in the overriden submit behavior
(from previous slide).
/**
* Send form data to the WPL web service.
*/
function submitRequest() {
let formData = new FormData();
// Build the 4 parameters for our POST request
formData.append("sid", qs("input[name='sid']").value);
formData.append("name", qs("input[name='name']").value);
formData.append("minutes", qs("textarea").value);
formData.append("question", qs("input[name='minutes']:checked").value);
fetch(URL, { method : "POST", body : formData })
.then(checkStatus)
.then(showResponse)
.catch(handleError);
}
As shown on Monday, we can also use the append method to append parameters one at a time (in this example, wpl.php only expects the 4 POST parameters)
While this is a bit more work, we don't always need to send all form elements in an API request, and it also gives us more control over validation checks in JS (for properties you can't check with HTML5 attributes) before the fetch.
Friday we will be starting Module 4 (PHP), where you will learn how to handle the requests you have been sending as clients!
An interactive "PHP Basics" Tutorial is posted for Friday! Please play around a bit with the language before Friday!