-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
202 lines (172 loc) · 7.21 KB
/
script.js
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
$(document).ready(function () {
// OpenWeather API
const apiKey = '767baab1ba615005b7b57e268ed513fe';
// Selectors for HTML elements to display weather information
const cityEl = $('h2#city');
const dateEl = $('h3#date');
const weatherIconEl = $('img#weather-icon');
const temperatureEl = $('span#temperature');
const humidityEl = $('span#humidity');
const windEl = $('span#wind');
const uvIndexEl = $('span#uv-index');
const cityListEl = $('div.cityList');
// Selectors for form elements
const cityInput = $('#city-input');
// Store past searched cities
let pastCities = [];
// Helper function to sort cities from https://www.sitepoint.com/sort-an-array-of-objects-in-javascript/
function compare(a, b) {
// Use toUpperCase() to ignore character casing
const cityA = a.city.toUpperCase();
const cityB = b.city.toUpperCase();
let comparison = 0;
if (cityA > cityB) {
comparison = 1;
} else if (cityA < cityB) {
comparison = -1;
}
return comparison;
}
// Local storage functions for past searched cities
// Load events from local storage
function loadCities() {
const storedCities = JSON.parse(localStorage.getItem('pastCities'));
if (storedCities) {
pastCities = storedCities;
}
}
// Store searched cities in local storage
function storeCities() {
localStorage.setItem('pastCities', JSON.stringify(pastCities));
}
// Functions to build the URL for the OpenWeather API call
function buildURLFromInputs(city) {
if (city) {
return `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`;
}
}
function buildURLFromId(id) {
return `https://api.openweathermap.org/data/2.5/weather?id=${id}&appid=${apiKey}`;
}
// Function to display the last 5 searched cities
function displayCities(pastCities) {
cityListEl.empty();
pastCities.splice(5);
let sortedCities = [...pastCities];
sortedCities.sort(compare);
sortedCities.forEach(function (location) {
let cityDiv = $('<div>').addClass('col-12 city');
let cityBtn = $('<button>').addClass('btn btn-light city-btn').text(location.city);
cityDiv.append(cityBtn);
cityListEl.append(cityDiv);
});
}
// Function to color the UV Index based on EPA color scale: https://www.epa.gov/sunsafety/uv-index-scale-0
function setUVIndexColor(uvi) {
if (uvi < 3) {
return 'green';
} else if (uvi >= 3 && uvi < 6) {
return 'yellow';
} else if (uvi >= 6 && uvi < 8) {
return 'orange';
} else if (uvi >= 8 && uvi < 11) {
return 'red';
} else return 'purple';
}
// Search for weather conditions by calling the OpenWeather API
function searchWeather(queryURL) {
// Create an AJAX call to retrieve weather data
$.ajax({
url: queryURL,
method: 'GET'
}).then(function (response) {
// Store current city in past cities
let city = response.name;
let id = response.id;
// Remove duplicate cities
if (pastCities[0]) {
pastCities = $.grep(pastCities, function (storedCity) {
return id !== storedCity.id;
})
}
pastCities.unshift({ city, id });
storeCities();
displayCities(pastCities);
// Display current weather in DOM elements
cityEl.text(response.name);
let formattedDate = moment.unix(response.dt).format('L');
dateEl.text(formattedDate);
let weatherIcon = response.weather[0].icon;
weatherIconEl.attr('src', `http://openweathermap.org/img/wn/${weatherIcon}.png`).attr('alt', response.weather[0].description);
temperatureEl.html(((response.main.temp - 273.15) * 1.8 + 32).toFixed(1));
humidityEl.text(response.main.humidity);
windEl.text((response.wind.speed * 2.237).toFixed(1));
// Call OpenWeather API OneCall with lat and lon to get the UV index and 5 day forecast
let lat = response.coord.lat;
let lon = response.coord.lon;
let queryURLAll = `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&appid=${apiKey}`;
$.ajax({
url: queryURLAll,
method: 'GET'
}).then(function (response) {
let uvIndex = response.current.uvi;
let uvColor = setUVIndexColor(uvIndex);
uvIndexEl.text(response.current.uvi);
uvIndexEl.attr('style', `background-color: ${uvColor}; color: ${uvColor === "yellow" ? "black" : "white"}`);
let fiveDay = response.daily;
// Display 5 day forecast in DOM elements
for (let i = 0; i <= 5; i++) {
let currDay = fiveDay[i];
$(`div.day-${i} .card-title`).text(moment.unix(currDay.dt).format('L'));
$(`div.day-${i} .fiveDay-img`).attr(
'src',
`http://openweathermap.org/img/wn/${currDay.weather[0].icon}.png`
).attr('alt', currDay.weather[0].description);
$(`div.day-${i} .fiveDay-temp`).text(((currDay.temp.day - 273.15) * 1.8 + 32).toFixed(1));
$(`div.day-${i} .fiveDay-humid`).text(currDay.humidity);
}
});
});
}
// Function to display the last searched city
function displayLastSearchedCity() {
if (pastCities[0]) {
let queryURL = buildURLFromId(pastCities[0].id);
searchWeather(queryURL);
} else {
// if no past searched cities, load Detroit weather data
let queryURL = buildURLFromInputs("Detroit");
searchWeather(queryURL);
}
}
// Click handler for search button
$('#search-btn').on('click', function (event) {
// Preventing the button from trying to submit the form
event.preventDefault();
// Retrieving and scrubbing the city from the inputs
let city = cityInput.val().trim();
city = city.replace(' ', '%20');
// Clear the input fields
cityInput.val('');
// Build the query url with the city and searchWeather
if (city) {
let queryURL = buildURLFromInputs(city);
searchWeather(queryURL);
}
});
// Click handler for city buttons to load that city's weather
$(document).on("click", "button.city-btn", function (event) {
let clickedCity = $(this).text();
let foundCity = $.grep(pastCities, function (storedCity) {
return clickedCity === storedCity.city;
})
let queryURL = buildURLFromId(foundCity[0].id)
searchWeather(queryURL);
});
// Initialization - when page loads
// load any cities in local storage into array
loadCities();
displayCities(pastCities);
// Display weather for last searched city
displayLastSearchedCity();
});