Prototyping - Exercise

Contact Us or call 1-877-932-8228
Prototyping - Exercise

Prototyping

Duration: 20 to 30 minutes.

In this exercise, you will create two prototypes to represent vehicles and a company's fleet of vehicles.

  1. Open AdvancedObjects/Exercises/vehicles.html for editing.
  2. Create a prototype for Vehicle representing a vehicle with a given type ('car', 'bus', etc.), year purchased, and VIN (vehicle identification number); the fields and methods are listed in the comment.
  3. Create a prototype for Fleet representing a company's collection of vehicles; the fields and methods are listed in the comment.
  4. The HTML markup for the page includes a form, a div to display the current fleet, and a button which the user can click to get the current average age of the fleet vehicles; the HTML markup and JavaScript event handling code is already done for you.
  5. When the page loads, a window.onload event handler instantiates a new Fleet object; where indicated in the comments, add JavaScript code to add a vehicle, to display the current fleet, and to display the average age of fleet vehicles in response to user actions.
  6. Test your solution in a browser.

Solution:

AdvancedObjects/Solutions/vehicles.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Company Fleet</title>
	<style>
		form#addVehicle {
			float:left;
			width:48%;
		}
		div#info {
			float:right;
			width:48%;
		}
	</style>
	<script>
		var Vehicle = function(vehicleType, yearPurchased, VIN) {
			this.vehicleType = vehicleType;
			this.yearPurchased = yearPurchased;
			this.VIN = VIN; //vehicle identification number
			this.toString = function() {
				return this.vehicleType + ', purchased ' + this.yearPurchased + ', VIN: ' + this.VIN;
			}
		}

		var Fleet = function(companyName) {
			this.companyName = companyName;
			this.vehicles = [];
			this.addVehicle = function(vehicle) {
				this.vehicles.push(vehicle);
			}
			this.toString = function() {
				var str = 'Current fleet for <strong>' + this.companyName + '</strong>:';
				str += '<ul>';
				for (let v in this.vehicles) {
					if (this.vehicles.hasOwnProperty(v)) {
						let vehicle = this.vehicles[v];
						str += '<li>' + vehicle + '</li>';
					}
				}
				str += '</ul>';
				return str;
			}
			this.averageAgeOfVehicles = function() {
				if (this.vehicles.length === 0) {
					return 0;
				}
				var yearSum = 0;
				for (let v in this.vehicles) {
					if (this.vehicles.hasOwnProperty(v)) {
						let vehicle = this.vehicles[v];
						yearSum += parseInt(vehicle.yearPurchased);
					}
				}
				var averageYear = parseInt(yearSum / this.vehicles.length);
				var curYear = new Date().getFullYear();
				return curYear - averageYear;
			}
		}

		function clearFields() {
			document.getElementById('vehicleType').value = '';
			document.getElementById('yearPurchased').value = '';
			document.getElementById('VIN').value = '';
		}

		window.onload = function() {
			var companyFleet = new Fleet('ABC, Inc.');
			document.getElementById('currentFleetInfo').innerHTML = companyFleet;

			var addVehicleForm = document.getElementById('addVehicle');
			addVehicleForm.addEventListener('submit',
				function(event) {
					event.preventDefault();
					var vehicleType = document.getElementById('vehicleType').value;
					var yearPurchased = document.getElementById('yearPurchased').value;
					var VIN = document.getElementById('VIN').value;
					companyFleet.addVehicle(new Vehicle(vehicleType, yearPurchased, VIN));
					document.getElementById('currentFleetInfo').innerHTML = companyFleet;
					clearFields();
				},
				false);
			var getAverageAgeButton = document.getElementById('getAverageAge');
			getAverageAgeButton.addEventListener('click',
				function() {
					var averageAge = companyFleet.averageAgeOfVehicles();
					alert('The average age of all vehicles is ' + averageAge + ' years');
				},
				false);
		}
	</script>
</head>
<body>
	<h1>Company Fleet</h1>
	<form id="addVehicle">
		<select id="vehicleType">
			<option value="">-vehicle type-</option>
			<option value="car">car</option>
			<option value="van">van</option>
			<option value="truck">truck</option>
			<option value="bus">bus</option>
		</select>
		<input type="text" id="yearPurchased" placeholder="year purchased">
		<input type="text" id="VIN" placeholder="VIN">
		<input type="submit" value="Add Vehicle">
	</form>
	<div id="info">
		<div id="currentFleetInfo"></div>
		<button id="getAverageAge">Average Age of Vehicles</button>
	</div>
</body>
</html>

Code Explanation

Note that we are using ES2015 code here; specifically, the let keyword. We create prototypes for Vehicle and Fleet, each with the specified data members. Both prototypes have a toString() method, dictating how each should be turned into a string; note that, in the toString() method for Fleet we use the toString() method from Vehicle:

str += '<li>' + vehicle + '</li>'

For the toString() method in Fleet, we iterate over the array elements of this.vehicles to build an ordered list of all vehicles.

For method averageAgeOfVehicles() we check first to see if there are no vehicles in the array (that is, if this.vehicles.length === 0), returning 0 if so; if there is at least one vehicle in the array, then we iterate over the array to build a running sum of the year each vehicle was purchased. We find an average of these years, convert it to an integer, and subtract that value from the current year.

When the window.onload event fires, we set the inner HTML of the div with id currentFleetInfo to display the current fleet - which, on initial page load, will have no vehicles.

When the user adds a vehicle, we invoke the Fleet method addVehicle() to add a vehicle from the information entered by the user. Note that we do not need to create a named Vehicle object: we create a new Vehicle "on the fly" and supply it as the parameter:

CompanyFleet.addVehicle(new Vehicle(vehicleType, yearPurchased, VIN));

Lastly, we invoke method CompanyFleet.averageAgeOfVehicles() in response to the user clicking the #getAverageAge button and generate an alert popup message.

Next