Walkthrough: Itinerary/Ports
Itinerary/Ports - Walkthrough
Steps
- Include in your
Itinerary.js
andPort.js
files intoindex.html
usingscript
tags. - In the inline
script
block, create some newPort
instances and add them to a newItinerary
instance. - Create a new div with the id
ports
nested inside theviewport
div. - In
style.css
, add a new selector for#ports
. Specify a width of0px
, amargin-top
of96px
, a display offlex
and ajustify-content
ofspace-around
. - Add a new selector for
#ports > .port
. Specify a width of64px
, a height of32px
and set the background image to theport.png
image file. - Add a new method to the
Controller
prototype calledrenderPorts
. It should have a parameter ofports
which will receive an array as an argument. - Inside
renderPorts
, usedocument.querySelector
to find theports
div and assign it to a variable namedportsElement
. SetportElement
's width to0px
. - You should then iterate over the array passed to the
ports
parameter usingforEach
and for each one should render a newdiv
to the DOM with the classport
- Each new port element should have a data attribute of
portIndex
set to the port's index in theports
array - Add 256px to the
#ports
div every time a new port element is appended to it - In the inline
script
block inindex.html
, call thecontroller.renderPorts
method, passing in yourItinerary
instance'sports
.
Include in your Itinerary.js
and Port.js
files into index.html
using script
tags.
In the inline script
block, create some new Port
instances and add them to a new Itinerary
instance.
This is similar to how we created itineraries in our tests (before we stubbed ports):
Create a new div with the id ports
nested inside the viewport
div.
We will use this as a container for individual port elements.
In style.css
, add a new selector for #ports
. Specify a margin-top
of 96px
, a display of flex
and a justify-content
of space-around
.
space-around
will give equal spacing around each of the element's children.
Add a new selector for #ports > .port
. Specify a width of 64px
, a height of 32px
and set the background image to the port.png
image file.
#ports > .port
means select all elements with a class of port
which are a direct child of an element with an id of ports
Add a new method to the Controller
prototype called renderPorts
. It should have a parameter of ports
which will receive an array as an argument.
Inside renderPorts
, use document.querySelector
to find the ports
div and assign it to a variable named portsElement
. Set portElement
's width to 0px
.
We set a width of 0
as we want JS to manipulate the width of this container every time we add a child element.
You should then iterate over the array passed to the ports
parameter using forEach
and for each one should render a new div
to the DOM with the class port
Firstly we create a new DOM element with document.createElement
. At this point it does not exist on the page, only in JavaScript.
We set it's className
attribute to our .port
selector. Note that in JS we reference to className
despite the fact the HTML attribute is class
. This is because class
is a reserved word in JavaScript.
Lastly, we call appendChild
on portsElement
(the #ports
div). This will insert our new element newPortElement
into the DOM as a child of the #ports
div.
Each new port element should have data attributes of portName
and portIndex
set to the name of the port and the port's index in the ports
array respectively.
Data attributes allow us to store our own custom attributes on HTML elements. This will be handy for differentiating each port we add to the ports
array.
This can be placed after the declaration of newPortElement
and before newPortElement
is mounted to the DOM. It will render a port div that looks something like this:
Note also that we are using the index
in this example. This is because we know this will always be unique.
Add 256px to the #ports
div every time a new port element is appended to it
This should be placed inside the forEach
(as we want it to repeat for every port) and should take place after you've appended newPortElement
to the DOM. There are some new concepts here. If you call parseInt with a string such as 256px
then it will automatically extract the number part of the string. The 10
is a radix - you don't need to remember this (it's all very mathematical) but a radix of 10
indicates that we want to convert from a decimal number. We now have an integer (whole number) of 256
assigned to portsElementWidth
. We use the power of template literals to do a JavaScript expression within a string, which evaluates to our previous width plus 256
, and then we add px
on the end (as we're setting a CSS property).
In the inline script
block in index.html
, call the controller.renderPorts
method, passing in your Itinerary
instance's ports
.
You should add this after you've instantiated your Itinerary.
If you open up your page in the browser, you should now have some ports: