Abstract: Windows 8 apps can be designed and coded using HTML/CSS/JS just like PhoneGap apps can. And with very little effort you can use your skill and existing resources to crank out a sleek, modern looking Windows 8 style app in no time.

PhoneGap and Windows 8 development – more similar than you realize

PhoneGap is an interesting animal. While it’s most salient aspect is the cross platform nature of the applications you can build with it, it’s also interesting in that you use HTML and JavaScript to create the apps. Since this relies on the underlying mobile browser technology on each platform, there are (from time to time) a few little quirks. But overall, it really does provide a nice layer of abstraction. You can bring your web skills into play, and all you have to do is learn a few specifics of creating and publishing an app on a particular platform, design the UI with HTML and CSS, code it up with standard JavaScript, learn a few new APIs that PhoneGap offers, and you’re all set. In fact, to some teams, the cross platform nature is secondary. They embarked on PhoneGap development because it allowed their teams to reuse their web development skills, their favorite libraries, design tools, and more.

What does this mean in the context of Windows 8 development? Well, one of the approaches for building the new Windows 8 applications is actually to use HTML/CSS/CS. If you haven’t yet, I suggest you read about creating a Windows 8 Metro style apps with JavaScript. Here’s the upshot for PhoneGap developers:

  • Your skills, assets, and probably a lot of your existing pure HTML/CSS and JavaScript code will just work in a Windows 8 application.
  • You can update the look of your applications with very little effort by using the intrinsic styles for the basic HTML elements like <h1> and <button>, as well as the advanced Windows 8 controls like the app bar, date picker, flip view, and more.
  • Your code that interacts with the PhoneGap API (to handle things like file access, sensors and application lifecycle events) can be updated to use the WinJS library to accomplish the same things you were doing in PhoneGap.
  • Scenarios where you had to write PhoneGap plugins can be addressed by either finding the functionality in the expansive WinJS library, or by incorporating native code in a Windows 8 JavaScript app.

This blog post series is going to address the third bullet above – figuring out how to do things in Windows 8 app development that you know how to do in PhoneGap. We’ll start with a simple example and then dive in deeper over subsequent weeks.

A simple PhoneGap example

Here is a very simple PhoneGap application that uses the PhoneGap geolocation API to get information on the device’s position. No matter what platform this PhoneGap code is executed on, this will work. That’s because the call to getCurrentPosition in line 28 calls into the underlying platform’s API. But to your code, It’s exposed as a JavaScript function.

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>

<title>Cordova WP7</title>

<link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>


<script type="text/javascript" charset="utf-8" src="cordova-1.9.0.js"></script>
 1:  
 2:  
 3:       <script type="text/javascript">
 4:  
 5:         var getLocation = function () {
 6:  
 7:             // Success callback
 8:             var success = function (p) {
 9:                 document.getElementById('latitude').innerHTML = p.coords.latitude;
 10:                 document.getElementById('longitude').innerHTML = p.coords.longitude;
 11:  
 12:                 document.getElementById('tdAlt').innerHTML = p.coords.altitude;
 13:                 document.getElementById('tdAcc').innerHTML = p.coords.accuracy;
 14:                 document.getElementById('tdAltAcc').innerHTML = p.coords.altitudeAccuracy;
 15:                 document.getElementById('tdHeading').innerHTML = p.coords.heading;
 16:                 document.getElementById('tdSpeed').innerHTML = p.coords.speed;
 17:  
 18:                 setLocationStatus("Done");
 19:             };
 20:  
 21:             // Fail callback
 22:             var fail = function (e) {
 23:                 console.log("getLocation fail callback with error code " + e.code);
 24:                 setLocationStatus("Error: " + e.code);
 25:             };
 26:  
 27:             // Get location
 28:             navigator.geolocation.getCurrentPosition(success, fail, { enableHighAccuracy: true }); //, {timeout: 10000});
 29:             setLocationStatus("Retrieving location...");
 30:  
 31:         };
 32:         /**
 33:  * Set location status
 34:  */
 35:         var setLocationStatus = function (status) {
 36:             document.getElementById('location_status').innerHTML = status;
 37:         };
 38:       
</script>




</head>
<body>

