Voice Of A Developer: Adding WinJS To Your Web App - Part 36

Before moving further, let us look at the previous articles of the series

JavaScript is a language of the Web. This series of articles will talk about my observations learned during my decade of software development experience with JavaScript, and what mistakes a developer generally makes and what differences they should be aware of.

Introduction

WinJS

WinJS is a Windows library for JavaScript. WinJS provides the controls. You need to make your app professional, equipped with the modern UI controls and include JS, CSS, and HTML all in one place. It is an open-source library by Microsoft and the source code is available at GitHub.

What’s the use of WinJS?

WinJS contains the standard implementation of Win 8 controls which aren’t covered by HTML5. It makes it possible to add Windows UI controls in HTML such as:

  • AppBar
  • DatePicker
  • FlipView
  • Flyout
  • ListView
  • Rating
  • SemanticZoom
  • TimePicker
  • ToggleSwitch
  • Tooltip
  • ViewBox
    and many more…

I found these controls pretty cool as it enhances your webApp UI experience. Microsoft developed this for a universal experience across Win 8 and HTML apps, where you can add WinJS.

Which frameworks are supported by WinJS?

WinJS provides support to the three popular JavaScript frameworks via adapters. These are:

  • Angular
  • React
  • Knockout

What is an adapter?

An adapter is a slim layer, which facilitates the usage of WinJS controls with the above three frameworks. Hence, there are different adapters available.

Create your first WinJS application

I will leverage the AngularJS adapter to build my first WinJS Application. I use the Yeoman Angular generator to scaffold my Application. Yeoman is a fantastic tool to kickstart new projects. For more information, visit here.

Setup basic AngularJS webapp

  • Go to command prompt, type YO and it will show you the list of installed generators.
  • cmd

    You must install the Angular generator before you can use it. If you can’t find the installed Angular generator, then scroll below to see the option:

    cmd

    You will see the list of matching generators.

    cmd

    Select the top, “Angular,” to install it.
  • Now, fire YO command again and create a project using “Angular” generator and it will prompt multiple options. Hence, select accordingly.

    command

  • Now, you are done with your basic scaffold Application.
  • Run the basic Application, using GRUNT command. The default port on which it runs is 9000.

    command

    Output
    Output
  • Go to the directory and the basic structure is ready for you.

    directory

Add WinJS in your application

There are multiple ways to include WinJS in your Application.

  • Dowload WinJS from GIT.
  • Refer from CDN.
  • Use command prompt tools npm, bower [I prefer this way].
  • Fire the commands shown below in your WebApp console location.

     npm install winjs
     bower install winjs

    This will install WinJS files under app\bower_components folder.

  • As I mentioned earlier, we’ll add the AngularJS adapter, hence, fire the command shown below:

     bower install angularjs-winjs

Goto directory app\bower_components and see the folder structure, shown below:

