Ranting and raving about anything I feel like complaining about.

What about Metro JS Projects and jQuery?

I spent this week at Build and was interested in both the XAML and HTML/JS part of the Metro story. I am in the middle of converting GooNews into both HTML and XAML Metro apps to test out the new APIs.

I have to admit, I was nervous at first because this in the keynote:

9-16-2011 10-28-27 PM

(From the keynote)

Do people still write document.getElementById? My nervousness was about that this isn’t how most web developers write code these days. But I was reassured that you could use JavaScript any way you want. Let’s look at this briefly.

Hello World

I started with the Hello World example in the new docs on MSDN. So I fired up a new JavaScript Empty project. It instructed me to add a couple of HTML controls like this:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>FirstJS</title>
  <!-- WinJS references -->
  <link rel="stylesheet" href="/winjs/css/ui-dark.css" />
  <script src="/winjs/js/base.js"></script>
  <script src="/winjs/js/wwaapp.js"></script>
  <!-- FirstJS references -->
  <link rel="stylesheet" href="/css/default.css" />
  <script src="/js/default.js"></script>
</head>
<body>
  <button onclick="click">
    Click me!</button>
  <p id="myText" />
</body>
</html>

This looks pretty good, but I don’t like the ‘onclick’ in the HTML markup. But it’s plain-old-HTML/JS so I won’t scream. Unsurprisingly, the JavaScript is pretty clean too:

(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) {
      document.addEventListener("click", function () {
        myText.innerText = "Hello Windows Metro style";
      });
    }
  }

  WinJS.Application.start();
})();

While this JavaScript works fine, it feels weird. Using addEventListener instead of jQuery feels wrong. Sure, I wrote this kind of code a long time ago, I don’t do that anymore.

Modern Hello World

I wanted to take this simple version but use the modern web development skills and apply them here. First thing I wanted was to add jQuery. I’ve tried to buy into using content delivery networks so in my web code, I do this commonly:

<script type="text/javascript" 
        src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>

This doesn’t work? The context delivery network URI to load the script doesn’t work because the security model for WinRT doesn’t allow me to remote scripts. So, I copy the script into the project and change this like so:

<script type="text/javascript" 
        src="/js/jquery-1.6.4.min.js" ></script>

To make me really happy, I also want to remove that onClick event from the markup since I am used to doing that with jQuery.  Here’s the new markup:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>FirstJS</title>
  <!-- WinJS references -->
  <link rel="stylesheet" href="/winjs/css/ui-dark.css" />
  <script src="/winjs/js/base.js"></script>
  <script src="/winjs/js/wwaapp.js"></script>
  <!-- FirstJS references -->
  <link rel="stylesheet" href="/css/default.css" />
  <script src="/js/jquery-1.6.4.min.js"></script>
  <script src="/js/default.js"></script>
</head>
<body>
  <button>
    Click me!</button>
  <p id="myText" />
</body>
</html>

More importantly, the JavaScript file will use jQuery to accomplish the same thing:

(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) {
      //  document.addEventListener("click", function () {
      //    myText.innerText = "Hello Windows Metro style";
      //  });
      $("button").click(function () {
        $("#myText").text("Hello Windows Metro style");
      });
    }
  }

  WinJS.Application.start();
})();

Notice I am just using the $("button") to find our button (though in practice we’d probably use an ID or a class) then in the click handler we are using jQuery to set the text. This feels better than the old school version we saw earlier. At least it does to me.

What about WinJS?

It’s not an either/or. I think you’ll find it useful to use both WinJS along-side other JavaScript libraries. The cool thing is that your skills will come over!

What’s Next?

I am planning on building two versions of the GooNews JS app. The first one I am taking the complete Microsoft approach and using all the new stuff. Once I am comfortable with that, I’ll be doing it with as little of the Metro specific JavaScript code (e.g. jQuery and Knockout). When I finish the GooNews JS app, I’ll release it on CodePlex and write another post about what I’ve found.

 
 

Comments

Gravatar Shawn, why on earth would you even bother with javascript? I don't understand why anyone with a C# background would even want to waste their time with javascript that targets WinRT.

