In this lab you will get to grips with the ECMA6 programming language by learning to build dynamic websites
We will start by producing dynamic web pages that combine a static layout with dynamic data using a templating view engine.
There are a number of templating view engines that are compatible with Express however in this worksheet we will be using one of the more popular ones, called Handlebars. This needs to be imported into your script and set the default layout page.
Locate the files in the 01_nodejs/01_templates_forms/simple_templating/
directory, install the dependencies and start the server.
Access the base route /
, notice that you are seeing a basic html page. Open the script:
- We start by importing the Handlebars package and create a default layout called main. This defines the
main.handlebars
page as the one to use as the default website layout.- Open the
views/layouts/main.handlebars
file. - This template page will be used by all the pages in the website.
- Notice there is a
{{{body}}}
placeholder, this defines where the different page templates will be inserted.
- Open the
- In the base route
/
we call theres.render()
function and pass it the name of the template we want to use:- The parameter is a string,
home
. - This refers to the template
views/home.handlebars
- The parameter is a string,
- The contents of the
home.handebars
template is inserted into the layout file replacing the{{{body}}}
placeholder.
When an html page is loaded into a browser it contains link to other static files such as stylesheets and images. These need to be stored in a directory on the Express server which is visible to the browser:
- Open the
index.js
script and locate line 11, this tells the Express web server to make the contents of thepublic/
directory visible to external clients. - Locate the
public/
directory and notice it contains two directories- One called
css/
containing the stylesheet - And one called
images/
containing some image files.
- One called
- Because all the pages share the same stylesheet, the
views/layouts/main.handlebars
file includes a link to the stylesheet. - We have also added an
img
element to thehome.handlebars
html to display the image.
- Create a
/hello
route that uses a template file calledhello.handlebars
to display a heading with the textHello World!
- Modify the external stylesheet to display the heading in dark red.
- Find a smiley face image online and display this on the page.
So far we have not done anything particularly useful except separate out the layout from the content. In this section you will learn how to insert data directly into a template before it is rendered to the browser.
In the previous example you have seen how to insert single values into a web page but how to we display lists of data? A list is stored in an array in JavaScript so the first task is to ensure your data is in an array. If you recall lab 3 you will remember that the sqlite db.all()
function returns an Array
.
Restart the server and access the /date
route. Notice that it displays the current date in the browser. Open the index.js
file and locate the route.
- We start by creating a new
Date
object. - We use its built-in functions to create a string containing the current date.
- Next we create a JavaScript object that contains all the data we want to send to the template:
- In this example we have a
title
property containing the stringMy First Template
. - We have a seccond property called
today
that contains the date string we have just built.
- In this example we have a
- Finally we call
res.render()
but this time we pass the data as the second parameter.
To understand what happens to this data we need to understand the template. Locate the views/date.handlebars
template file:
- Notice that there are two placeholders, shown as
{{xxx}}
.- Each placeholder has a name.
- The names need to match the properties in the data we are sending to the template.
- Each placeholder is replaced by the data stored against the object property:
- The
{{title}}
placeholder is replaced by the stringMy First Template
. - The
{{date}}
placeholder is replaced with the date string we built in the script.
- The
- Use suitable properties of the
Date
object to display the date in a variety of different formats in a series of paragraph elements:- dd/mm/yyyy
- a Unix timestamp (number of seconds since 1st Jan 1970)
- Add a table to display some information about the client computer (using the
req.connection
object). - Extend the table to display the header information (using the
req.headers
object). - Insert a picture of a calendar.
So far we have inserted data from object properties into our templates. This works find for single records however often we will have multiple records to display such as the results of a database query. In this situation we will need to repeat a block of html code such as a list item or table row.
Restart the server and view the /food
route. Notice that it displays a numbered list showing four food items. Locate the route in your script.
- We start by creating an array. Each imdex contains an object with two properties, name and qty.
- We pass the array to
res.render()
as a JavaScript object using the myFood property.
Open the food.handlebars
template:
- Notice that there is an ordered list element.
- Inside this there is a special helper,
{{#each myFood}}
- The helper also has a closing block
{{/each}}
- The
myFood
property is passed to the opening block.
- The helper also has a closing block
- This block loops through the array stored in the
myFood
property. - The
this
object holds the object for the current index.- So
this.item
returns theitem
property (the name of the food item).
- So
This allows the handlebars template view engine to handle repeated data.
- Modify the template to display the shopping items in a html table instead of an ordered list.
- Add a second column to display the quantities of each item.
- Add a table header to display column headings.
- Without adding any more html, colour every other row of the table in light grey.
You have covered a lot of topics over the first few weeks of the module. Before you continue, complete the challenges listed below. These will help you revise all the content you have covered.
The repeating_data/
directory contains a 2-page template-driven dynamic website based on the data you used in the Databases lab. Install the dependencies, start the server and access the base route /
and the /details/1
route then study the script index.js
.
Now try to complete the following challenges:
- Add a route called
/about
that displays information about the fictional bookshop. - Add a footer that appears on all pages using the correct html5 element.
- Convert the list of books into a table.
- Add a column to display the ISBN number
- Add a hyperlink to the book titles to jump to the correct book details page.
- Add a column that displays links to take you to the Amazon product page (hint: use the ISBN number and study this link carefully!).
- Create and link a stylesheet to improve the page appearance:
- Style the header.
- Style the footer.
- Make the table easier to read.
- Add all the database fields to the product details page.
- Modify the stylesheet to improve the appearance.
If you can complete them all successfully, well done! You are ready to move onto the next section.
In this final part of the worksheet you will be building forms that can send data to a web server. Locate the simple_forms/
directory, install the necessary modules and start the server.
Lets start by looking at how forms send data to the server. This can be done using the HTTP GET
method or using the POST
method. Lets try out both so we can understand the differences.
Make sure the web server is running and access the /postform
route and open the corresponding html file.
- Complete the form with your name.
- Click on the the Submit button.
- Examine the URL carefully:
- Notice that it points to the base route
/
with no additional data in the URL.
- Notice that it points to the base route
- Open the Chrome developer tools and look at the http request:
- Notice that the request uses the
POST
method. This corresponds to themethod
attribute in the<form>
element. - The request header includes a
Content-Type
header which contains the valueapplication/x-www-form-urlencoded
.
- Notice that the request uses the
- There is a request body which contains the form data:
- This uses the
application/x-www-form-urlencoded
encoding. - Notice that it contains 2 query parameters in a querystring.
- The names of the query parameters correspond to the values in the
name
attributes in the<input>
elements.
- This uses the
Make sure the web server us running and access the /getform
route and open the corresponding html file.
- Complete the form with your name.
- Click on the the Submit button.
- Examine the URL carefully:
- Notice that it contains 2 query parameters in a querystring.
- The names of the query parameters correspond to the values in the
name
attributes in the<input>
elements.
- Open the Chrome developer tools and look at the http request:
- Notice that the request uses the
GET
method. This corresponds to themethod
attribute in the<form>
element. - The URL contains the data (remember there is only a request body when the
POST
method is used.
- Notice that the request uses the
In the previous section the form used the <input>
element which displayed simple text boxes where you could enter anything. In this section you are going to learn about how to use a wide range of different controls to capture user input.
locate and open the complex_forms/
directory. Install the required modules and start the server. Open the /register
route which will display a course registration form, complete this and submit the form. This demonstrates some of the more complex controls you can use. Open the views/register.handlebars
file which contains the markup used to render the form. Notice the following (see how many you can spot in the example form):
- The form is split into several logical sections using the fieldset element.
- Each fieldset has a legend element that represents its caption.
- Each form element has a
name
attribute. This is the key that the data can be accessed from by the processing script. Try completing the form and submitting. Examine the JSON data and compare the object keys to the form element names. - Each form element has a label. The
for
attribute should match thename
attribute of the form element it is labelling. - The input element defines a number of input types that can be used in forms:
- Plain text:
<input type="text">
- Password fields:
<input type="password">
- Email addresses:
<input type="email">
- URL addresses:
<input type="url">
- Numeric data:
<input type="number">
- Date pickers:
<input type="date">
- Hidden fields
<input type="hidden">
- Plain text:
- Sometimes we want the user to pick from a list of options:
Complete the following tasks. After each, complete and submit the form to ensure all data is avaialable:
- Add a box for the user's email address in the personal detail section.
- Create a new fieldset for the user's address and add input boxes to capture this. Make sure each box has a unique, descriptive
name
attribute. - You will find a json file containing a longer list of courses. Replace the static list with the data contained in this file (you will need to pass some repeating data to the template).
- Display the form data on the page rather than just the JSON string (you will need to pass each item through to the template and insert into individual placeholders).
- Add a link to the data page to return to the form.