<h1>Location</h1>
<div id="info">
<b>Status:</b> <span id="location_status">Stopped</span>
<table width="100%">
<tr><td><b>Latitude:</b></td><td id="latitude"> </td></tr>
<tr><td><b>Longitude:</b></td><td id="longitude"> </td></tr>
<tr><td><b>Altitude:</b></td><td id="tdAlt"> </td></tr>
<tr><td><b>Accuracy:</b></td><td id="tdAcc"> </td></tr>
<tr><td><b>Altitude Accuracy:</b></td><td id="tdAltAcc"> </td></tr>
<tr><td><b>Heading:</b></td><td id="tdHeading"> </td></tr>
<tr><td><b>Speed:</b></td><td id="tdSpeed"> </td></tr>
</table>
</div>
<h2>Action</h2>
<button onclick="getLocation();">Get Location</button>
</body>
</html>

The HTML of a PhoneGap application is a little different from the HTML you’d write for a browser application. Let’s take a look at the differences and their equivalents in Windows 8 JavaScript apps.

The DOCTYPE element

Since we’re not running in a browser of the user’s choice, but instead in a specific execution environment, we can use the standard HTML5 doctype which is simply “HTML”. This is identical in Windows 8.

The meta tag controlling the “viewport”

Because in PhoneGap, the hosting container is essentially a web browser, this tag tells it behave less like a web browser. That is, don’t allow the user to pan and pinch to zoom as if it were a web page. We don’t need this for Windows 8 apps because there is no scrolling, panning or zooming like in a web page since it’s an app.

The stylesheet reference

One of the great aspects of designing a web page is the flexibility and power of CSS. Since an app has a design as well, CSS can be used to design the app’s interface in the same way. The “master.css” here is from the template for building Windows Phone apps with PhoneGap. When you design a PhoneGap application, you’re going to want to give it a different look and feel on each platform. And swapping out CSS files when you’re building the final app for each platform is one way to do that. The CSS and overall design you use should be tailored to the platform.

Windows 8 JavaScript apps use CSS to design the UI just like a browser or PhoneGap app. In moving this code to Windows 8, we won’t need this line as there’s a default Windows 8 style for every control. You’d only need to specify styles if you want to customize the look. Later in this article I’ll show that in action.

The script reference to “cordova”

When your code is running in PhoneGap, all the standard JavaScript APIs are available to use. By bringing in this script file, you can then use the PhoneGap APIs to do more “appy” stuff like working with the file system, responding to application lifecycle events, and more.

In Windows 8 we have something similar in the form of WinJS. So it’s just a matter of learning what’s in the WinJS API like you did when you first learned PhoneGap.

The app code

The rest of the source is the code and markup for your app. There is a table in which to display the location information once we retrieve it, and an asynchronous call into the PhoneGap’s geolocation API to get the result.

The Windows 8 equivalent

Now that we have reviewed the anatomy of a basic PhoneGap application page, let’s look at the equivalent in Windows 8. When you set up a machine (physical or virtual) with the Windows 8 Release Preview and Visual Studio 2012 Release Candidate, you’ll be able to create Windows 8 apps with JavaScript and HTML. For an overview on how that works, check out this this introduction.

When you create a new Windows 8 JavaScript project, you’ll get the following basic HTML:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SimpleLocation</title>

<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script>
 1:  
 2:     <script src="//Microsoft.WinJS.1.0.RC/js/ui.js">
 1: </script>
 2:  
 3:     <!-- SimpleLocation references -->
 4:     <link href="/css/default.css" rel="stylesheet" />
 5:     <script src="/js/default.js">
</script>

</head>
<body>
<p>Content goes here</p>
</body>
</html>

Looks a lot like PhoneGap, huh? There’s the same DOCTYPE, some CSS and JS references to intrinsic resources and some to project-specific styles and code. So let’s bring in pieces from the PhoneGap sample above and make the necessary changes to get it running on Windows 8!

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SimpleLocation</title>