I'm really confused by the confusion out there by the greater community. Are people really thinking that if they write javascript apps that target WinRT, they'll be able to run the apps on platforms other than Windows8?

Having a C# background in the SL/WPF arena, I personally wouldn't even waste my time with javascript against WinRT. I am curious as to why you are? I have to be missing something, because javascript? Really?? You can kiss LINQ goodbye :(

Thanks, Shawn!
Gravatar You shouldn't bother with JavaScript with WinRT. You're not the audience. The ASP.NET dev's who've never built windows apps and the PHP, RoR (et al) crowd is who this is aimed at. And I think it's a good story.
Gravatar I am a tech guy. People think of me as a Silverlight/XAML guy but I do SL/XAML where appropriate, web dev where appropriate, etc. I think if you paint yourself in a corner, you're in trouble.

The XAML stuff is familiar and i'll be doing more of that, but I was immediately wanting to see how much traction the JS stuff would get from real web guys.
Gravatar This is getting more common. SL/WPF guys feels threatened by Javascript now when they are playing on the same arena.
I see this as a great opportunity to learn both! It's time well spent. And I'm glad to se that you do too.
Gravatar Carl,

The fact is that a lot of XAML guys already know JS/HTML. Many of them (like me) do development in both. It's never been either/or for me no matter what some of my readers like to think ;)
Gravatar Good post Shawn, and responses here.

I also was seeing the 'getElementById' stuff and cringed a bit :) Glad to see this is easy to add to one's local project. Some of me was surprised it's not baked in, since asp.net nowdays just includes jquery - unless they want to keep it separate so they don't have to keep up with different jquery version.
Gravatar oh, and to huh:

http://linqjs.codeplex.com/

You don't have to kiss your linq goodbye.

I've been working with javascript on a project exclusively for the last month or so - and once you learn it's power and capability - it's really a joy to work with. The dynamic nature, the ease of callbacks, the tons of code available to a dev from the community, etc..
Gravatar These are the exact same steps I tried on my first Metro JavaScript project. Damn you for reading my mind! Or, thank you for letting me read yours.

Anyway, exciting times, thanks for the article.
Gravatar I guess this will be a trend as I asked the very same set of questions about using jquery within the first 30 minutes of reviewing the new javascript/hmtl5 project output in VS2011.

I am in the process of converting my open source javascript library that is heavily invested in jquery to the winrt/metro interface and don't like not having a jquery baseline (www.kusog.org)

Thanks for answering my first instinct questions - now I can go write the type of code you're showing here that uses jquery as its core coding standard!
Gravatar I have big concerns about successfully using jQuery in a metro app. jQuery does lots of browser checking to see how it should behave; how will a metro app look to jQuery? Is it possible portions of jQuery are downgrading because it seems an "unknown environment"? If it works now, will it work later?

I noticed things that appear similar to jQuery in the MS JavaScript included in a HTML5 metro app. I also noticed what appeared to be a falling out between MS and the jQuery group, when a few months back jQuery dropped all the official MS plugins including jQuery tmpl.

Another thing I am concerned about is the data-win-bind stuff. I do believe it is possible to use abstractions to have a portion of JavaScript shared between a Web 2.0 app and a metro app. One area that is important to share between those two environments are the templates. I notice many people like handlebarJS template engine. If you write all your app templates in metro specific templates, even the most basic templates have to be recreated for the Web 2.0.

I hope MS can take these types of issues into consideration.l
Gravatar Hi Shawn

Just beginning to check out WinRT+Javascript, v. nice post thanks! I think the javascript community has done some great 'view model' work in the TDD space recently http://tddjs.com/

jQuery is great, but I do think it should be hidden away in an 'adapter' class, which can then be tested independently of application code. It's orfogonal binding stuff, innit?? Same place where getElementById belongs too... [do they still support document.all?? O-M-F-G]

JavaScript is great, but apps get so bug ridden once they hit a certain level of complexity. Devs always want to code right against the metal because tightly coupled code is easier to start writing... [hang on a minute... I just described 75% of the C# community!]

Kenno

Add a Comment

*
*
*