Skip to content

Commit

Permalink
adds complete code at end of Step2 of Weather app. but see: #8 (comment)
Browse files Browse the repository at this point in the history
  • Loading branch information
nelsonic committed May 7, 2016
1 parent dd86529 commit 322705f
Show file tree
Hide file tree
Showing 2 changed files with 300 additions and 2 deletions.
121 changes: 119 additions & 2 deletions demo/pwa-weather/step-02/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather PWA</title>
<!-- Insert link to styles here -->
<link rel="stylesheet" type="text/css" href="styles/inline.css">
</head>
<body>

Expand All @@ -16,11 +17,127 @@ <h1 class="header__title">Weather PWA</h1>
</header>

<main class="main" hidden>
<!-- Insert forecast-card.html here -->
<div class="card cardTemplate weather-forecast" hidden>
<div class="city-key" hidden></div>
<div class="location"></div>
<div class="date"></div>
<div class="description"></div>
<div class="current">
<div class="visual">
<div class="icon"></div>
<div class="temperature">
<span class="value"></span><span class="scale">°F</span>
</div>
</div>
<div class="description">
<div class="feels-like">
<span class="value"></span><span class="scale">°F</span>
</div>
<div class="precip"></div>
<div class="humidity"></div>
<div class="wind">
<span class="value"></span>
<span class="scale">mph</span>
<span class="direction"></span>
</div>
</div>
</div>
<div class="future">
<div class="oneday">
<div class="date"></div>
<div class="icon"></div>
<div class="temp-high">
<span class="value"></span>°
</div>
<div class="temp-low">
<span class="value"></span>°
</div>
</div>
<div class="oneday">
<div class="date"></div>
<div class="icon"></div>
<div class="temp-high">
<span class="value"></span>°
</div>
<div class="temp-low">
<span class="value"></span>°
</div>
</div>
<div class="oneday">
<div class="date"></div>
<div class="icon"></div>
<div class="temp-high">
<span class="value"></span>°
</div>
<div class="temp-low">
<span class="value"></span>°
</div>
</div>
<div class="oneday">
<div class="date"></div>
<div class="icon"></div>
<div class="temp-high">
<span class="value"></span>°
</div>
<div class="temp-low">
<span class="value"></span>°
</div>
</div>
<div class="oneday">
<div class="date"></div>
<div class="icon"></div>
<div class="temp-high">
<span class="value"></span>°
</div>
<div class="temp-low">
<span class="value"></span>°
</div>
</div>
<div class="oneday">
<div class="date"></div>
<div class="icon"></div>
<div class="temp-high">
<span class="value"></span>°
</div>
<div class="temp-low">
<span class="value"></span>°
</div>
</div>
<div class="oneday">
<div class="date"></div>
<div class="icon"></div>
<div class="temp-high">
<span class="value"></span>°
</div>
<div class="temp-low">
<span class="value"></span>°
</div>
</div>
</div>
</div>

</main>

<div class="dialog-container">
<!-- Insert add-new-city-dialog.html here -->
<div class="dialog">
<div class="dialog-title">Add new city</div>
<div class="dialog-body">
<select id="selectCityToAdd">
<option value="austin">Austin, TX</option>
<option value="boston">Boston, MA</option>
<option value="chicago">Chicago, IL</option>
<option value="portland">Portland, OR</option>
<option value="sanfrancisco">San Francisco, CA</option>
<option value="seattle">Seattle, WA</option>
</select>
</div>
<div class="dialog-buttons">
<button id="butAddCity" class="button">Add</button>
<button id="butAddCancel" class="button">Cancel</button>
</div>
</div>

</div>

<div class="loader">
Expand All @@ -30,6 +147,6 @@ <h1 class="header__title">Weather PWA</h1>
</div>

<!-- Insert link to app.js here -->

<script src="/scripts/app.js"></script>
</body>
</html>
181 changes: 181 additions & 0 deletions demo/pwa-weather/step-02/scripts/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@

