The Code
            
const events = [
  {
    event: "ComicCon",
    city: "New York",
    state: "New York",
    attendance: 240000,
    date: "06/01/2017",
  },
  {
    event: "ComicCon",
    city: "New York",
    state: "New York",
    attendance: 250000,
    date: "06/01/2018",
  },
  {
    event: "ComicCon",
    city: "New York",
    state: "New York",
    attendance: 257000,
    date: "06/01/2019",
  },
  {
    event: "ComicCon",
    city: "San Diego",
    state: "California",
    attendance: 130000,
    date: "06/01/2017",
  },
  {
    event: "ComicCon",
    city: "San Diego",
    state: "California",
    attendance: 140000,
    date: "06/01/2018",
  },
  {
    event: "ComicCon",
    city: "San Diego",
    state: "California",
    attendance: 150000,
    date: "06/01/2019",
  },
  {
    event: "HeroesCon",
    city: "Charlotte",
    state: "North Carolina",
    attendance: 40000,
    date: "06/01/2017",
  },
  {
    event: "HeroesCon",
    city: "Charlotte",
    state: "North Carolina",
    attendance: 45000,
    date: "06/01/2018",
  },
  {
    event: "HeroesCon",
    city: "Charlotte",
    state: "North Carolina",
    attendance: 50000,
    date: "06/01/2019",
  },
];

// build dropdown for specific cities

const buildDropDown = () => {
  let dropDownMenu = document.getElementById("eventDropDown");
  dropDownMenu.innerHTML = "";

  let currentEvents = getEventData(); // TO - DO: get these from storage

  const cityNames = currentEvents.map((event) => event.city);
  const citiesSet = new Set(cityNames);

  let distinctCities = [...citiesSet];
  const dropDownTemplate = document.getElementById("dropDownItemTemplate");

  // copy the template
  let dropDownItemNode = document.importNode(dropDownTemplate.content, true);

  // make our changes
  let dropDownItemLink = dropDownItemNode.querySelector("a");
  dropDownItemLink.innerHTML = "All Cities";
  dropDownItemLink.setAttribute("data-string", "All");

  // add our copy to the page
  dropDownMenu.appendChild(dropDownItemNode);

  for (let i = 0; i < distinctCities.length; i++) {
    // get city name
    let cityName = distinctCities[i];

    // generate dropdown menu
    let itemNode = document.importNode(dropDownTemplate.content, true);
    let anchorTag = itemNode.querySelector("a");
    anchorTag.innerHTML = cityName;
    anchorTag.setAttribute("data-string", cityName);
    // append it to the dropdown menu
    dropDownMenu.appendChild(itemNode);
  }

  displayEventData(currentEvents);
  displayStats(currentEvents);
  document.getElementById('location').innerText = 'All Events';
};

const displayEventData = (currentEvents) => {
  const eventTable = document.getElementById("eventTable");
  const template = document.getElementById("tableRowTemplate");

  eventTable.innerHTML = "";

  for (let i = 0; i < currentEvents.length; i++) {
    let event = currentEvents[i];
    let tableRow = document.importNode(template.content, true);

    tableRow.querySelector('[data-id="event"]').textContent = event.event;
    tableRow.querySelector('[data-id="city"]').textContent = event.city;
    tableRow.querySelector('[data-id="state"]').textContent = event.state;
    tableRow.querySelector('[data-id="attendance"]').textContent =
      event.attendance.toLocaleString();
    tableRow.querySelector('[data-id="date"]').textContent = new Date(event.date).toLocaleDateString();

    eventTable.appendChild(tableRow);
  }
};

const calculateStats = (currentEvents) => {
  let total = 0;
  let most = currentEvents[0].attendance;
  let least = currentEvents[0].attendance;
  let average = 0;

  currentEvents.forEach((thisEvent) => {
    let currentAttendance = thisEvent.attendance;

    total += currentAttendance;
    if (most < currentAttendance) most = currentAttendance;
    if (least > currentAttendance) least = currentAttendance;
  });

  average = total / currentEvents.length;

  return {
    total: total,
    average: average,
    most: most,
    least: least,
  };
};

