| Comments

Last week I was wanting to do something on my site sort of a ‘breaking news’ style banner that would span the entire site width but only when I wanted it too – based on a cookie or something else.  And I didn’t want to do something server side, because I was sick of doing stuff like that.

Not having played with jQuery, I thought I’d take a dive.  Prior to MIX09, I’d been testing something that the MIXOnline team had been toying with, which has just been released: Glimmer.  Glimmer is described as a jQuery Interactive Design Tool.  A helper for those like me who know nothing about it.  Sure, jQuery has a ton of resources, and my Twitter peeps came through helping me navigate some of the things that aren’t glaringly obvious for noobs like me :-).

But Glimmer got me started, and I think that’s the point.  I had an overall HTML structure already and had the div element that I wanted to work with in jQuery – my goal was to animate it in a ‘breaking news’ sort of manner (or at least what’s in my head when I think of that concept).  I opened up my HTML in Glimmer and went to work.  I simply added the action (the function I wanted to trigger), then pointed it to the element to target.  Here’s what my simple Glimmer UI action setup looked like:

Glimmer UI

I clicked save and it created a JavaScript file for me with the completed code:

   1: jQuery(function($) {
   2:  
   3: function loadBreakingNews(event)
   4: {
   5:      $("#info").css("top","-50px");
   6:     $("#info").animate({"top":0}, 894, "easeOutBounce", null);
   7: }
   8:  
   9: loadBreakingNews();
  10:  
  11: });

Sure, to you jQuery pros, this looks simple, but this tool helped me quickly use a design-time tool to generate this without previous knowledge of jQuery.  Now, I’ve learned a few things about jQuery since my first incarnation – all of which took 2 seconds with Glimmer.  I decided I wanted to use the built-in “slideDown” feature in jQuery.  Some things like this aren’t supported in Glimmer yet, but simple things are…and quite frankly, the combination of Y position animation and an easing function accomplished the same goal.

I made a few hand-modifications to fit my needs (checking for cookies to trigger the banner, etc), but Glimmer got me started right away figuring things out quickly…it was awesome.  I think it comes with a free ShamWow as well, I’m not sure, but I swear Karsten told me that. :-)  Check out Glimmer today if you are new (or even seasoned) to jQuery.  There is a plugin model I haven’t explored, but check out the Glimmer project site for more information.

Next maybe I should explore working with jQuery and Silverlight as I know there is more to jQuery than animations and I think it would make a helpful library for the HTML interop layer.

| Comments

A few days ago Google announced “event tracking” for their Google Analytics platform.  My account was invited to participate in this initial wave so I decided to take a look.  The main reason of course is because of a keyword in their email they sent to me (emphasis mine):

“Event Tracking allows you to track interactions with Web 2.0 style content such as Flash, AJAX, Silverlight, social networking apps, etc.”

I have the script already running on my site for general analytics so I figured I’d whip up a quick sample to see how it might work with Silverlight.  If you are in to analytics you may also want to check out Michael Scherotter’s webcast with WebTrends on some analytics techniques with Silverlight as well.

There are a bunch of existing techniques you can do today using existing analytics packages and scripts, but it is really nice to see movements toward recognizing unique characteristics of rich Internet application activities and the need for something more granular that represents user behavior rather than just a view.  After all, “paths” for normal web browsing have been available for analytics for a long while…why should RIA have to suffer?  The main reason is that no analytics packages have successfully managed yet to provide enough artificial intelligence to reflect on the behavior within the RIA.  As RIA development becomes more mainstream in applications facing the consumers, it will be increasingly important to understand where/what the user’s are doing to discern better usability changes, etc.

Google calls their feature “event tracking” and enables a function on the existing script to track an event, much like a Windows event log (for those who are familiar with it).  You provide a category and action, then optionally a label and value (where value is an integer value, generally going to be used I assume for counts of actions).  The “action” doesn’t have to actually be an literal action such as “click” but something you can put together.

In my less-than-creative mind I just thought of putting together two category scenarios: media and e-commerce.  My commerce actions would be: Add Item to Cart, Sample Music (i.e. a music store action), Start Checkout, Complete Order…all rolled up in a Commerce category.  My Media category would include Play and Pause tracking.  The signature of the event tracking method in Google is:

   1: _trackEvent(category, action, [label], [value]);

This would be called on your variable given to whatever your _getTracker() call was made with (mine is called pageTracker, using the default from the script).

NOTE: This post assumes you know some of the terminology from Google analytics offering.  If you don’t, you can read about it at their Analytics page.

