In all the previous labs you have been writing JavaScript code to run on the server however the language was originally written to run in the web browser! In this lab you will be exploring how the JavaScript labguage can be used to directly interact with the HTML content in the web browser.
xxx
One of the first tasks you will face when working with the DOM is getting a reference to the correct DOM object. There are two approaches.
The simplest way is to use a CSS Selector to get a reference to the element or elements you want to manipulate.
- The
document.querySelector()
function takes a string parameter which is the CSS Selector that can identify the DOM objects you want to reference. For exampledocument.querySelector('h1')
returns a reference to the top-level heading on the page. If there are more than one element matching the CSS selector it returns the first match. - If you want to get a reference to multiple elements such as all the list items you should use the
document.querySelectorAll()
function which returns an array of all the matching DOM objects. For exampledocument.querySelectorAll('li')
returns an array of all the items in all lists on the page.
When an event handler is fired, the function called is passed a single parameter , often labelled as e
which is an object representing the event. This contains a property called target
which stores the DOM of the element that triggered the event itself. So, for example, if you clicked on an item in a list to trigger the event, the target
would contain a reference to the li
element. This is useful when you want to use the same event handler to handle events triggered by multiple elements such as items in a list.
For example both lines of code below get a reference to the first table cell on the first row.
document.querySelectorAll('tr')[0].childNodes[0].innerHTML
document.querySelector('table').rows[0].childNodes[0].innerHTML
When you are working with the DOM you will frequently need to access the parent DOM element or perhaps the child one. This is called traversing the DOM and there are a number of important properties and functions you will need to use:
- To access the parent node (such as the
ol
node when you select ali
node) you use theparentElement
property. - To access a child node (for example the
li
node if you are referencing theol
node) you will need to make use of thechildNodes
array. For example to access the third item in the list you would use the expression.childNodes[2]
. If there is only a single child node you can use thefirstChild
property instead. - Once you have a reference to the desired DOM node you will often want to access the text inside it. This can be accessed using the
innerHTML
property.
By chaining these together you can navigate both up and down the DOM tree to locate the DOM object you want, for example the following returns the contents of the first cell of the table row regardless of which cell in the row was clicked.
e.target.parentElement.firstChild.innerHTML
- When the user tries to delete an item, use the
confirm()
function to ask if they are sure. This returns true if the user agrees.- Display the name of the item being deleted in the confirmation dialog using one of the three ways to access the table DOM.
- When the confirm dialog closes, bring the focus back to the input box.
- If the user clicks on any of the cells the focus shound return to the input box.
- Use the
e.target.innerHTML
property to prevent the row being deleted unless the user clicks on thedelete
link. - Add a second textbox called
qty
, this will hold the number of items being added.- When the item name is added and the enter key pressed focus should move to the qty field.
- When a quantity is entered and the enter key pressed the data should be added to the table.
- Add a column between the item name and the delete link (making a total of 3 columns) to the table to display the quantity of each item.
- Prevent items being added if they are already in the list.
- When a duplicate item is added increase the qty of the item already in the list.
Now you have mastered DOM manipulation its time to move onto one of the most common uses of client-side JavaScript, form validation. The base code can be found in the exercises/05_client/contacts/
directory. In the previous example we opened the index.html
file using the files://
protocol by dragging the html file into the chrome browser. Since we will be implementing some features that don't support this we need to access the page over http://
. One way would be to create a koa script that serves static content however a quick and simple solution is to use the serve
package. This needs to be installed and run from the contacts/
directory.
$ npm install serve
$ ./node_modules/.bin/serve
┌──────────────────────────────────────────────────┐
│ │
│ Serving! │
│ │
│ - Local: http://localhost:5000 │
│ - On Your Network: http://10.17.114.20:5000 │
│ │
│ Copied local address to clipboard! │
│ │
└──────────────────────────────────────────────────┘
Now you can paste the url into the chrome browser to access the page over http! Since the code is loaded by the browser you don't need to restart this server after making changes to the code. Remember to stop the server using ctrl+c
when you have stopped working on the site.
Handling form validation
Revealing sections of the form
Preventing form submission
If you close your browser down and re-open it you will see that the contacts you added have been persisted! The data is stored within the browser using a document database techology called IndexedDB.
Viewing the data.
In this section you will learn how to retrieve data from an API, specifically we will be covering:
- How to make a GET call to a RESTful API.
- Building a dropdown list using dynamic data.
- Building a table using dynamic data.
- Modify the HTML page to add:
- A second dropdown list with a name of
converted
. This should contain the same currency list as thebase
dropdown. - A textbox that only accepts numerical data, call this
amount
.
- A second dropdown list with a name of
- Modify the event listener at the top of the script so that changes to either of the dropdown lists triggers the
getRates()
function. - Currently the
getRates()
function checks to see that thebase
selection has been made before it generates the table of rates. Modify this function so that it only generates the table if:- The use makes a selection from the second dropdown.
- The user has entered a numerical value in the
amount
box (don't forget to convert the amount entered into a number and add anonkeyup
event handler!).
- If the user has done the above replace the table with a
<h2>
element that displays the conversion rate between the two selected currencies:- Use this example
https://api.exchangeratesapi.io/latest?base=GBP&symbols=USD
as a guide.
- Use this example
- Finally multiply this rate by the amount from the textbox and display the result instead.
- Round the value down to the nearest whole number.
- Display the currency code as well.
Using localstorage (and sqlite)?
xxx