const displayStats = (currentEvents) => {
  let statistics = calculateStats(currentEvents);
  document.getElementById("total").textContent =
    statistics.total.toLocaleString();
  document.getElementById("average").textContent = Math.round(
    statistics.average
  ).toLocaleString();
  document.getElementById("most").textContent =
    statistics.most.toLocaleString();
  document.getElementById("least").textContent =
    statistics.least.toLocaleString();
};

const getEventData = () => {
  let data = localStorage.getItem("stadiumStatsEventData");

  if (data == null) {
    localStorage.setItem("stadiumStatsEventData", JSON.stringify(events));
  }

  let currentEvents = data == null ? events : JSON.parse(data);

  return currentEvents;
};

const viewFilteredEvents = (dropDownItem) => {
  let cityName = dropDownItem.getAttribute("data-string");

  // get all events
  let allEvents = getEventData();

  if (cityName == 'All') {
    displayStats(allEvents);
    displayEventData(allEvents);
    document.getElementById("location").innerText = cityName;

    return;
  }

  // filter to just selected city
  let filteredEvents = allEvents.filter(
    (event) => event.city.toLowerCase() == cityName.toLowerCase()
  );

  // display stats for those events
    displayStats(filteredEvents);
  // change the stats header
    document.getElementById('location').innerText = cityName;
  // display only those events in the table
  displayEventData(filteredEvents);
};

const saveNewEvent = () => {
  // get the form input values
  let name = document.getElementById('eventName').value;
  let city = document.getElementById('cityName').value;
  let attendance = parseInt(document.getElementById('attendance').value, 10);
  // let state = document.getElementById("newEventState");
  let dateValue = document.getElementById('eventDate').value;
  dateValue = new Date(dateValue);

  let date = dateValue.toLocaleDateString();

  let stateSelect = document.getElementById('newEventState');
  let stateIndex = stateSelect.selectedIndex;
  let state = stateSelect.options[stateIndex].text;
  // create a new event object
  const newEvent = {
    event: name,
    city: city,
    state: state,
    attendance: attendance,
    date: date
  }
  // add it to the array of current events
  let events = getEventData();
  events.push(newEvent);

  // then, save the array with the new event (local storage)
  localStorage.setItem("stadiumStatsEventData", JSON.stringify(events));

  buildDropDown();
}


            
          

Each task in this application being executed needs specific instructions, so keeping these concerns carefully organized in different functions is of primary importance for readability.

Some of the functions are for display purposes, and others are for fetching data. Others still, are designed to sort through data to only present content that the user wants.

Overall, I think the most interesting aspect of this application is how it saves data that the user enters, using only JavaScript, which is not a back end language. Much like how websites can store cookies on your device, this app keeps note on your own machine of any changes you've made to the content.

Going through the code now in broad terms, we start simply with an array of objects to populate the event table by default. Next we build a dropdown menu by mapping the city properties from each object into an array, importing an appropriate HTML template, and appending the content to the dropdown.

Inside of that function, we make sure to call the relevant display functions automatically, showing the user the event data table and updating the statistics. The displayEventData function simply takes the passed in events, clears out the table, and loops through each piece of information re-populating the table, cell by cell, and row by row.

In the bottom of this function, we start calling other display functions, so that everything needed to load onto the page is being run automatically. displayStats doesn't get its information from a parameter, but rather from calculateStats which checks for minimum values, averages, and whatever other statistics we want to feature.

In order to filter through the data to view events in a particular city, the viewFilteredEvents function sorts through an array of all events and simply runs displayStats as before, passing along only relevant filtered data to be displayed i.e. events in San Diego.

Finally, getEventData and saveNewEvent contain my favorite functionalities. By referencing your machine's local storage, each of them are able to manipulate .JSON files, turning them into strings or objects as needed, to execute or store your inputs respectively, even when you refresh or close the page.