Overview

The calculator package is the main project package, it is comprised of html, js, css, and its core functionality relies on no outside libraries. In addition to its core functionality the calculator application has vue developer menu web component embedded.

Table of Contents

App Structure

Bellow is the current structure of the Distance Calculator Package.

public/
├── styles/
│   ├── style.css
│   └── debug.css
├── scripts/
│   ├── tests/
│   │    └── main.tests.js
│   ├── main.js
│   ├── dev-menu.js
│   ├── dev-menu.js.map
│   ├── dev-menu.min.js
│   └── dev-menu.min.js.map
├── index.html
└── styleDebug.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
file Contents
index.html holds main application
styleDebug.html holds main application with css debug mode activated
main.js holds main application's javascript
dev-menu.js holds compiled web component for hidden dev menu
main.tests.js holds mockup unit tests vanilla js

How to use

Frontent Application

Directions

Open index.html file in your web browser.

Enter the first letters of your target Departing airport in the input box marked from, than choose from the available airports from the dropdown that appears. After that enter the first letters of your target Destination airport in the input box marked to, than choose from the available airports from the dropdown that appears.

If succesfull the distance between the two airports will appear.

Frontent Application - Hidden Developer Menu

Directions

Open index.html file in your web browser.

To activate the secret developer menu hidden in the frontend application type the following keys in order.

UP, UP, DOWN, DOWN, LEFT, RIGHT, LEFT, RIGHT, B, A

After that if succesfful the developer menu activation button will appear, click it to toggle the menu.

Frontent Application - Style Debug View

Directions

Open styleDebug.html file in your web browser or select Style Debug view from the hidden developer menu.

The style debug page features the page with clearly defined boarders to check for overlap.

HTML Elements Overview

The html located in index.html is what defines the structure for the frontend application.

Important Frontend Elements

Element TagName Use
.hero section Houses all of the elments within the frontend application, and has a image background
.hero-inner div Inner wrapper inside the main hero element, used to center interactive components horizontally and vertically
#devHolder div Holds the hidden developer menu toggle button, shown only when one enters the secret konami code
.form-inline .btn form Holds the form elements for the distance calculator, as well as results and feedback for form validation
#feedBack p Used for form validation, shows message directing user in choosing correct form input
#from_airport input Used to prompt user to enter a departing airport
#to_airport input Used to prompt user to enter a destination airport
#distance p Upon correct airport selections displays distance between two airports

Frontend Code Snippet

   <section class="hero">
      <div class="hero-inner">
         <div id="devHolder" class="hideMenu">
            Developer Menu
            <dev-menu></dev-menu>
         </div>
         <h1>Distance Travel Calculator</h1>
         <h2>Choose your Airports and find out the distance</h2>

         <form class="form-inline btn" autocomplete="off" name="distanceForm">
            <p id="feedBack">
            </p>
            <label for="from_airport">From:</label>
            <div class="dropdown">
               <div class="autocomplete dropdown">
                  <input id="from_airport" type="text" name="from_airport" placeholder="Airport Code"
                     class="selectInput airport_input">
               </div>
            </div>
            <label for="to_airport">To:</label>
            <div class="dropdown">
               <div class="autocomplete dropdown">
                  <input id="to_airport" type="text" name="to_airport" placeholder="Airport Code"
                     class="selectInput airport_input">
               </div>
            </div>
            <p id="distance">
            </p>
         </form>

      </div>
   </section>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Javascript Overview

The javascript located in scripts/main.js is what controls the inner workings of the frontend application.

Variables

Variable Use
fakeFetchedData Simulate web scraping of airport codes or information
distanceTotal Placeholder for distance message
feedbackMessage Placeholder for feedback message
intentChecked Simulate comparison of internal intent data vs fetched data from
currentFocus Currently Focused element from autocomplete values
inputArray Holds input values
from Used to validate departure form input
to Used to validate destination input
keySequence Contains running list of keypresses made by user
devMode Contains series of keys to press for unlocking developer mode
resetArray Contains key to reset keySequence Array

Main Frontend Functions

Function Arguments Use
autocomplete user input, autocomplete array handles autocompletion functionality
validateForm none validates user form input
travelListener Departure airport code, Destination airport code Calculates distance between airports and appends
feedBack Message to attach to input feedback Inform user throughout process
devToggle Itself Listens for correct key sequences
closeAllLists Clicked on element Removes all other active lists from DOM
addActive Current Active List Adds active class to current list
removeActive Current Active List Removes active class
invokeAutocomplete Target DOM Elements Invokes autocomplete function on target DOM Elements

Isolated Code Snippets and tests

main.tests.js

/* Define testing functions*/
function describe(text, fn) {
  console.log("FUNCTION", text);
  fn();
}

function it(text, fn) {
  console.log("DESCRIPTION", text);
  fn();
}

function expect(arg) {
  return {
    value: arg,
    toBe(arg) {
      if (arg === this.value) {
        console.log("TEST PASSED!");
      } else {
        console.log("TEST FAILED");
      }
    }
  };
}

/*Run Tests*/

//Function : completeChecker

function completeChecker(arrayItem, val) {
  if (arrayItem.substr(0, val.length).toUpperCase() == val.toUpperCase()) {
    let autocompleteItem = document.createElement("DIV");
    autocompleteItem.innerHTML =
      "<strong>" + arrayItem.substr(0, val.length) + "</strong>";
    autocompleteItem.innerHTML += arrayItem.substr(val.length);
    autocompleteItem.innerHTML +=
      "<input type='hidden' value='" + arrayItem + "'>";
    autocompleteItem.addEventListener("click", function(e) {
      inp.value = this.getElementsByTagName("input")[0].value;
      // closeAllLists();
      // validateForm();
    });
    return autocompleteItem;
  }
}
//Test : completeChecker

describe("completeCheker", () => {
  it("returns a dom node if arguments match", () => {
    const item = "FAX";
    const value = "FA";
    const Actual = completeChecker(item, value);
    expect(Actual.nodeName).toBe("DIV");
  });
  it("returns undefined if arguments don't match", () => {
    const item = "abC";
    const value = "FA";
    const Actual = completeChecker(item, value);
    expect(Actual).toBe(undefined);
  });
});

//Function : invokeAutocomplete

function invokeAutocomplete(targetElements) {
  if (targetElements) {
    targetElements.forEach(function(input) {
      // autocomplete(input, intentChecked);
    });
    return targetElements;
  }
}
//Test : invokeAutocomplete

describe("invokeAutocomplete", () => {
  it("returns array if elements exist", () => {
    var elements = ["element"];
    const Actual = invokeAutocomplete(elements);
    expect(Actual.length).toBe(1);
  });
  it("returns undefined if elements don't exist on page", () => {
    var elements;
    const Actual = invokeAutocomplete(elements);
    expect(Actual).toBe(undefined);
  });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
Last Updated: 8/11/2019, 3:34:12 AM