Since all of this was Javascript calling from Silverlight I’d have to use the HTML bridge capabilities.  You can learn how to call Javascript from Silverlight from here or view a walk-through video on how to do it on the Silverlight community site as well.  I created a simple function on my page that basically wrapped the actual function call.  Honestly I figured it would be here that you may want to do some error handling or any other event-based “stuff” – but for now, it’s pretty much just a wrapper to the same function and looks like this:

   1: <script type="text/javascript">
   2: var pageTracker = _gat._getTracker("PROFILE_CODE_HERE");
   3: pageTracker._initData();
   4: pageTracker._trackPageview();
   5: </script>
   6:  
   7: <script type="text/javascript">
   8:     function trackEvent(category, action, label) {
   9:         pageTracker._trackEvent(category, action, label);
  10:     }
  11: </script>

As you can see, in my sample I wasn’t concerned with the value parameter for now.  Now in my Silverlight application I just created some lame looking XAML that would more generally be spread out throughout a typical application, but just for playing I put it in one place.  Here’s the XAML:

   1: <UserControl x:Class="GAEventTracking.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     Width="400" Height="600">
   5:     <Grid x:Name="LayoutRoot" Background="White">
   6:         <StackPanel Orientation="Vertical">
   7:             <Button Width="200" Content="Added Item to Cart" x:Name="AddCart" />
   8:             <Button Width="200" Content="Sampled Music File" x:Name="SampleMusic" />
   9:             <Button Width="200" Content="Started Checkout" x:Name="StartCheckout" />
  10:             <Button Width="200" Content="Completed Order" x:Name="CompleteOrder" />
  11:             <MediaElement x:Name="LakeVideo" Width="320" Height="240" 
  12:                           Source="Lake.wmv" AutoPlay="False"/>
  13:             <StackPanel Orientation="Horizontal">
  14:                 <Button Content="Play" x:Name="PlayVideo" />
  15:                 <Button Content="Pause" x:Name="PauseVideo" />
  16:             </StackPanel>
  17:         </StackPanel>
  18:     </Grid>
  19: </UserControl>

On the relevant code I’ve wired up the buttons to the same event handler for simplicity and just looking at the name and content for what to do.  Here’s what that looks like:

   1: public Page()
   2: {
   3:     InitializeComponent();
   4:     AddCart.Click += new RoutedEventHandler(EventButtonClick);
   5:     SampleMusic.Click += new RoutedEventHandler(EventButtonClick);
   6:     StartCheckout.Click += new RoutedEventHandler(EventButtonClick);
   7:     CompleteOrder.Click += new RoutedEventHandler(EventButtonClick);
   8:     PlayVideo.Click += new RoutedEventHandler(PlayVideo_Click);
   9:     PauseVideo.Click += new RoutedEventHandler(PauseVideo_Click);
  10: }
  11:  
  12: void PauseVideo_Click(object sender, RoutedEventArgs e)
  13: {
  14:     LakeVideo.Pause();
  15:     HtmlPage.Window.Invoke("trackEvent", new object[] { "Media", "Pause", "Lake video was paused" });
  16: }
  17:  
  18: void PlayVideo_Click(object sender, RoutedEventArgs e)
  19: {
  20:     LakeVideo.Play();
  21:     HtmlPage.Window.Invoke("trackEvent", new object[] { "Media", "Play", "Lake video was started" });
  22: }
  23:  
  24: void EventButtonClick(object sender, RoutedEventArgs e)
  25: {
  26:     Button btn = sender as Button;
  27:     string actionName = btn.Name;
  28:     string label = btn.Content.ToString();
  29:  
  30:     HtmlPage.Window.Invoke("trackEvent", new object[] { "Commerce", actionName, label });
  31: }

So you can see here at line 30 above is where the relevant code is.  Using the HTML bridge, I can invoke a method on the hosting page and provide the arguments to it.  That’s it!  So what does this look like on the reporting side?

For a summary view of the categories you’ll get some decent information about the action:

But then when you also drill into a specific category, your label information will be viewable:

So that now using methods like this you could track specifically what is going on within your RIA.  As I mentioned, you can do this with existing platforms today with being clever of how you track a “PageView” but it is nice to see a specific implementation for event-driven tracking.  And this isn’t limited to just RIA, you can still (obviously) use this event tracking in your AJAX applications, static pages, whatever.

The Google links demonstrated how to implement this with ActionScript and Flash, but while they mentioned Silverlight, they didn’t provide a relevant sample.  Luckily basically the steps are as easy as outlined here:

    • Include the tracking script
    • Decide what/when/where you want to track within your Silverlight application
    • Use the HTML bridge (Html.Window.Invoke) to call out to the _trackEvent function

