Single Page App – isLoading jQuery Plugin to Indicate Content Loads

imageWhen 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.

image

Then once the page is loaded, it will display the data based on an external template.

image

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

  GitHub NuGet
jQuery jquery/jquery · GitHub jQuery on NuGet
Knockout knockout/knockout · GitHub Knockout on NuGet
koExternalTemplateEngine Knockout.js-External-Template-Engine · GitHub Knockout.js External Template Engine on NuGet
Bootstrap Twitter Bootstrap on GitHub Twitter Bootstrap on Nuget
Font Awesome Font Awesome on GitHub Font Awesome on NuGet
IsLoading isLoading jQuery Plugin on GitHub  

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:


[{"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"}]

view raw

spa-data.json

hosted with ❤ by GitHub

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.


<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>

view raw

spa-header.html

hosted with ❤ by GitHub

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.


<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>

view raw

spa-body.html

hosted with ❤ by GitHub

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


<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.


// 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.


<!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.


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.

image

Apply the isLoading method to jQuery and then release it the same way.


// 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


<div id="myProducts" class="isloading-overlay"></div>

The I apply some style to the div, but you are on your own here:


.isloadingoverlay{
position:relative;
textalign:center;
background:#FFFFFF;
webkitbackgroundclip:paddingbox;
mozbackgroundclip:padding;
backgroundclip:paddingbox;
display:inlineblock;
margin:0 auto;
padding:10px 20px;
top:10%;
zindex:9000;
}

Div Indicator

Or you can apply the loading indicator over the div itself.

$("#myProducts").isLoading({
  text: "Loading",
  position: "overlay"
});

image

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