<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script>
 1:  
 2:     <script src="//Microsoft.WinJS.1.0.RC/js/ui.js">
 1: </script>
 2:  
 3:     <!-- SimpleLocation references -->
 4:     <link href="/css/default.css" rel="stylesheet" />
 5:     <script src="/js/default.js">
 1: </script>
 2:  
 3:         <script type="text/javascript">
 4:  
 5:             var getLocation = function () {
 6:  
 7:                 // Success callback
 8:  
 9:                 var success = function (p) {
 10:  
 11:                     document.getElementById('latitude').innerHTML = p.coordinate.latitude;
 12:                     document.getElementById('longitude').innerHTML = p.coordinate.longitude;
 13:                     document.getElementById('tdAlt').innerHTML = p.coordinate.altitude;
 14:                     document.getElementById('tdAcc').innerHTML = p.coordinate.accuracy;
 15:                     document.getElementById('tdAltAcc').innerHTML = p.coordinate.altitudeAccuracy;
 16:                     document.getElementById('tdHeading').innerHTML = p.coordinate.heading;
 17:                     document.getElementById('tdSpeed').innerHTML = p.coordinate.speed;
 18:  
 19:                     setLocationStatus("Done");
 20:                 };
 21:  
 22:                 // Fail callback
 23:  
 24:                 var fail = function (e) {
 25:  
 26:                     //setLocationStatus("Error: " + e.code);
 27:                     setLocationStatus("Error: " + e.message);
 28:                 };
 29:  
 30:  
 31:  
 32:                 // Get location
 33:  
 34:                 //navigator.geolocation.getCurrentPosition(success, fail, { enableHighAccuracy: true }); //, {timeout: 10000});
 35:            
 36:                 var geolocator = Windows.Devices.Geolocation.Geolocator();
 37:                 geolocator.desiredAccuracy = Windows.Devices.Geolocation.PositionAccuracy.high; //or default
 38:                 geolocator.getGeopositionAsync().then(success, fail);
 39:  
 40:  
 41:                 setLocationStatus("Retrieving location...");
 42:  
 43:  
 44:  
 45:             };
 46:  
 47:             /**
 48:  
 49:  * Set location status
 50:  
 51:  */
 52:  
 53:             var setLocationStatus = function (status) {
 54:  
 55:                 document.getElementById('location_status').innerHTML = status;
 56:  
 57:             };
 58:  
 59:       
</script>

</head>
<body>
<h1>Location</h1>

<div id="info">

<b>Status:</b> <span id="location_status">Stopped</span>

<table>
<tr><td><b>Latitude:</b></td><td id="latitude"> </td></tr>
<tr><td><b>Longitude:</b></td><td id="longitude"> </td></tr>
<tr><td><b>Altitude:</b></td><td id="tdAlt"> </td></tr>
<tr><td><b>Accuracy:</b></td><td id="tdAcc"> </td></tr>
<tr><td><b>Altitude Accuracy:</b></td><td id="tdAltAcc"> </td></tr>
<tr><td><b>Heading:</b></td><td id="tdHeading"> </td></tr>
<tr><td><b>Speed:</b></td><td id="tdSpeed"> </td></tr>
</table>

</div>

<h2>Action</h2>

<button onclick="getLocation();">Get Location</button>
</body>
</html>

The HTML is virtually unchanged, other than swapping the PhoneGap app-specific “master.css” for the built in Windows 8 one called “ui-dark”. And yes, there is a “ui-light” if you want your app to have a light colored background. The code is only a little different because we’re using the .then syntax from the WinJS Promise object to accomplish things asynchronously. The success parameter became coordinate instead of coords (but note the properties are the same name!).

Below, I have some screen shots of the PhoneGap app running in the Windows Phone emulator, and the Windows 8 JavaScript app.

SimpleLocationStopped  screenshot_07062012_151729

SimpleLocationDonescreenshot_07062012_151858

Conclusion

When you started using PhoneGap you had to design for a different rendering environment (an app) instead of a browser. And you had to learn a new set of APIs. But you still used your HTML/CSS/JS skills from creating browser applications. And so it is with Windows 8 HTML/JS development. In future articles I’ll cover a lot more aspects of Windows 8 JavaScript apps from a PhoneGap developers perspective.

A Windows 8 developer has good reason to be excited. With over 650 million licenses of Windows 7 out there, exciting new hardware coming from manufacturers, a developer friendly store with a great revenue sharing approach, and tons of resources (online and local), frankly, PhoneGap developers who aren’t targeting Windows 8 are just missing the boat.

Don't forget that we have a great program to get you from idea to Windows 8 app with our 30 to Launch program as part of Generation App. Sign up today!