The Code
var 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 city
function buildDropDown() {
let dropdownMenu = document.getElementById('eventDropDown');
dropdownMenu.innerHTML = ''; //clears out the current city values above
let currentEvents = getEventData();
let cityNames = currentEvents.map(
function(event) {
return event.city;
}
) //map method requries anon function, gives each item of array one item at a time
// you can also write it like: let cityNames = currentEvents.map(event => event.city);
let citiesSet = new Set(cityNames); //Set objects are a collection of values to ensure NO DUPLICATES
let distinctCities = [...citiesSet]; // converts set to array with the []: ['Charlotte', 'San Diego', 'New York'] // ...spread operator
const dropdownTemplate = document.getElementById('dropdownItemTemplate');
//copy the template
let dropdownItemNode = document.importNode(dropdownTemplate.content, true); //false would include li parent tag but no child elements inside
//make our changes
let dropdownItemLink = dropdownItemNode.querySelector('a')
dropdownItemLink.innerText = 'All Cities';
dropdownItemLink.setAttribute('data-string', 'All');
//add out copy to the page
dropdownMenu.appendChild(dropdownItemNode);
for(let i = 0; i < distinctCities.length; i += 1) {
//get the city name
let cityName = distinctCities[i];
//generate a dropdown element
let dropdownItemNode = document.importNode(dropdownTemplate.content, true);
let dropdownItemLink = dropdownItemNode.querySelector('a');
dropdownItemLink.innerText = cityName;
dropdownItemLink.setAttribute('data-string', cityName);
//append to dropdown menu
dropdownMenu.appendChild(dropdownItemNode);
}
displayEventData(currentEvents);
displayStats(currentEvents);
document.getElementById('location').innerText = 'All Events';
}
function displayEventData(currentEvents) {
// get the table
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();
//display results
eventTable.appendChild(tableRow);
}
}
function calculateStats(currentEvents) {
let total = 0;
let average = 0;
let most = 0;
let least = currentEvents[0].attendance;
for(let i = 0; i < currentEvents.length; i++) {
let currentAttendance = currentEvents[i].attendance;
total += currentAttendance; // total = total + currentAttendance;
if (currentAttendance > most) {
most = currentAttendance;
}
if (currentAttendance < least) {
least = currentAttendance;
}
}
average = total / currentEvents.length;
// created 1 object stats for the values above to be able to return
let stats = {
total: total,
average: average,
most: most,
least: least
}
return stats;
}
function displayStats(currentEvents) {
let statistics = calculateStats(currentEvents); //giving the stats object since that is what it is returning from calculateStats(currentEvents)
//get the elements where the stats go
//set their text to be the correct stat form statistics
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();
}
function getEventData() {
let data = localStorage.getItem('kwSuperStarEventData'); //pick a string name unique to you to store in data variable
if (data == null) {
localStorage.setItem('kwSuperStarEventData', JSON.stringify(events))
}
let currentEvents = data == null ? events : JSON.parse(data);
// AKA if (data == null) {
// currentEvents = events;
// } else {
// currentEvents = JSON.parse(data);
// }
return currentEvents;
}
function viewFilteredEvents(dropdownItem) {
let cityName = dropdownItem.getAttribute('data-string');
// get all my events
let allEvents = getEventData();
if (cityName == 'All') {
displayStats(allEvents);
displayEventData(allEvents);
document.getElementById('location').innerText = 'All Events';
}
// filter those events to just selected city
let filteredEvents = allEvents.filter(event => event.city.toLowerCase() == cityName.toLowerCase());
// display the stats for those events
displayStats(filteredEvents);
// change the stats header
document.getElementById('location').innerText = cityName;
// display only those events in the table
displayEventData(filteredEvents);
}
function saveNewEvent() {
//get the form input values
let name = document.getElementById('newEventName').value;
let city = document.getElementById('newCityName').value;
let attendance = parseInt(document.getElementById('newEventAttendance').value, 10);
let dateValue = document.getElementById('newEventDate').value;
dateValue = new Date(dateValue);
let date = dateValue.toLocaleDateString();
let stateSelect = document.getElementById('newEventState');
let selectedIndex = stateSelect.selectedIndex;
let state = stateSelect.options[selectedIndex].text;
// create a new event object
let 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);
//the, save the array with the new event
localStorage.setItem('kwSuperStarEventData', JSON.stringify(events)); //you can only store a string in local storage, reason for stringify
buildDropDown();
}
Explanation:
buildDropDown():
This function generates a dropdown menu on the webpage based on the unique cities present in the data, and sets it as the event filter. It also displays statistics and event data based on the filtered data, and sets the location display accordingly.
displayEventData():
This function is called by buildDropDown() and displays event data in a table based on the current events.
calculateStats():
This function calculates and returns statistics such as the total attendance, average attendance, highest and lowest attendance based on the current events.
displayStats():
This function is called by buildDropDown() and displays statistics based on the current events.
getEventData():
This function retrieves the event data from local storage, and generates unique IDs for the events if not present. It returns the current event data.
viewFilteredEvents():
This function is called when a dropdown item is selected and filters the event data based on the selected city. It displays statistics and event data based on the filtered data, and sets the location display accordingly.
saveNewEvent():
This function saves a new event with the event name, city, state, attendance, and date that are obtained from form inputs.
generateId():
This function generates a random alphanumeric ID using the crypto.getRandomValues() method and bitwise operations. The generated ID is returned as a string.
editEvent():
This function populates a form with the details of a selected event for editing. It takes an event row element as an argument and retrieves the event ID from its data-event attribute. It then uses the ID to find the corresponding event object from an array of events, and populates the form fields with the event details.
deleteEvent():
This function deletes an event from an array of events and updates the list of events in local storage. It retrieves the ID of the event to be deleted from a form field, filters out the event from the array, and saves the updated array to local storage. It then rebuilds the drop-down list of events.
updateEvent():
This function updates the details of an existing event and saves the updated event to local storage. It retrieves the ID of the event to be updated from a form field, and retrieves the updated details from the form fields. It then creates a new event object with the updated details and replaces the existing event object in the array of events. The updated array of events is then saved to local storage, and the drop-down list of events is rebuilt.