Again the relevant code for Silverlight is:

   1: HtmlPage.Window.Invoke("[methodName]", new object[] { "[category]", "[action]", "[label]"});

Where the “[methodName]” is whatever Javascript function you are calling that exists in the hosting page (and matching the proper signature you’ve set up.  As I mentioned I didn’t use the optional value parameter in the event tracking, but had you done that (say you wanted to know how many times a media item had been played) you’d add a value of “1” for example and the reporting would provide aggregate summaries of that action within the category.

Have fun and hope this helps some!

| Comments

When working with Silverlight 2, most will be working with managed code (c#, vb, etc.).  But likely people are working with Silverlight as an additive value to their web application, providing some enhanced user experience to an application.  there may be times where you will still need to call back into the hosting html context.  For then, you'll want to be familiar with two objects HtmlDocument and HtmlPage. 

Both of these objects provide access to the page context hosting your silverlight control.  If you need to seek things in the HTML DOM, you could use the HtmlDocument class.  For example, let's say I need to change the innerHTML property of some <div> element:

using System.Web.Browser;

HtmlDocument doc = HtmlPage.Document;
doc.GetElementById("mydiv").SetProperty("innerHTML", "<b>hello world</b>");

Also, i might want to interact with existing client-side functions, perhaps from client-side frameworks or other library utilities you might have developed on your own.  If I have a function on my page called "foo()" I would invoke it like this:

using System.Web.Browser;

HtmlPage.Window.CreateInstance("foo");

And if I had parameters in a function, like "foo2(theAlert)," I would invoke it like this:

using System.Web.Browser;

HtmlPage.Window.CreateInstance("foo2", new string[] { "tim heuer" });

This may not be the norm with your Silverlight project, but I hope this helps clear some things up!  I am including the "using" statements in my c# samples so you know where in the namespace the class library exists.

| Comments

When developing Virtual Earth applications I find myself always having the SDK documents open in the background for reference.  While this isn't a bad practice, I've historically only used them for parameter reference, etc.  I longed for the time that I could get cheater help intellisense for the Virtual Earth API. 

When Visual Studio 2008 came out with Javascript intellisense, I figured the day has come.  But unfortunately, the Javascript intellisense isn't enabled for external (external==not-the-same-app-domain) files.  The thing about the implementation of the Javascript intellisense in VS2008 is that you can just make a reference to a file for the intellisense and it doesn't have to actually be the implemented file.  Make sense?  Probably not. 

My colleague Marc has created a Codeplex project for enabling Virtual Earth intellisense.  Basically he's created a helper Javascript file that you can reference in your project to enable the intellisense.  Note that this does not actually get referenced in your project (meaning, the Javascript file isn't downloaded to your users), but rather just leveraging the VS2008 Javascript intellisense reference scheme to 'trick' the IDE into giving you intellisense for your referenced Virtual Earth API.  This is accomplished because the Javascript reference of the helper file is a design-time only helper...not affecting any true reference to the Virtual Earth control.

Once you do that, you'll get something like this:

Marc did a great job getting a lot up and running with this helper file.  He's recorded a short screencast on how it works to help you understand it a little better.  And if you are interested in helping contribute to the project, please watch the screencast for more information.

| Comments

miniclip.com now has a silverlight 1.0 puzzle game to their catalog.  this is pretty good to see among the massive catalog of casual games they offer.  this game is built using silverlight 1.0 and is a good use of a lot of the capabilities (and in some cases maxing them out) for the 1.0 platform.

Games at Miniclip.com - Zombomatic
Zombomatic

 

Swap the conductors to connect them into a path for the electricity to flow.

Play this free game now!!

the game, built by terralever, falls into that 'casual gaming' category -- you know, the ones where you decide only to spend a few minutes taking a look and then end up forgetting that meeting so you can complete all the levels?  this one is an addicting game to figure out how to reveal all the levels possible.  check it out.

 

you may remember the terralever name from the zero gravity game.  while that game was a proof to look at the capabilities of silverlight 1.1 at that time, the zombomatic game was built using silverlight 1.0 release technology so that it could go production.  congrats to the terralever team for this release and we look forward to seeing what you can do with silverlight 2 when available for production applications!

the silverlight team will be at MIX08 this year and i'm sure eager to talk to those interested.  i'm trying to ensure they stop by open spaces @ mix where i'll be hanging out most of the time.