directory

  • Modify below files as

    index.html:
    For our WebApp, we shall include all the relevant WinJS and the adapter files:
    1. <script src="bower_components/angular/angular.js"></script>   
    2. <script src="bower_components/angular-route/angular-route.js"></script>   
    3. <script src="bower_components/winjs/js/base.js"></script>  
    4. <script src="bower_components/winjs/js/ui.js"></script>  
    5. <script src="bower_components/angular-winjs/js/angular-winjs.js"></script>   
    6. <link href="bower_components/winjs/css/ui-dark.css" rel="stylesheet" />  
    The index.html will be transformed, as shown below:
    1. <!doctype html>  
    2. <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->  
    3. <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->  
    4. <!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->  
    5. <!--[if gt IE 8]><!-->  
    6. <html class="no-js">  
    7. <!--<![endif]-->  
    8.   
    9. <head>  
    10.     <meta charset="utf-8">  
    11.     <meta http-equiv="X-UA-Compatible" content="IE=edge">  
    12.     <title></title>  
    13.     <meta name="description" content="">  
    14.     <meta name="viewport" content="width=device-width">  
    15.     <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->  
    16.   
    17.     <!-- build:css(.tmp) styles/main.css -->  
    18.     <link rel="stylesheet" href="styles/main.css">  
    19.     <!-- endbuild -->  
    20. </head>  
    21.   
    22. <body ng-app="NewAppApp">  
    23.     <!--[if lt IE 7]>  
    24. <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>  
    25. <![endif]-->  
    26.   
    27.     <!--[if lt IE 9]>  
    28. <script src="bower_components/es5-shim/es5-shim.js"></script>  
    29. <script src="bower_components/json3/lib/json3.min.js"></script>  
    30. <![endif]-->  
    31.   
    32.     <!-- Add your site or application content here -->  
    33.     <div class="container" ng-view=""></div>  
    34.   
    35.     <!-- Google Analytics: change UA-XXXXX-X to be your site's ID -->  
    36.     <script>  
    37.         (function(i, s, o, g, r, a, m)  
    38.          {  
    39.             i['GoogleAnalyticsObject'] = r;  
    40.             i[r] = i[r] || function()  
    41.             {  
    42.                 (i[r].q = i[r].q || []).push(arguments)  
    43.             }, i[r].l = 1 * new Date();  
    44.             a = s.createElement(o),  
    45.                 m = s.getElementsByTagName(o)[0];  
    46.             a.async = 1;  
    47.             a.src = g;  
    48.             m.parentNode.insertBefore(a, m)  
    49.         })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');  
    50.   
    51.         ga('create', 'UA-XXXXX-X');  
    52.         ga('send', 'pageview');  
    53.     </script>  
    54.     <script src="bower_components/angular/angular.js"></script>  
    55.     <script src="bower_components/angular-route/angular-route.js"></script>  
    56.     <script src="bower_components/winjs/js/base.js"></script>  
    57.     <script src="bower_components/winjs/js/ui.js"></script>  
    58.     <script src="bower_components/angular-winjs/js/angular-winjs.js"></script>  
    59.     <link href="bower_components/winjs/css/ui-dark.css" rel="stylesheet" />  
    60.   
    61.   
    62.   
    63.     <!-- build:js({.tmp,app}) scripts/scripts.js -->  
    64.     <script src="scripts/app.js"></script>  
    65.     <script src="scripts/controllers/main.js"></script>  
    66.     <!-- endbuild -->  
    67. </body>  
    68.   
    69. </html>  
    App.js: We know this is the starting file of AngularJS and we shall include WinJS module dependency, as shown below:
    1. 'use strict';  
    2. angular.module('NewAppApp', ['winjs', 'ngRoute'])  
    3.     .config(function($routeProvider)  
    4.     {  
    5.         $routeProvider  
    6.             .when('/',  
    7.             {  
    8.                 templateUrl: 'views/main.html',  
    9.                 controller: 'MainCtrl'  
    10.             })  
    11.             .otherwise  
    12.             ({  
    13.                 redirectTo: '/'  
    14.             });  
    15.     });  
    Main.html: Modify main.html file and include the directive win-rating, as shown below:
    1. <win-rating max-rating="maxRating" user-rating="rating"></win-rating>  
    2. <div>  
    3.     <h2 class="win-h2">Rating: {{rating}}</h2>  
    4.     <input class="win-slider" type="range" min="1" max="{{maxRating}}" ng-model="rating" />  
    5. </div>  
    6. <div>  
    7.     <h2 class="win-h2">Maximum Rating: {{maxRating}}</h2>  
    8.     <input class="win-slider" type="range" min="1" max="50" ng-model="maxRating" />  
    9. </div>  
    Main.js: In above main.html, we are using two variable, “rating” and “maxRating,” and we can initialize their value in MainCtrl (controller),
    1. 'use strict';  
    2.   
    3. angular.module('NewAppApp')  
    4.     .controller('MainCtrl', function($scope)  
    5.     {  
    6.         $scope.rating = 1;  
    7.         $scope.maxRating = 5;  
    8.     });  
    Output

    Output

See that the  “win-rating” directive has added stars according to the value of the slider.

You can download the code shown above from my GitHub Repository.

Note: Once you clone, please don’t forget to run “node install” and “bower install” commands.

There are many other such Win 8 controls which you can try:

  • win-date-picker: Add below code in “main.html” and date control will show up,
    1. <win-date-picker current="date" on-change="dateChanged()"></win-date-picker>  
    Output

    Output

  • win-date-picker: Add the code shown below in “main.html” and click the button to see flyout effect.
    1. <button id="flyoutAnchor">Flyout!</button>  
    2. <win-flyout anchor="'#flyoutAnchor'">Happy coding!</win-flyout>  
    Output

    Output

  • win-time-picker: Add the code generated below in “main.html” and see time control.
    1. <win-time-picker current="time"></win-time-picker>  
    Output

    Output

There are many other nice controls available and you can do a lot to enhance your UI experience.

Playground

If you would like to try using WinJS without installing the above stuff, you can go to two playgrounds.

Test the various samples that are provided. For example,

samples

Summary

Please try the GitHub code and samples given above. I appreciate your feedback.