HTML5 Zone is brought to you in partnership with:

Gil Fink, Microsoft MVP, is an expert in Web development and Microsoft data platform. He works as a senior architect at Sela Group. He is currently consulting for various enterprises and companies, where he architects and develops Web and RIA-based solutions. He conducts lectures and workshops for developers and enterprises who want to specialize in infrastructure and Web development. He is also a co-author of several Microsoft Official Courses and training kits. You can read his publications at his blog: http://blogs.microsoft.co.il/blogs/gilf. Gil is a DZone MVB and is not an employee of DZone and has posted 147 posts at DZone. You can read more from them at their website. View Full User Profile

How to Write a WinJS Custom Control - Take Two

10.30.2012
| 2305 views |
  • submit to reddit
In a previous post, I showed how to create a WinJS custom control that adds support to textbox autocomplete using the HTML5 datalist element. I was asked how I can improve this control to support remote data scenarios so I updated the source code to show how to achieve that. Note that if you are not familiar with WinJS.Promise object which is used in the solution, you can read about it in MSDN before you proceed.

The Updated Control

Here is the source code for the updated control:

(function (WinJS) {
    WinJS.Namespace.define("MyApp.UI", {
        Autocomplete: WinJS.Class.define(function (element, options) {
            if (!element || element.tagName.toLowerCase() !== "input") throw "input type must be provided";
            var that = this;
            options = options || {};
            that._setElement(element);
            this._element.winControl = this;
            WinJS.UI.setOptions(this, options);
 
            if (options.remoteDataSource) {
                options.remoteDataSource.then(function (optionList) {
                    that._setOptionList(optionList);

The main change here is that I expect to get a remoteDataSource WinJS.Promise parameter as part of the options object. If it exists, I use the then function of WinJS.Promise object to wait for the asynchronous remote data retrieval to finish. When it does, I can use the _setOptionList and _createDataList functions.

The Updated Data Source

Now that there is support for both synchronous and asynchronous data retrieval, you can mimic remote data retrieval by creating a fulfilled WinJS.Promise object. Here is the new code in data.js file:

(function () {
    "use strict";

    var citiesList = ["Seattle", "Las Vegas", "New York", "Salt lake City"];

    WinJS.Namespace.define("Data", {
        citiesAsync: new WinJS.Promise(function (complete) {
            complete(citiesList);
        }),
        cities: citiesList
    });
})();

As you can see, I’m creating the cities list and then return it as a fulfilled WinJS.Promise. The citiesAsync property could be set to the outcome of using WinJS.xhr object or any other asynchronous operation.

The Updated home.html File

To complete the example, you should change the home.html to include another textbox. The new textbox will have the remoteDataSource option property set to Data.citiesAsync:

<input type="text" name="txtCitiesAsync" id="txtCitiesAsync" data-win-control="MyApp.UI.Autocomplete" data-win-options="{ remoteDataSource: Data.citiesAsync }"/>

That is all.

Summary

In this post I showed how to change a custom control to support async data retrieval as part of its creation. I use the WinJS.Promise object to do that.

 

 

 

Published at DZone with permission of Gil Fink, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)