Let's complete our page by adding a simple busy indicator spinner:
- Add the HTML in bold to index.html:
<div id="productsContainer" class="clear-fix"></div>
<div class="clear-fix"></div>
<div id="wait" class="loader-container hidden">
<div class="loader"></div>
</div>
- Add the relevant CSS to app.css:
.loader-container {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
background-color: azure;
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
}
.loader {
border: 16px solid #f3f3f3;
border-top: 16px solid #3498db;
border-radius: 50%;
width: 80px;
height: 80px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
- Implement spinner activation in app.js by adding the JavaScript in bold:
function hideBusyIndicator() {
$('#wait').addClass('hidden');
}
function showBusyIndicator() {
$('#wait').removeClass('hidden');
}
function syncProducts() {
const productsContainer = $('#productsContainer');
const category = $('#menu > li').filter('.menu-selected').attr('categoryName');
productsContainer.empty();
showBusyIndicator();
window.api.getProducts(category, items => {
productsContainer.append(
items.map(item => renderTemplate('product-item', item)));
hideBusyIndicator();
});
}
function loadCategories(callback) {
const menu = $('#menu');
showBusyIndicator();
window.api.getCategories(items => {
items[0].className = 'menu-selected';
menu.append(items.map(item => renderTemplate('menu-item', item)));
hideBusyIndicator();
if (callback) callback();
});
}
Congratulations! You have just finished implementing the app's home page. You can now view the complete result in the browser and see it in action, it should look similar to this -