Windows Live Contacts Control Beta 0.2 Released

Our next iteration on the contacts control (nee gadget) is now live and ready for you to experiment with!

The snapshot of the contacts control in the online documentation is a static image. The one below is not!  This a live (as in real) contacts control sitting in an iframe on this blog page. Go head, click on it.  Login and check out your Live contacts.

New and Improved in Beta v0.2:
  • Performance - We've moved the control to a server closer to the contacts storage server, reducing the number of domain hops by half.  If you have a lot of contacts, you'll notice a huge improvement (order of magnitude?) in the load time with this new release compared to the first release.
  • Clicks - The click noises in IE have been significantly reduced
  • History litter - The cross-domain mechanism no longer leaves "droppings" in the browser history
  • No ActiveX control prompts!  - Proper use of the IE7 "native" XMLHttpRequest object.  We figured out why the IE7 XMLHttpRequest wasn't cooperating with our code and now its humming along nicely.  More on that snag later.
  • Support for https - The cross-domain communication channel now conforms to the protocol of the host page URL.  You can now use the contacts control on your https pages (such as shopping cart checkout - hint hint).  This was a strong beta feedback request.  In hindsight, it seems pretty obvious, but we overlooked it the first time around.
  • Contact details in tooltips - Hover the mouse over a contact in the list and the popup tooltip will display their name and address infos.  This helps show a lot more detail without consuming more screen space.
  • Refactored for modularity and versioning - Ok, so this isn't an end-user feature, but it is a big deal for enabling us to move forward quickly with future revision cycles for this control and others in the pipeline.  Modularity (encapsulation and isolation) are virtually non-existent in JavaScript.  I'm changing that.

The iframe on this page was necessary to get around the html rewriting done by the blogs.msdn.com host server. (grr...) It's also remarkably difficult to upload a file to blogs.msdn.com, which is a critical requirement for getting the cross-domain communication channel to work.  Then again, blogs.msn.com wasn't intended to host files, just blog articles.

So, I put the contacts control client demo on my own server and just placed an iframe here to point over there.

What does this little demo do?

It displays the contact info received from the control when the user selects and ok's the transfer.  Sign into the control with your LiveID identity, select a few of your contacts, and press Send.  The control will display the data and ask for confirmation.  If you approve the transfer, the data is sent to the host page via the cross-domain channel.

How do I set it up? 

We've streamlined the control setup, switching from a programmatic constructor call model to a declarative HTML element model.  The only JavaScript you write is the function to do something with the returned data.  To put the control on your page, you add two script references to your page (live.js and control.js, on versioned URLs), declare an XML namespace (xmlns:devlive=dev.live.com), and insert an HTML element tag named "contactscontrol".  The long list of parameters required by the previous constructor call are now attributes of the contactscontrol element.  Like this:

<devlive:contactscontrol
devlive:privacyStatementURL="yourdomain.com/privacyStatement.html"
devlive:channelEndpointURL="yourdomain.com/channel.htm"
devlive:dataDesired="name, email"
devlive:onData="myDataProc"
devlive:onSignin="mySigninProc"
devlive:onSignout="mySignoutProc"
devlive:onError="myErrorProc" />

You'll probably also want to set the width and height of the box as well, by adding a style="width:250;height:400;float:right" attribute in there.  The devlive namespace is optional, but a good idea to avoid colliding with somebody else's contactscontrol tag or channelEndpointURL attribute.

Put that on your page, along with the two required includes and the callback functions you've indicated, and when the page loads, the contacts control code will discover the contactscontrol HTML tag, grab the info it needs from the attributes, and do all the behind the scenes stuff necessary to display its UI and talk to the Windows Live Contacts database server.  Full step by step details are on the Getting Started page.

There are two critical pieces you need to get right:  placing the channel.htm on your site, and writing your onData callback function.  Without those, everything can look fine but you'll get no data. 

Channel.htm

Channel.htm is easy:  just copy the file from <dev.live.com/scripts/channel/v0.1/channel.htm> to some place on your web site.  Don't bother clicking on that link in your browser - channel.htm autonavigates to about:blank, so by the time you can click View: Source the source you want is already gone.  This isn't an obfuscation measure, it's an integral part of the channel mechanism - immediately navigating to a different URL allows the channel to detect consecutive navigations to the same URL.  Otherwise, the browser would ignore the second request because the page is already on the requested URL.

To copy the channel.htm file to your machine, right click on the URL and select Save Target As, or open the URL in Notepad or Visual Studio, then Save As to a local file.  It doesn't matter what the file name or path is, it just needs to be in the same domain as the page you want to use the contacts control on. 

Do not use MS Word or Write to open channel.htm - word processors are prone to reformatting HTML in ways that make sense for interoffice memos but wreak havoc on HTML and JavaScript syntax.  Word is particularly bad helpful about replacing simple double quotes with fancy back slanted and forward slanted quote chars.  Very pretty on paper, but nasty, hard to spot syntax errors in JavaScript and HTML.  "What do you mean 'Unterminated string'?  The friggin quote is right there!!"

Receiving the Data

Writing the code to receive the contacts is pretty easy, too.  The code on the demo page looks like this:

function receiveData(p_contacts) {
    var s = "Done! " + p_contacts.length + " records received.";
    for (var i = 0; i < p_contacts.length; i++) {
        s += "<p>";
        s += "name: " + p_contacts[i].name +"<br/>";
        s += "email: " + p_contacts[i].email;
        s += "</p>";
    }
    document.getElementById("ContactsDisplay").innerHTML = s;
}

The p_contacts param is an array of JavaScript objects, one object per contact.  The data for each contact is stored in properties / attributes on the object.  p_contacts[0].name returns the name field of the first contact in the array.

Keep in mind that some of the contact records you receive may not have data for all the fields you asked for.  Currently, that means the field values you receive will be undefined, and will display "undefined" when you convert them to strings.  We'll fix that to return empty strings in a future release.

But How Does It Work, Inside?

That's tomorrow's post.