When you’re loading information using jQuery AJAX, you may want to provide visual feedback when loading data or for any action that would take time.
In this Snippet, you will learn how to:
- Load JSON data from a getJSON call to our server.
- Show and hide a spinning indicator inside a div.
- Bind the incoming data to a view model object.
- Use the view model to populate an external template.
Then once the page is loaded, it will display the data based on an external template.
And we’ll provide some tips on how you you can use the IsLoading library to display the loading indicator on top of the page while loading and on top of the div itself.
About isLoading
isLoading is a simple jQuery plugin that checks if all content (or any action) of your web page has been loaded and then triggers a visual feedback to your visitors. It also can disable form elements and put an overlay an specified area or whole page while the loading is active.
The Technologies
To do this, we’ll combine a variety of technologies that we can use for our single-page-application (SPA). In this snippet, we’ll use:
- jQuery to load our data.
- Knockout to bind the data to viewmodel.
- koExternalTemplateEngine to bind our to an external Knockout template.
- Bootstrap.js to provide formatting for our loading spinner.
- Font Awesome will provide the spinner icon.
- IsLoading will provide the functions to display and hide the spinner.
Where to Get the JavaScript Libraries
Each of the home pages has Getting Started sections. And you can find tutorials on this site for each one too.
Incoming Data
The incoming data is JSON. And it looks like this:
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
[{"id":1,"name":"Tomato soup","category":"Groceries","price":1.39, | |
"freshness":"2013-08-01T00:00:00"}, | |
{"id":2,"name":"Yo-yo","category":"Toys","price":3.75, | |
"freshness":"2013-09-01T00:00:00"}, | |
{"id":3,"name":"Hammer","category":"Hardware","price":16.99, | |
"freshness":"2013-08-06T00:00:00"}] |
Note that the data is an array of items that we know are products. Each item has a id, name, category, price, and freshness property.
Set the Header
You will need style sheets for both Bootstrap and Font Awesome in the head.
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
<head> | |
<title>Simple Render Named Template in Knockout With the Spinner in a div</title> | |
<link href="Content/bootstrap-responsive.css" rel="stylesheet" /> | |
<link href="Content/font-awesome.css" rel="stylesheet" /> | |
</head> |
NOTE: Font Awesome assumes that the .eot, .svg, .ttf, .woff, .otf fonts are available in a sub-folder named font.
NOTE: Be sure to update the Web.Config files as shown in Setting MIME Types (Font Awesome or Custom Fonts or Json File Extensions Doesn’t Work When Deployed on Windows).
The Body
To keep this example simple, we will have minimal text formatting.
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
<h2>Products</h2> | |
<p>Here are the products:</p> | |
<section id="myProducts"> | |
</section> | |
<!– container for the teaplate –> | |
<ul data-bind="template: { name: 'ProductTemplate', foreach: products }"></ul> |
NOTE: I could not get the Knockout template to display when it was inside the section used by IsLoading.
The Template
The template itself is in a separate file named ProductTemplate.html. It just puts the data into a list item.
By default, koExternalTemplateEngine will look into the same folder for a template with the .html extension for this template and load it.
ProductTemplate.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
<li> | |
<span data-bind="text: name"></span> | | |
<span data-bind="text: price"></span> | | |
<span data-bind="text: freshness"></span> | |
</li> |
The JavaScript
Load the libraries.
<script src="Scripts/jquery-2.0.2.js"></script> http://span http://span http://span <script src="Scripts/jquery.isloading.js"></script>
In real life, you can optimize these files, put them into modules, and more. But for the sake of this snippet, we can just load the libraries.
The Snippet
Now we get to our snippet.
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
// Create the model and the viewModel | |
var model = []; | |
var viewModel = { | |
products: ko.observableArray(model) | |
}; | |
// When the page is ready, set up the loading indicator | |
// and load the data | |
$(document).ready(function () { | |
// Set the myProducts element to receive the loading indicator | |
$("#myProducts").isLoading({ | |
text: "Loading", | |
position: "inside", | |
}); | |
// Load the data into the model | |
$.getJSON( | |
"/api/products/", | |
function (model) { | |
// Do something that take a couple seconds so we can | |
// see the spinner | |
var a = 0; | |
setTimeout(function () { | |
var b = a * 5000; | |
}, 2000); | |
// Hide the loading indicator | |
$("#myProducts").isLoading("hide"); | |
// Bind the data to the viewModel | |
viewModel.products(model); | |
} | |
); | |
// Apply the Knockout bindings | |
ko.applyBindings(viewModel); | |
}); |
The key parts are:
- isLoading, which provides the text and the position inside the myProducts element.
- Upon success, then to hide the loading indicator using $(“#myProducts”).isLoading(“hide”);
- And then setting up the viewModel, and applying the binding.
The Entire Page
The following shows the page.
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Simple Render Named Template in Knockout With the Spinner in a div</title> | |
<link href="Content/bootstrap-responsive.css" rel="stylesheet" /> | |
<link href="Content/font-awesome.css" rel="stylesheet" /> | |
</head> | |
<body> | |
<h2>Products</h2> | |
<p>Here are the products:</p> | |
<div id="myProducts"> | |
</div> | |
<ul data-bind="template: { name: '5b-ViewProductTemplate', foreach: products }"> </ul> | |
<script src="Scripts/jquery-2.0.2.js"></script> | |
<script src="Scripts/knockout-2.2.1.js"></script> | |
<script src="Scripts/koExternalTemplateEngine_all.js"></script> | |
<script src="Scripts/bootstrap.js"></script> | |
<script src="Scripts/jquery.isloading.js"></script> | |
<script> | |
// Create the model and the viewModel | |
var model = []; | |
var viewModel = { | |
products: ko.observableArray(model) | |
}; | |
// When the page is ready, set up the loading indicator | |
// and load the data | |
$(document).ready(function () { | |
// Set the myProducts element to receive the loading indicator | |
$("#myProducts").isLoading({ | |
text: "Loading", | |
position: "inside", | |
}); | |
// Load the data into the model | |
$.getJSON( | |
"/api/products/", | |
function (model) { | |
// Do something that take a couple seconds so we can | |
// see the spinner. Be sure to remove | |
var a = 0; | |
setTimeout(function () { | |
var b = a * 5000; | |
}, 2000); | |
// Hide the loading indicator | |
$("#myProducts").isLoading("hide"); | |
// Bind the data to the viewModel | |
viewModel.products(model); | |
} | |
); | |
// Apply the Knockout bindings | |
ko.applyBindings(viewModel); | |
}); | |
</script> | |
</body> | |
</html> |
Do not forget the template in the ProductTemplate.html file, shown in a previous section.
Options Displays for Your Loading Indicator
You should go deeper into the isLoading documentation for other ways to display the indicators. But suffice it to say, there are a couple more variations for the isLoading parameters.
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
defaults = { | |
'position': "right", // right | inside | overlay | |
'text': "", // Text to display next to the loader | |
'class': "icon-refresh", // loader CSS class | |
'tpl': '<span class="isloading-wrapper %wrapper%">%text%<i class="%class% icon-spin"></i></span>', | |
'disableSource': true, // true | false | |
'disableOthers': [] | |
}; |
disableSource and disableOthers is used specify which buttons and other controls you want to disable during the load.
See isLoading | jQuery plugin for complete examples. The keys to understanding the samples on those pages are shown in the following section.
Page Indicator
You can set the indicator to be in a modal dialog to the page itself.
Apply the isLoading method to jQuery and then release it the same way.
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
// Apply isLoading to jQuery | |
$.isLoading({ | |
text: "Loading" | |
}); | |
// Release it when you have finished loading data for your page | |
$.isLoading("hide"); |
You will want some style your div. So in my samples I replaced myProducts div with
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
<div id="myProducts" class="isloading-overlay"></div> |
The I apply some style to the div, but you are on your own here:
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
.isloading–overlay{ | |
position:relative; | |
text–align:center; | |
background:#FFFFFF; | |
–webkit–background–clip:padding–box; | |
–moz–background–clip:padding; | |
background–clip:padding–box; | |
display:inline–block; | |
margin:0 auto; | |
padding:10px 20px; | |
top:10%; | |
z–index:9000; | |
} |
Div Indicator
Or you can apply the loading indicator over the div itself.
$("#myProducts").isLoading({ text: "Loading", position: "overlay" });
Sample Code
Sample code for this is Loading is available on the DevDays GitHub repository in https://github.com/devdays/single-page-app/tree/master/isLoading
References
jQuery Plugin For Checking Content Has Been Loaded – is loading
isLoading | jQuery plugin demo page