(function() {
'use strict';

var app = {
isLoading: true,
visibleCards: {},
selectedCities: [],
spinner: document.querySelector('.loader'),
cardTemplate: document.querySelector('.cardTemplate'),
container: document.querySelector('.main'),
addDialog: document.querySelector('.dialog-container'),
daysOfWeek: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
};


/*****************************************************************************
*
* Event listeners for UI elements
*
****************************************************************************/

document.getElementById('butRefresh').addEventListener('click', function() {
// Refresh all of the forecasts
app.updateForecasts();
});

document.getElementById('butAdd').addEventListener('click', function() {
// Open/show the add new city dialog
app.toggleAddDialog(true);
});

document.getElementById('butAddCity').addEventListener('click', function() {
// Add the newly selected city
var select = document.getElementById('selectCityToAdd');
var selected = select.options[select.selectedIndex];
var key = selected.value;
var label = selected.textContent;
app.getForecast(key, label);
app.selectedCities.push({key: key, label: label});
app.toggleAddDialog(false);
});

document.getElementById('butAddCancel').addEventListener('click', function() {
// Close the add new city dialog
app.toggleAddDialog(false);
});


/*****************************************************************************
*
* Methods to update/refresh the UI
*
****************************************************************************/

// Toggles the visibility of the add new city dialog.
app.toggleAddDialog = function(visible) {
if (visible) {
app.addDialog.classList.add('dialog-container--visible');
} else {
app.addDialog.classList.remove('dialog-container--visible');
}
};

// Updates a weather card with the latest weather forecast. If the card
// doesn't already exist, it's cloned from the template.
app.updateForecastCard = function(data) {
var card = app.visibleCards[data.key];
if (!card) {
card = app.cardTemplate.cloneNode(true);
card.classList.remove('cardTemplate');
card.querySelector('.location').textContent = data.label;
card.removeAttribute('hidden');
app.container.appendChild(card);
app.visibleCards[data.key] = card;
}
card.querySelector('.description').textContent = data.currently.summary;
card.querySelector('.date').textContent =
new Date(data.currently.time * 1000);
card.querySelector('.current .icon').classList.add(data.currently.icon);
card.querySelector('.current .temperature .value').textContent =
Math.round(data.currently.temperature);
card.querySelector('.current .feels-like .value').textContent =
Math.round(data.currently.apparentTemperature);
card.querySelector('.current .precip').textContent =
Math.round(data.currently.precipProbability * 100) + '%';
card.querySelector('.current .humidity').textContent =
Math.round(data.currently.humidity * 100) + '%';
card.querySelector('.current .wind .value').textContent =
Math.round(data.currently.windSpeed);
card.querySelector('.current .wind .direction').textContent =
data.currently.windBearing;
var nextDays = card.querySelectorAll('.future .oneday');
var today = new Date();
today = today.getDay();
for (var i = 0; i < 7; i++) {
var nextDay = nextDays[i];
var daily = data.daily.data[i];
if (daily && nextDay) {
nextDay.querySelector('.date').textContent =
app.daysOfWeek[(i + today) % 7];
nextDay.querySelector('.icon').classList.add(daily.icon);
nextDay.querySelector('.temp-high .value').textContent =
Math.round(daily.temperatureMax);
nextDay.querySelector('.temp-low .value').textContent =
Math.round(daily.temperatureMin);
}
}
if (app.isLoading) {
app.spinner.setAttribute('hidden', true);
app.container.removeAttribute('hidden');
app.isLoading = false;
}
};


/*****************************************************************************
*
* Methods for dealing with the model
*
****************************************************************************/

// Gets a forecast for a specific city and update the card with the data
app.getForecast = function(key, label) {
var url = 'https://publicdata-weather.firebaseio.com/';
url += key + '.json';
// Make the XHR to get the data, then update the card
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
var response = JSON.parse(request.response);
response.key = key;
response.label = label;
app.hasRequestPending = false;
app.updateForecastCard(response);
}
}
};
request.open('GET', url);
request.send();
};

// Iterate all of the cards and attempt to get the latest forecast data
app.updateForecasts = function() {
var keys = Object.keys(app.visibleCards);
keys.forEach(function(key) {
app.getForecast(key);
});
};

var fakeForecast = {
key: 'newyork',
label: 'New York, NY',
currently: {
time: 1453489481,
summary: 'Clear',
icon: 'partly-cloudy-day',
temperature: 30,
apparentTemperature: 21,
precipProbability: 0.80,
humidity: 0.17,
windBearing: 125,
windSpeed: 1.52
},
daily: {
data: [
{icon: 'clear-day', temperatureMax: 36, temperatureMin: 31},
{icon: 'rain', temperatureMax: 34, temperatureMin: 28},
{icon: 'snow', temperatureMax: 31, temperatureMin: 17},
{icon: 'sleet', temperatureMax: 38, temperatureMin: 31},
{icon: 'fog', temperatureMax: 40, temperatureMin: 36},
{icon: 'wind', temperatureMax: 35, temperatureMin: 29},
{icon: 'partly-cloudy-day', temperatureMax: 42, temperatureMin: 40}
]
}
};
// Uncomment the line below to test with the provided fake data
// app.updateForecastCard(fakeForecast);

})();

0 comments on commit 322705f

Please sign in to comment.