WinJS – how to create your own custom control !

, , 4 Comments

WinJS comes with several controls out of the box : Listview, FlipView, SemanticZoom, DatePicker, Flyout, etc…

Although they are really powerful and useful, they do not cover all needs and it’s time for us (the community) to provide some other controls.

In this post we’ll see how this can be done. Don’t worry it’s in fact really easy and straightforward.

The steps to create a custom WinJS control are :

  1. Define a namespace and a clas for your control
  2. Initialize the control in the class constructor
  3. Create the visual tree of the control
  4. Declare the control !
  5. Use the control in the javascript code

Define a namespace and a class for the control

WinJS provide some APIs to create namespaces and classes in javascript.
I recommend to use them because it will provide a more structured code and maintainability will be increased.

The naming convention I use is the same than for the standard WinJS controls : PascalCase.

You can also declare some properties/fields in your class. Don’t forget to comment them 🙂 ! In the example below, I expose a element property which will return the element anchor of the control. I also create a private method named _createVisualTree that we will see in depth later in this post.

Here the namespace is “MyNamespace” and the control class name is “MyControl”.
[javascript]
WinJS.Namespace.define("MyNamespace", {
MyControl: WinJS.Class.define(function (element, options) {

//This is the constructor

}, {

/// <field type="HTMLElement" domElement="true" hidden="true"
/// locid="MyNamespace.MyControl.element">
/// Gets the DOM element that hosts the MediaViewer.
/// </field>
element: {
get: function () { return this._element; }
},
_createVisualTree : function (){ /* …*/}

} // END properties

) //END control class definition

}); //END namespace definition
[/javascript]

Initialize the control in the class constructor

When the WinJS.UI.processAll or the WinJS.UI.process method is called in your code, the DOM is parsed by the WinJS engine.

If a control is found, WinJS will instanciate it and call the constructor providing the element which is the anchor of the control and the options provided.

In the constructor, you have to validate the provided options and to be sure that the element is … existing.
It’s also in it that you have to create the visual tree of the control. As you can guess, it depends of the control you create.

Here I simply store the anchor element in a ‘private’ field named _element and I call the _createVisualTree method.
[javascript]
function (element, options) {

//This is the anchor-element of the control
if (!element) {
throw "element must be provided";
}
options = options || {};

//Store the element
this._element = element;

_createVisualTree();

}
[/javascript]

Create the visual tree of the control

I create the visual tree in the previously mentionned method _createVisualTree. Take note that I use a specific name convention to inform potential code reader that the method should not be called from “outside”.

You can create as much element as needed by the control. The Listview for example use the item template you provide to create one DOM element by item in the provided data source.

In this snippet, I simply create a black div inside the element :
[javascript]
_createVisualTree: function () {
var child = document.createElement("div");
child.style.width = "100px";
child.style.height = "100px";
child.style.backgroundColor = "black";

this._element.appendChild(child);
}
[/javascript]

In this case, I take for granted that the anchor element is empty but it can be different. For example the semantic zoom, let you provide two child elements which will be the two “zoom view”. To retrieve them, classic CSS selector are used.

Use the control !

Now that you’ve created all the necessary code, how can you use the control ?
Simply as one another WinJS control : by declaring it in your html page !

You use the data-win-control attribute to set the whole control name (namespace + class name) and you use the data-win-options attribute to sets the options provided to the constructor. When the processAll method is called, the control will be found and the mappping between your control and the html done automatically by WinJS.

Also, don’t forget to add a reference to you js file !

[html] <div data-win-control="MyNamespace.MyControl"
data-win-options="{ kikou : ‘lol’ }"
/>[/html]

Use the control in the javascript code

As an usual control, you can also retrieve the control created for an element using the wintControl property.
[javascript] var myControl= document.getElementById("myControlId").winControl;[/javascript]

More to come

This post is pretty generic and I hope it is really understandable.

Sometimes concrete example are better so I will soon take some time to write a full control and share it with you.

What do you think of this custom-control creation code compared to what you know with XAML ?

 

4 Responses

  1. Peter Morlion

    12/03/2012 14 h 06 min

    I'd say it will have its own difficulties compared to XAML (which also has its complexities). I'm curious about styling and templating these. Interesting post though, thanks!

  2. Alexandar

    03/01/2013 16 h 01 min

    Pretty good explanation. I run in to custom control creation code while looking windows 8 app examples and was very confused. Haven’t been able to find anything about this in windows documentation and your tutorial is pretty much only I could find…. so thanks!

Comments are closed.