WinRT JavaScript - WinControls
Written by Mike James   
Monday, 09 January 2012
Article Index
WinRT JavaScript - WinControls
Controls in code

If you are building an HTML5 app specifically for Windows 8 there is a lot to be gained in functionality by using the Windows extensions and giving your app the full Metro style. Microsoft's custom controls are  easy to use once you know how they work.

Articles on WinRT JavaScript

  1. Getting Started
  2. WinControls (this article)
  3. Templates & Data Binding

 

In the first part of this series we looked at the simplest sort of JavaScript application you could construct - basically just an HTML5 page with some code. If you want to remain platform-independent then this is all you need to know and you need to keep away from the Windows extensions. In particular, you need to avoid using the WinControls. If you are building an app specifically for Windows 8, however, there is a lot to be gained in functionality by making you app have the Metro style.

So let's take a look at the way that this all works.

The controls library

The first thing you need to do is to add a reference to controls.js to your project so that the appropriate JavaScript is loaded.

The minimum set of libraries to you need to make use of the WinControls is:

<script type="text/javascript" 
src="/WinJS/js/base.js"></script>
<script type="text/javascript"
src="/WinJS/js/ui.js"></script>
<script type="text/javascript"
src="/WinJS/js/controls.js"></script>
<script type="text/javascript"
src="/WinJS/js/wwaapp.js"></script>

The controls.js library is where the code that implements the controls are and ui.js provides many of the objects needed to implement the UI, including event handlers.

The above scripts need to be loaded as part of the default.html files header.

How controls work

How do you add controls to HTML?

You can't create new tags for them because HTML isn't extensible like other markup languages. What you can do is to use a simple tag like a <div> and augment it with the help of JavaScript. The <div> simply marks the location of the JavaScript generated control in the rest of the HTML generated page. This is a very standard way to creating new controls and you will encounter it in lots of other places. Microsoft has implemented this approach to JavaScript controls in a fairly standards- compliant way by making use of data- attributes. These are the recommended way of adding custom attributes to tags.

So, for example, to create a Rating control you would add:

<div data-win-control="WinJS.UI.Rating">
</div>

at the location in the HTML that you want the control to appear.

What happens is that, when the DOM has finished loading, the JavaScript scans the DOM looking for tags with data-win-control properties. When it finds one, it injects the necessary objects into the DOM to create the control and generates a JavaScript object to represent the control in the program.

So when does the JavaScript scan the DOM looking for data-win-control attributes?

The answer is when you call the:

WinJS.UI.processAll();

function.

You can call the processAll function at any point after the DOM is completely loaded and there are lots of possibilities for when to do this.

When an app is launched the sequence of events fired is:

  1. DOMContentLoaded
  2. activated (also known as mainwindowactivated)
  3. window.load

When an app is resumed only the activated event fires and when the app is refreshed only the DOMContentLoaded and window.load events fire. What this means is that you should put anything that has to deal with restoring the state of the app into the activated event handler and any permanent setup actions that don't need to be repeated in the DOMContentLoads event handler, or perhaps the window.loaded event handler.

In other words, we should put the call to processAll in the DOMContentLoaded event handler:

(function () {
'use strict';
// Uncomment the following line to
//enable first chance exceptions.
// Debug.enableFirstChanceException(true);

WinJS.Application.onmainwindowactivated
 = function (e) {
if (e.detail.kind ===
Windows.ApplicationModel.
Activation.ActivationKind.launch) {
// TODO: startup code here
}
}

document.addEventListener(
"DOMContentLoaded", function (e) {
WinJS.UI.processAll();
});
WinJS.Application.start();
})();

If you now run the program you will see a default ratings control:

 

ratings

 

Notice that this is all standard HTML5 and you could use the same techniques to implement your own custom controls.

What about setting some parameters of the displayed control?

This is also easy as there is another data- attribute that you can set to indicate that the processAll function should set parameters.

For example, the Ratings control has a maxRating property and this can be set using HTML by:

<div id="rating1" 
data-win-control="WinJS.UI.Rating"
data-win-options="{maxRating:10}" >
</div>

Now if you run the program you will discover that the Rating control is displayed with ten stars.

The general idea is that to set properties on the control you set data-win-options to a JSON style object that consists of property:name:value pairs. When processAll reads the data-win-options attribute it simply uses the JSON object to initialize all of the properties of the control to the set values.

For example, as well as maxRating, the Rating control also offers the userRating property which sets the number of stars that are set. You can initialize both properties using:

<div id="rating1" 
data-win-control="WinJS.UI.Rating"
data-win-options="{maxRating:10,
userRating:8}" >
</div>

ratings2

 

Once you have seen the basic mechanism, it is fairly easy to initialize any control properties. It is worth noting that some properties are themselves objects, and so you can have something like:

{property1:{property2:value,
property3:value...}}

which sets property1.property2 to value and so on.



Last Updated ( Wednesday, 18 January 2012 )