-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7f056b6
commit 5527037
Showing
3 changed files
with
438 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" > | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>CodePen - Weather App - FreeCodeCamp</title> | ||
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css'> | ||
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.css'> | ||
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'><link rel="stylesheet" href="./style.css"> | ||
|
||
</head> | ||
<body> | ||
<!-- partial:index.partial.html --> | ||
<div class="container" id="wrapper"> | ||
<div class="container-fluid" id="current-weather"> | ||
<div class="row"> | ||
|
||
<!-- Right panel --> | ||
<div class="col-md-4 col-sm-5"> | ||
<h5><spam id="cityName"></spam>, <spam id="cityCode"></spam></h5> | ||
<h6 id="localDate"></h6> | ||
<h5 id="localTime"></h5> | ||
<a id="refreshButton" href="#"><i class="fa fa-refresh fa-fw" aria-hidden="true"></i> Refresh</a> | ||
</div> | ||
|
||
<!-- Center panel --> | ||
<div class="col-md-5 col-sm-7" style="margin: 10px auto;padding:0;"> | ||
<div class="row"> | ||
<i class="wi" id ="main-icon" style="font-size: 85px;"></i> | ||
<div> | ||
<spam id="mainTemperature"></spam> | ||
<p id="tempDescription"></p> | ||
</div> | ||
<p style="font-size: 1.5rem;"><a href="#" class="active" id="celcius">°C</a> | <a href="#" id="farenheit">°F</a></p> | ||
</div> | ||
</div> | ||
|
||
<!-- Left panel --> | ||
<div class="col-xs-12 col-sm-12 col-md-3 row" style="text-align: right;"> | ||
<div class="col-md-12 col-sm-3 col-xs-3 side-weather-info"> | ||
<h6>Humidity: <spam id="humidity"></spam>%</h6> | ||
</div> | ||
<div class="col-md-12 col-sm-3 col-xs-3 side-weather-info"> | ||
<h6>Wind: <spam id="wind"></spam> m/s</h6> | ||
</div> | ||
<div class="col-md-12 col-sm-3 col-xs-3 side-weather-info"> | ||
<h6>High: <spam id="mainTempHot"></spam>°</h6> | ||
</div> | ||
<div class="col-md-12 col-sm-3 col-xs-3 side-weather-info"> | ||
<h6>Low: <spam id="mainTempLow"></spam>°</h6> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
</div> | ||
|
||
<!-- Modal --> | ||
<div class="modal fade" id="protocol-modal" tabindex="-1" role="dialog"> | ||
<div class="modal-dialog" role="document"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||
</div> | ||
<div class="modal-body"> | ||
<p>Due to weather api restrictions, data can only be shown via HTTP request.</p> | ||
<p>Sorry for the inconvenience.</p> | ||
</div> | ||
<div class="modal-footer"> | ||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<!-- 4 days forecast --> | ||
<div class="container-fluid"> | ||
<div class="row" style="padding: 2px;"> | ||
|
||
<!-- Day 1 --> | ||
<div class="col-md-3 col-sm-6 day-weather-box"> | ||
<div class="col-sm-12 day-weather-inner-box"> | ||
<div class="col-sm-8 forecast-main"> | ||
<p id="forecast-day-1-name"></p> | ||
<div class="row"> | ||
<h5 id="forecast-day-1-main">°</h5> | ||
<i class="wi forecast-icon" id="forecast-day-1-icon"></i> | ||
</div> | ||
</div> | ||
<div class="col-sm-4 forecast-min-low"> | ||
<p><spam class="high-temperature" id="forecast-day-1-ht"></spam></p> | ||
<p><spam class="low-temperature" id="forecast-day-1-lt"></spam></p> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<!-- Day 2 --> | ||
<div class="col-md-3 col-sm-6 day-weather-box"> | ||
<div class="col-sm-12 day-weather-inner-box"> | ||
<div class="col-sm-8 forecast-main"> | ||
<p id="forecast-day-2-name"></p> | ||
<div class="row"> | ||
<h5 id="forecast-day-2-main">°</h5> | ||
<i class="wi forecast-icon" id="forecast-day-2-icon"></i> | ||
</div> | ||
</div> | ||
<div class="col-sm-4 forecast-min-low"> | ||
<p><spam class="high-temperature" id="forecast-day-2-ht"></spam></p> | ||
<p><spam class="low-temperature" id="forecast-day-2-lt"></spam></p> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<!-- Day 3 --> | ||
<div class="col-md-3 col-sm-6 day-weather-box"> | ||
<div class="col-sm-12 day-weather-inner-box"> | ||
<div class="col-sm-8 forecast-main"> | ||
<p id="forecast-day-3-name"></p> | ||
<div class="row"> | ||
<h5 id="forecast-day-3-main">°</h5> | ||
<i class="wi forecast-icon" id="forecast-day-3-icon"></i> | ||
</div> | ||
</div> | ||
<div class="col-sm-4 forecast-min-low"> | ||
<p><spam class="high-temperature" id="forecast-day-3-ht"></spam></p> | ||
<p><spam class="low-temperature" id="forecast-day-3-lt"></spam></p> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<!-- Day 4 --> | ||
<div class="col-md-3 col-sm-6 day-weather-box"> | ||
<div class="col-sm-12 day-weather-inner-box"> | ||
<div class="col-sm-8 forecast-main"> | ||
<p id="forecast-day-4-name"></p> | ||
<div class="row"> | ||
<h5 id="forecast-day-4-main">°</h5> | ||
<i class="wi forecast-icon" id="forecast-day-4-icon"></i> | ||
</div> | ||
</div> | ||
<div class="col-sm-4 forecast-min-low"> | ||
<p><spam class="high-temperature" id="forecast-day-4-ht"></spam></p> | ||
<p><spam class="low-temperature" id="forecast-day-4-lt"></spam></p> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
</div> | ||
</div> | ||
<!-- partial --> | ||
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js'></script> | ||
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.min.js'></script><script src="./script.js"></script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
var unitIsCelcius = true; | ||
var globalForecast = []; | ||
|
||
// Maps the API's icons to the ones from https://erikflowers.github.io/weather-icons/ | ||
var weatherIconsMap = { | ||
"01d": "wi-day-sunny", | ||
"01n": "wi-night-clear", | ||
"02d": "wi-day-cloudy", | ||
"02n": "wi-night-cloudy", | ||
"03d": "wi-cloud", | ||
"03n": "wi-cloud", | ||
"04d": "wi-cloudy", | ||
"04n": "wi-cloudy", | ||
"09d": "wi-showers", | ||
"09n": "wi-showers", | ||
"10d": "wi-day-hail", | ||
"10n": "wi-night-hail", | ||
"11d": "wi-thunderstorm", | ||
"11n": "wi-thunderstorm", | ||
"13d": "wi-snow", | ||
"13n": "wi-snow", | ||
"50d": "wi-fog", | ||
"50n": "wi-fog" | ||
}; | ||
|
||
|
||
$(function(){ | ||
getClientPosition(); | ||
startClock(); | ||
}); | ||
|
||
|
||
function startClock(){ | ||
setInterval(function(){ | ||
$("#localTime").text(new Date().toLocaleTimeString()); | ||
}, 1000); | ||
} | ||
|
||
|
||
function getClientPosition(){ | ||
$.getJSON("https://ipapi.co/json/", function(position) { | ||
$("#cityName").text(position.city); | ||
$("#cityCode").text(position.country); | ||
|
||
getWeatherData(position.latitude, position.longitude); | ||
}); | ||
} | ||
|
||
|
||
function getWeatherData(latitude, longitude){ | ||
$.ajax({ | ||
type: "GET", | ||
url: "https://cors-anywhere.herokuapp.com/http://api.openweathermap.org/data/2.5/forecast/daily?APPID=9b4bbf30228eb8528d36e79d05da1fac&lat=" + latitude + "&lon=" + longitude + "&units=metric&cnt=5", | ||
cache: true, | ||
headers: { | ||
"Access-Control-Allow-Headers": "x-requested-with" | ||
}, | ||
success: function(forecast){ | ||
globalForecast = forecast; | ||
updateForecast(forecast); | ||
|
||
// Stops Refresh button's spinning animation | ||
$("#refreshButton").html("<i class='fa fa-refresh fa-fw'></i> Refresh"); | ||
}, | ||
error: function(error){ | ||
console.log("Error with ajax: "+ error); | ||
} | ||
}); | ||
} | ||
|
||
|
||
// Update view values from passed forecast | ||
function updateForecast(forecast){ | ||
|
||
// Present day | ||
var today = forecast.list[0]; | ||
$("#tempDescription").text(toCamelCase(today.weather[0].description)); | ||
$("#humidity").text(today.humidity); | ||
$("#wind").text(today.speed); | ||
$("#localDate").text(getFormattedDate(today.dt)); | ||
$("#main-icon").addClass(weatherIconsMap[today.weather[0].icon]); | ||
$("#mainTemperature").text(Math.round(today.temp.day)); | ||
$("#mainTempHot").text(Math.round(today.temp.max)); | ||
$("#mainTempLow").text(Math.round(today.temp.min)); | ||
|
||
|
||
// Following days data | ||
for(var i = 1; i < (forecast.list).length; i++){ | ||
var day = forecast.list[i]; | ||
|
||
// Day short format e.g. Mon | ||
var dayName = getFormattedDate(day.dt).substring(0,3); | ||
|
||
// weather icon from map | ||
var weatherIcon = weatherIconsMap[day.weather[0].icon]; | ||
|
||
$("#forecast-day-" + i + "-name").text(dayName); | ||
$("#forecast-day-" + i + "-icon").addClass(weatherIcon); | ||
$("#forecast-day-" + i + "-main").text(Math.round(day.temp.day)); | ||
$("#forecast-day-" + i + "-ht").text(Math.round(day.temp.max)); | ||
$("#forecast-day-" + i + "-lt").text(Math.round(day.temp.min)); | ||
} | ||
} | ||
|
||
|
||
// Refresh button handler | ||
$("#refreshButton").on("click", function(){ | ||
// Starts Refresh button's spinning animation | ||
$("#refreshButton").html("<i class='fa fa-refresh fa-spin fa-fw'></i>"); | ||
getWeatherData(); | ||
}); | ||
|
||
|
||
// Celcius button handler. | ||
// Converts every shown value to Celcius | ||
$("#celcius").on("click", function(){ | ||
if(!unitIsCelcius){ | ||
$("#farenheit").removeClass("active"); | ||
this.className = "active"; | ||
|
||
// main day | ||
var today = globalForecast.list[0]; | ||
today.temp.day = toCelcius(today.temp.day); | ||
today.temp.max = toCelcius(today.temp.max); | ||
today.temp.min = toCelcius(today.temp.min); | ||
globalForecast.list[0] = today; | ||
|
||
// week | ||
for(var i = 1; i < 5; i ++){ | ||
var weekDay = globalForecast.list[i]; | ||
weekDay.temp.day = toCelcius(weekDay.temp.day); | ||
weekDay.temp.max = toCelcius(weekDay.temp.max); | ||
weekDay.temp.min = toCelcius(weekDay.temp.min); | ||
globalForecast[i] = weekDay; | ||
} | ||
|
||
// update view with updated values | ||
updateForecast(globalForecast); | ||
|
||
unitIsCelcius = true; | ||
} | ||
}); | ||
|
||
|
||
// Farenheit button handler | ||
// Converts every shown value to Farenheit | ||
$("#farenheit").on("click", function(){ | ||
if(unitIsCelcius){ | ||
$("#celcius").removeClass("active"); | ||
this.className = "active"; | ||
|
||
// main day | ||
var today = globalForecast.list[0]; | ||
today.temp.day = toFerenheit(today.temp.day); | ||
today.temp.max = toFerenheit(today.temp.max); | ||
today.temp.min = toFerenheit(today.temp.min); | ||
globalForecast.list[0] = today; | ||
|
||
// week | ||
for(var i = 1; i < 5; i ++){ | ||
var weekDay = globalForecast.list[i]; | ||
weekDay.temp.day = toFerenheit(weekDay.temp.day); | ||
weekDay.temp.max = toFerenheit(weekDay.temp.max); | ||
weekDay.temp.min = toFerenheit(weekDay.temp.min); | ||
globalForecast[i] = weekDay; | ||
} | ||
|
||
// update view with updated values | ||
updateForecast(globalForecast); | ||
|
||
unitIsCelcius = false; | ||
} | ||
}); | ||
|
||
|
||
// Applies the following format to date: WeekDay, Month Day, Year | ||
function getFormattedDate(date){ | ||
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; | ||
return new Date(date * 1000).toLocaleDateString("en-US",options); | ||
} | ||
|
||
|
||
// Formats the text to CamelCase | ||
function toCamelCase(str) { | ||
var arr = str.split(" ").map( | ||
function(sentence){ | ||
return sentence.charAt(0).toUpperCase() + sentence.substring(1); | ||
} | ||
); | ||
return arr.join(" "); | ||
} | ||
|
||
|
||
// Converts to Celcius | ||
function toCelcius(val){ | ||
return Math.round((val - 32) * (5/9)); | ||
} | ||
|
||
|
||
// Converts to Farenheit | ||
function toFerenheit(val){ | ||
var degrees = (val * 1.8) + 32; | ||
var rounded = Math.round(degrees); | ||
return rounded; | ||
} |
Oops, something went wrong.