-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
225 lines (210 loc) · 9.14 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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// global variables
let today = moment();
let lat;
let lon;
let retrArr = JSON.parse(localStorage.getItem("city")) || "null";
let appid = "99686e16316412bc9b27bd9cb868d399";
let UVIndex;
let displayedCity = localStorage.getItem("displayedCity");
// this function builds a url to make UV request using jQuery param method
function buildUVIndexUrl(){
let url = "https://api.openweathermap.org/data/2.5/uvi?";
var queryParams = { "appid": "99686e16316412bc9b27bd9cb868d399"};
queryParams.lat = lat;
queryParams.lon = lon;
return url + $.param(queryParams);
}
// a function to update the DOM with current weather and cities searched
function updateLocationPage(location){
let city = location.name;
//save it in local storage with key "displayedCity"
localStorage.setItem("displayedCity", city);
//grap it out from local storage so that it updates whenever there is an ajax call
displayedCity = localStorage.getItem("displayedCity");
//take out array saved in local storage with the key "city" and call it cityArr
let cityArr = JSON.parse(localStorage.getItem("city"));
// if cityArr is not found
if (!cityArr) {
//make cityArr and empty array
cityArr = [];
//push it to cityArr
cityArr.push(city);
// stringfy and store it in the local storage with "city" as a key
localStorage.setItem("city", JSON.stringify(cityArr));
}
// if cityArr is found in local storage
else {
//if city is already not searched before and not in cityArr, push it and store it
if(cityArr.indexOf(city) === -1){
cityArr.push(city);
// stringfy and store it in the local storage with "city" as a key
localStorage.setItem("city", JSON.stringify(cityArr));
}
}
// grap from local storage, parse it and call it retrArr, to make sure retrArr updates after every ajax call
retrArr = JSON.parse(localStorage.getItem("city"));
//take icon from weather array inside the location object
let icon = location.weather[0].icon;
//use icon to create a url which will be src for an img element below
let src = `https://openweathermap.org/img/wn/${icon}.png`
$(".list-group-flush").empty();
// loop through retrArr
for(let i = 0; i < retrArr.length; i++){
// create a list elemtn with the class shown
let liEl = $(`<li class='list-group-item'>`);
//update the textContent of the list created with array elements
liEl.text(retrArr[i]);
// append it to the ul element containing list-group-flush class
$(".list-group-flush").prepend(liEl);
}
// make the div contaning id main-body visible
$("#main-body").removeClass("d-none");
// fill the element containing id city-title with city name, date and imge that shows weather icon
$("#city-title").html(`${city} (${today.format("L")}) <img src=${src}>`)
// convert temprature to farheniet and place it in the element containing id temp
$("#temp").html(`Temprature: ${convertKtoF(parseFloat(location.main.temp)).toFixed(2)}°F`)
// humidity also placed in the DOM
$("#humidity").text(`Humidity: ${location.main.humidity}%`)
// wind speed also placed in the DOm
$("#wind-speed").text(`Wind Speed: ${location.wind.speed}MPH`)
// grap longtide and latitiude from location onject
lon = location.coord.lon;
lat = location.coord.lat;
// using the lon and lat variables call buildUVIndexUrl function
let UVUrl = buildUVIndexUrl();
// make ajax call
$.ajax({
url: UVUrl,
method: "GET"
}).then(function(res){
// get the UVindex
UVIndex = res.value;
// update the DOM by invoking UpdateUVIndex function
UpdateUVIndex();
})
}
//this function converts Kelvin to Farenheit
function convertKtoF(tempInKelvin) {
return ((tempInKelvin - 273.15) * 9 / 5 + 32);
}
// this function updates the UVindex in the DOM and changes the color of the button
// containing UV index depending on the calue of the UV index
function UpdateUVIndex(){
if(UVIndex > 8.00){
$("#uv-index").addClass("btn-danger");
$("#uv-index").removeClass("btn-success");
$("#uv-index").removeClass("btn-warning");
} else if(UVIndex < 8.00 && UVIndex > 3.00) {
$("#uv-index").addClass("btn-warning");
$("#uv-index").removeClass("btn-danger");
$("#uv-index").removeClass("btn-sucess");
} else {
$("#uv-index").addClass("btn-success");
$("#uv-index").removeClass("btn-danger");
$("#uv-index").removeClass("btn-warning");
}
$("#uv-label").text(`UV-Index: `)
$("#uv-index").text(`${UVIndex}`)
}
// function to update the 5-day forecast html file
function updateForecastpage(forecast){
// select the list array from the forcast object
let listArr = forecast.list;
let i = 5;
// loop through listArr for every 8th index after starting on the 5th index
while(i < listArr.length){
let newForecast = listArr[i];
i +=8;
// grap icon
let icon = newForecast.weather[0].icon;
// use icon to assemble a src to be used in img tag later
let src = `https://openweathermap.org/img/wn/${icon}.png`;
// create a div with the classes shown and call it cardCol
let cardCol = $('<div class="col-md-2 card pl-1 bg-primary">');
// create a another div with the classes shown and call it cardCol
let cardBody = $('<div class="card-body p-0">');
// create h5 and fill the text as shown here
let h5El = $("<h5>").text(moment(newForecast.dt_txt).format("L"));
// create img tag and make its source the src variable defined above
let imgEl = $("<img>").attr("src", src);
//create a p tag and fill its innerHTML as sown
let p1El = $("<p>").html(`Temp: ${convertKtoF(parseFloat(newForecast.main.temp)).toFixed(2)}°F`)
// create an other p and fill the textContent as shown
let p2El = $("<p>").text(`Humidity: ${newForecast.main.humidity}%`)
// append the created html elements in the order shown and finally append them to the div that contains
// card-deck class
cardBody.append(h5El);
cardBody.append(imgEl);
cardBody.append(p1El);
cardBody.append(p2El);
cardCol.append(cardBody);
$(".card-deck").append(cardCol);
}
// make the html element containing id 5d-forecast visible
$("#5d-forecast").removeClass("d-none");
}
// this function takes the last index in the retrArr and makes an ajax call
function renderCity(city) {
// the url to make weather ajax call with the parameter on this function
let url = `https://api.openweathermap.org/data/2.5/weather?appid=${appid}&q=${city}`;
// the url to make a forecast ajax call with the parameter on this function
let forecastUrl = `https://api.openweathermap.org/data/2.5/forecast?appid=${appid}&q=${city}`;
// ajax call
$.ajax({
url: url,
method: "GET"
})
// if the ajax call fails - alert and return
.fail(function () {
alert("Not a valid city, try again.");
})
// the call back function is updateLocationPage
.then(updateLocationPage)
// ajax call
$.ajax({
url: forecastUrl,
method: "GET"
})
// the call back function is updateForecastpage
.then(updateForecastpage)
}
// when the page loads - if displayedCity variable is available, run renderCity function by
// taking displayedCity variable
if(displayedCity){
renderCity(displayedCity)
}
// listen to a click event on search button - push the text input value in to local-storage array and call renderCity function
$("#search-button").on("click", function(event){
event.preventDefault();
// empty the div that displays the 5-day forecast
$(".card-deck").empty();
// empty the ul elements that displays the list of cities searched
$(".list-group-flush").empty();
// grap the value from text input and call it city
let city = $("#city-name").val().trim();
// if a user enters empty string, alert and render the last city in the array and then return(dont save empty string)
if(city === ""){
alert("You have to enter a valid city name");
return;
}
//making sure city is not a number
else if(isNaN(city) === false){
alert("Numbers are not accepted, try again");
return;
}
renderCity(city);
})
// listening to a click on city lists
$(document).on("click", ".list-group-item", function(event){
event.preventDefault();
// empty the div that displays the 5-day forecast
$(".card-deck").empty();
// grab the value of the cliked list and call it clickedCity
let clickedCity = $(this).text();
//save it local storage with a key displayedCity;
localStorage.setItem("displayedCity", clickedCity)
//get it out from localStorage so tha it updated after every city click
displayedCity = localStorage.getItem("displayedCity");
//Invoke renderCity function with a new clickedCity variable
renderCity(clickedCity)
});