Walkthrough: Itinerary/Ports
Itinerary/Ports - Walkthrough
Steps
- Include in your
Itinerary.jsandPort.jsfiles intoindex.htmlusingscripttags. - In the inline
scriptblock, create some newPortinstances and add them to a newItineraryinstance. - Create a new div with the id
portsnested inside theviewportdiv. - In
style.css, add a new selector for#ports. Specify a width of0px, amargin-topof96px, a display offlexand ajustify-contentofspace-around. - Add a new selector for
#ports > .port. Specify a width of64px, a height of32pxand set the background image to theport.pngimage file. - Add a new method to the
Controllerprototype calledrenderPorts. It should have a parameter ofportswhich will receive an array as an argument. - Inside
renderPorts, usedocument.querySelectorto find theportsdiv and assign it to a variable namedportsElement. SetportElement's width to0px. - You should then iterate over the array passed to the
portsparameter usingforEachand for each one should render a newdivto the DOM with the classport - Each new port element should have a data attribute of
portIndexset to the port's index in theportsarray - Add 256px to the
#portsdiv every time a new port element is appended to it - In the inline
scriptblock inindex.html, call thecontroller.renderPortsmethod, passing in yourItineraryinstance'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:
