Show the Local Weather
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://dl.dropbox.com/s/k2hnbpt80dzpe5w/weather-icons.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Asap" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
@font-face {
font-family: "Weather Icons";
src: url(https://dl.dropbox.com/s/h7c1gj4m4hi6kjx/weather-icons.ttf);
}
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body {
background-color: #004966;
color: #fff;
font-family: Asap, sans-serif;
letter-spacing: 2px;
min-height: 100%;
padding-bottom: 60px;
position: relative;
}
h1 {
font-size: 1.2em;
letter-spacing: 4px;
margin: 6% 0;
}
.well {
background-color: #006e99;
border: none;
max-width: 1000px;
}
#location,
#weather {
font-size: 1.2em;
margin: 2%;
text-shadow: 1px 1px 1px #004966;
}
#temp {
font-size: 5em;
text-shadow: 2px 2px 1px #004966;
}
#weather-icon {
font: 4em "Weather Icons";
text-shadow: 2px 2px 1px #004966;
}
.btn,
.btn:active,
.btn:focus {
background-color: #006e99;
border: 1px solid #fff;
color: #fff;
margin: 25px 0;
width: 50px;
}
.btn:hover {
background-color: #004966;
color: #fff;
}
.btn.active {
background-color: #fff;
box-shadow: none;
color: #006e99;
}
.table {
font-size: 1.5rem;
margin: 0 auto 20px;
width: 215px;
}
.table tbody tr td .wi {
font: 1.5rem "Weather Icons";
}
#hourly-forecast {
background-color: #004966;
display: -webkit-flex;
display: flex;
}
#hourly-forecast tbody {
display: -webkit-flex;
display: flex;
overflow-x: auto;
position: relative;
}
#hourly-forecast tbody tr {
display: table-cell;
padding: 18px;
}
#hourly-forecast tbody tr td {
border: none;
display: table-row;
line-height: 25px;
}
#daily-forecast thead tr th {
background-color: #004966;
border: none;
font-size: 1rem;
text-align: center;
}
#daily-forecast tbody tr td {
border-top: 1px solid #004966;
line-height: 22px;
text-align: center;
}
#daily-forecast tbody tr td:nth-child(5) {
display: none;
}
#spinner {
font-size: 4.5rem;
margin: 3%;
text-shadow: 2px 2px 1px #004966;
}
.alert-warning {
margin: 3%;
}
footer {
background-color: #006e99;
bottom: 0;
font-size: 0.9rem;
left: 0;
letter-spacing: 2px;
margin: 0;
padding: 12px 0;
position: absolute;
right: 0;
width: 100%;
}
footer span {
margin: 0 8px;
}
footer a,
footer a:visited,
footer a:hover,
footer a:active,
footer a:focus {
color: #ffff80;
}
@media only screen and (min-width: 350px) {
.table {
width: 285px;
}
}
@media only screen and (min-width: 550px) {
h1 {
font-size: 1.6em;
margin: 6% 0 3%;
}
.table {
font-size: 1.2rem;
width: 460px;
}
#daily-forecast tbody tr td {
text-align: left;
}
#daily-forecast tbody tr td:nth-child(5) {
display: table-cell;
}
footer {
font-size: 1.2rem;
}
footer span {
margin: 0 16px;
}
}
My project for the Show the Local Weather challenge as part of the curriculum for the Front End Development Certification on Free Code Camp.
A Pen by HARUN PEHLİVAN on CodePen.
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap.min.js"></script>
var app = angular.module('myApp', ['ui.bootstrap']);
app.controller('myController', function($scope, $http, $q) {
$scope.loadingSpinner = true;
function getSuccess(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
var weatherAPIKey = '6e76605e3f2672147d041fcb0df33e81';
var geocodingAPI = $http.get('https://maps.googleapis.com/maps/api/geocode/json?latlng=' + lat + ',' + lng);
var weatherAPI = $http.jsonp('https://api.darksky.net/forecast/' + weatherAPIKey + '/' + lat + ',' + lng + '?callback=JSON_CALLBACK');
$q.all([geocodingAPI, weatherAPI]).then(function(data) {
$scope.location = data[0].data.results[0].address_components[3].long_name;
$scope.temp = data[1].data.currently.temperature;
$scope.tempUnit = 'F';
$scope.weatherIcon = 'wi wi-forecast-io-' + data[1].data.currently.icon;
$scope.weather = data[1].data.currently.summary;
$scope.hourly = data[1].data.hourly.data;
$scope.hourlyFahrenheit = true;
$scope.daily = data[1].data.daily.data;
$scope.dailyFahrenheit = true;
$scope.loadingSpinner = false;
$scope.success = true;
$scope.convertToCelsius = function() {
$scope.temp = (data[1].data.currently.temperature - 32) * (5/9);
$scope.tempUnit = 'C';
$scope.hourlyFahrenheit = false;
$scope.hourlyCelsius = true;
$scope.dailyFahrenheit = false;
$scope.dailyCelsius = true;
}
$scope.convertToFahrenheit = function() {
$scope.temp = data[1].data.currently.temperature;
$scope.tempUnit = 'F';
$scope.hourlyCelsius = false;
$scope.hourlyFahrenheit = true;
$scope.dailyCelsius = false;
$scope.dailyFahrenheit = true;
}
}).catch(function() {
$scope.loadingSpinner = false;
$scope.errorMessage = ' Unable to load current weather.';
$scope.errorHandling = true;
});
}
function getError(err) {
$scope.$apply(function() {
$scope.loadingSpinner = false;
$scope.errorMessage = ' ' + err.message + '.';
$scope.errorHandling = true;
});
}
navigator.geolocation.getCurrentPosition(getSuccess, getError);
});
<div data-ng-app="myApp">
<div class="container-fluid text-center">
<!-- HEADER -->
<header>
<h1>View your local weather</h1>
</header>
<div data-ng-controller="myController">
<main>
<div class="well center-block">
<div class="row" data-ng-show="success">
<div class="col-md-6">
<!-- CURRENT WEATHER -->
<div id="location">{{ location }}</div>
<div id="temp">{{ temp | number:0 }}°{{ tempUnit }}</div>
<div><span id="weather-icon" data-ng-class="weatherIcon"></span></div>
<div id="weather">{{ weather }}</div>
<!-- BUTTONS -->
<div class="btn-group">
<button class="btn active" data-ng-model="tempUnit" data-ng-click="convertToFahrenheit()" data-uib-btn-radio="'F'">°F</button>
<button class="btn" data-ng-model="tempUnit" data-ng-click="convertToCelsius()" data-uib-btn-radio="'C'">°C</button>
</div>
</div>
<div class="col-md-6">
<!-- HOURLY FORECAST -->
<table class="table" id="hourly-forecast">
<tbody>
<tr data-ng-repeat="forecast in hourly | limitTo: 24">
<td>{{ forecast.time * 1000 | date:"ha" }}</td>
<td><span class="wi wi-forecast-io-{{ forecast.icon }}"></span><span class="sr-only">{{ forecast.icon }}</span></td>
<td data-ng-show="hourlyFahrenheit">{{ forecast.temperature | number:0 }}°</td>
<td data-ng-show="hourlyCelsius">{{ (forecast.temperature - 32) * (5/9) | number:0 }}°</td>
</tr>
</tbody>
</table>
<!-- FIVE-DAY FORECAST -->
<table class="table" id="daily-forecast">
<thead class="text-uppercase">
<tr>
<th>Day</th>
<th>High/Low</th>
<th colspan="2">Weather</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="forecast in daily | limitTo: 5">
<td>{{ forecast.time * 1000 | date:"EEE" }}</td>
<td data-ng-show="dailyFahrenheit">{{ forecast.temperatureMax | number:0 }}°/{{ forecast.temperatureMin | number:0 }}°</td>
<td data-ng-show="dailyCelsius">{{ (forecast.temperatureMax - 32) * (5/9) | number:0 }}°/{{ (forecast.temperatureMin - 32) * (5/9) | number:0 }}°</td>
<td><span class="wi wi-forecast-io-{{ forecast.icon }}"></span><span class="sr-only">{{ forecast.icon }}</span></td>
<td>{{ forecast.summary }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- LOADING SPINNER -->
<div data-ng-show="loadingSpinner" id="spinner">
<span class="fa fa-refresh fa-spin fa-fw"></span>
<span class="sr-only">Loading...</span>
</div>
<!-- ERROR HANDLING -->
<div class="alert alert-warning text-center" data-ng-show="errorHandling"><span class="fa fa-warning fa-lg fa-fw"></span>{{ errorMessage }}</div>
</div>
</main>
</div>
<!-- FOOTER -->
<footer><span>Coded by <a href="https://gist.github.com/harunpehlivan" target="_blank">HARUN PEHLİVAN</a></span><span>Powered by <a href="https://tr.gravatar.com/tebm" target="_blank">Gravatar</a></span></footer>
</div>
</div>