Archive for July, 2007

* Oil Highs, Oil Lows

Posted on July 31st, 2007 by Dave Johnson. Filed under Uncategorized, climatechange, globalwarming, peakoil.


It is a bit of a change for me to be posting about environmental issues on my Nitobi blog but I think it is about time - particularly since my PhD is in solar cell physics.

Forget about climate change, oil is the new and old black. That old black has just hit a new high on supply troubles.

We can do everything we want to reduce our climate changing, ice melting, and chaotic weather making actions but depleting oil is also a real concern.

So not only do we have to worry about a warming world but also decreasing fuel for that warming. I think this is an appropriate post to be making from Dallas no?

.



* IronRuby aka Ruby.NET Pre-Alpha Release

Posted on July 29th, 2007 by Dave Johnson. Filed under Components, Declarative Programming, Uncategorized.


About a week ago Scott G over a MS blogged about the pre-alpha release of IronRuby. Very cool stuff.

For those that don’t know, IronRuby and friends (IronPython, JavaScript, Dynamic VB) is a project that is, like JRuby for Java, enabling Ruby to run on top of the .NET Framework. This means that your dynamic Ruby script can also have access to all the underlying .NET goodness (and badness). It will be very interesting to see how the performance is.

It is also really cool that they are doing Python and JavaScript as well. It’s like Phobos and JRuby all in one neat little package with a dash of python for good measure. Oh have I forgotten one of the languages? I can’t help but laugh when I see Dynamic VB.

Here is a code snippet from Scott’s post with some Ruby script using WPF - pretty cool stuff!

.



* Dallas Here I Come!

Posted on July 29th, 2007 by Dave Johnson. Filed under AJAX, JavaScript, Nitobi.


Looks like I am heading to Dallas to do some on-site Ajax training and consulting. If anyone knows a good place to go for a beer pls let me know - cause I will definitely need it!

.



* I ♥ Internet Explorer

Posted on July 25th, 2007 by Dave Johnson. Filed under InternetExplorer, Uncategorized.


Yes it’s true, my love affair with Firefox has fizzled away - we will never have the same hot romance of yesteryear.

Alas, I have had enough of Firefox stealing my memory with wreckless abandon.

The only thing that is keeping me on Firefox is my unabiding love for Firebug. However, for some of my everyday browsing I am making the switch back to IE <sob/>.

Tags: , .



* Dreamweaver IDE Support

Posted on July 21st, 2007 by Dave Johnson. Filed under AJAX, Nitobi, RIA, declarative, dreamweaver, javafx.


Mike has been at it again building some way cool tooling support around our components and screencasting about it! This time it is support for Dreamweaver.

.



* Salesforce.com AIR Application

Posted on July 18th, 2007 by Dave Johnson. Filed under AJAX, Nitobi, Web2.0, air, completeui, onairbustour, salesforce.


Since Andre was invited to go on the Adobe AIR bus tour we decided to build a cool sample application that would exhibit some of the cool features of AIR and our components. Since we like to focus on the “business case” for our Ajax components and our custom development, we built an AIR application that integrated with the Salesforce.com API. Being the RIA nutters that we are and knowing that most people would be building Flex based applications - which we are currently building a few of for various customers - we decided to build an HTML / Ajax based application instead.

The cool AIR features that we wanted to show off were things like

      1. custom chrome to make things look hawt
      2. drag and drop from the desktop for vcard integration
      3. file system integration for taking things offline

Since we had a pretty tight timeline we went fairly simple and built the application in about three person weeks. The idea was centered around a mobile sales person being able to have access to their Salesforce Account and Contact data while online or offline. Of course, being an Ajax application it should also prove to be a much nicer interface than the current Web 1.0 based Salesforce user interface - man would I like to be able to redesign the Salesforce UI!

Custom Chrome

The most important part of the application was to make it look hawt. This involved a bit of design assistance from Alexei and the creation of some JavaScript and text based activity indicators since animated gifs don’t work in the current AIR beta :( What we did use a lot though was the CSS3 border-image style. It doesn’t seem to work quite right but if you just go with it you can make something that looks half decent.

So on the outer window we applied a style like this:
[code]
-webkit-border-image:url(../images/app-border.png) 18 18 18 18 stretch stretch; border: 18px;
[/code]

Where the app-border.png looks like this:

As well as looking great the chrome needs to be functional. It needs to have minimize, maximize, restore and close buttons. It needs to be resizable and draggable. Maximize, minimize, restore and close are easy - for example:

[code]
window.htmlControl.stage.window.restore();
[/code]

All of those methods (restore, close, minimize, maximize) are created on the nitobi.air.Window JavaScript class. To enable draggability we attach an HTML event handler to the our main window DIV element like this:

[code]
nitobi.html.attachEvent($(”main_window”), “mousedown”, handleMove, this);
[/code]

The handleMove method is shown below where we just do a quick check first to see if the element that the user is trying to drag has the chrome class on it - this lets us make the window draggable from various points like the header and around the edges. Once they get the chrome we just call startMove() like this:

[code]
nitobi.air.Window.prototype.handleMove = function(evt)
{
if (nitobi.html.Css.hasClass(evt.srcElement, “chrome”))
window.nativeWindow.startMove();
}
[/code]

Desktop Integration

The other cool thing about using AIR is that rather than having some ridiculous multi file upload utility written in Java or Flash, with AIR we can just take files from the desktop and drag them onto the application. What this means is that we can take things like VCards or CSV files full of contact information and have them automagically entered into Salesforce. If offline they get saved as updategrams and get uploaded once the computer is back online. The events for the drag and drop are Flex events on the AIR htmlControl but they connect to JavaScript methods as handlers.

[code]
window.htmlControl.addEventListener(
runtime.flash.events.NativeDragEvent.NATIVE_DRAG_ENTER,
nitobi.lang.close(this, doEnter));
window.htmlControl.addEventListener(
runtime.flash.events.NativeDragEvent.NATIVE_DRAG_DROP,
nitobi.lang.close(this, doDrop));
[/code]

When the drag operation enters the AIR window we call the acceptDragDrop method with the htmlControl as the only argument. This will enable dropping onto our HTML application.

[code]
nitobi.air.Window.prototype.doEnter = function( e )
{
if(e.transferable.hasFormat(air.TransferableFormats.FILE_LIST_FORMAT ) ) {
runtime.flash.desktop.DragManager.acceptDragDrop(window.htmlControl);
onDragEnter.notify();
}
}
[/code]

Now that we have enabled dropping on our HTML app we can actually process the information when it is dropped by accessing the transferred data like this:

[code]
nitobi.air.Window.prototype.doDrop = function( e )
{
var files = e.transferable.dataForFormat(
air.TransferableFormats.FILE_LIST_FORMAT,
air.TransferableTransferMode.CLONE_PREFERRED );
for( var f = 0; f < files.length; f++ ) {
onDragDrop.notify(files[f]);
}
}
[/code]

In this case we specify that the drop should be a list of files and we are able to iterate over that list to add each of the VCards to Salesforce.

Offline Operation

Finally, we did some filesystem integration for working offline and that was pretty cool. Rather than using the SQL-Lite database that comes with AIR, we wanted a solution that would be more conducive to a web way of working - ie something that will essentially queue HTTP POSTs and subsequently POST them when a network connection is present. Because frankly, unless you have A LOT of data on the client and interfacing to a SQL-Lite database is generally going to be overkill and make a lot more work for the developer since they will have to write not one backend in their server language of choice but also a client side backend in JavaScript. Anyhow, in the Nitobi CompleteUI framework, all changes on the client are stored as XML “updategrams”. So it was a pretty easy task to put a layer between the client side JavaScript DataTable and the XMLHttpRequest that sends data to the server when it is “saved”. Instead of the data being sent to the server with an XHR, if the client is offline the updategram is just persisted to disk. Even when online, the data is continually saved to the disk for offline use at any time. All this took very little extra coding since we just serialized the server messages rather than actually transforming them into SQL statements that would store the data in SQL-Lite.

For all of this to work we needed to be notified when the computer is connected to the network. This is done in the nitobi.air.Window class by using the AIR service monitor. This has the additional requirement of having the servicemonitor.swf library in the web page by using a script tag with the src as servicemonitor.swf. To create the service monitor we do something like this:

[code]
var req = new air.URLRequest(’http://www.adobe.com’);
this.monitor = new window.runtime.air.net.URLMonitor(req);
this.monitor.addEventListener(
air.StatusEvent.STATUS, handleStatusChange
);
this.monitor.start();
[/code]

Where the handleStatusChange method will notify any objects that are connected to the the onOnline and onOffline events of the nitobi.air.Window class.

[code]
nitobi.air.Window.prototype.handleStatusChange = function(evt) {
// Fire the event for online / offline notification
if (evt.code == “Service.unavailable”)
onOffline.notify();
else
onOnline.notify();
}
[/code]

For writing the data to disk we use the AIR filesystem integration and wrap it all in two IO methods for reading and writing. The air.File.applicationStorageDirectory is (on Windows) in c:\documents and settings\username\application data\Application-Name folder.

[code]
nitobi.data.IO.readXml = function(filename) {
var file = air.File.applicationStorageDirectory.resolve(filename);
var stream = new air.FileStream();
stream.open(file, air.FileMode.READ);
var str = stream.readMultiByte(file.size, air.File.systemCharset);
stream.close();
return nitobi.xml.createXmlDoc(str);
}

nitobi.data.IO.writeXml = function(xmlDoc, filename) {
if (typeof xmlDoc != ’string’) xmlDoc = nitobi.xml.serialize(xmlDoc);
var file = air.File.applicationStorageDirectory.resolve(filename);
var stream = new air.FileStream();
stream.open(file, air.FileMode.WRITE);
var str = stream.writeMultiByte(xmlDoc, air.File.systemCharset);
stream.close();
}
[/code]

I think that those were definitely the coolest parts of the application and made for a a pretty sweet little app for managing Salesforce Contacts and Accounts. There is still a little more work that I would like to do in the coming weeks like allowing adding and saving of both Contacts and Accounts without VCards as well as some other searching features. Alas, this will have to do for now :) Also, when Adobe gets XSLT support in there it will be even more awesome!

You can check out the half baked source code here and get the AIR application for installation here. I am working on a version of the AIR app that will allow the user to enter their Salesforce.com credentials and actually see their data - and there will be a HUGE disclaimer that you use at your own risk :D
Update: I just found out that the Mac version of AIR does not have XPathResult (!!!) so selectNodes doesn’t work … sorry Mac users but it should be fixed soon.

.



* onAIR Bus Tour - Next Stop Vancouver

Posted on July 11th, 2007 by Dave Johnson. Filed under AJAX, JavaScript, Nitobi, Uncategorized, air.


Tonight the Adobe onAIR Bus Tour is stopping in Vancouver - home of Nitobi. I think that the bus should be rolling into town right about now.

Andre will again be giving his _amazing_ presentation about Ajax / JavaScript / HTML development in AIR so be there!

It is at Ceili’s (formerly Sky Bar) - check here for all the detailson.

Tags: .



* IPhone SDK Released!

Posted on July 5th, 2007 by Dave Johnson. Filed under Uncategorized, Web, iphone.


And of course by “SDK” I mean an Apple SDK that consists of a single HTML page with half a dozen snippits of HTML.

Nonetheless there are some good tidbits there.

I was wondering about some event stuff and here is the general event info:


Gesture Result
Double tap Zoom in and center a block of content
Touch and hold Display an information bubble
Drag Move the viewport or pan
Flick Scroll up or down (depending on the direction of the finger movement)
Pinch open Zoom in
Pinch close Zoom out

Remember, since there is no mouse, hover events will not work.

You can have the iPhone make calls for you from HTML pages using tel: in the URL like this:

<a href="tel:1-408-555-5555">1-408-555-5555</a>

An iPhone specific CSS can be applied using the media attribute in the link element - which most developers probably ignore.

<link media="only screen and (max-device-width: 480px)"
	href="iPhone.css" type="text/css" rel="stylesheet" />

Also of interest is the viewport meta tag that lets you tell Safari on the iPhone how to scale and zoom your content:

<meta name="viewport" content="width = 320" />
<meta name="viewport" content="initial-scale=2.3, user-scalable=no" />

For lots more good info check out the recent post on Ajaxian and the google group.

.



* Declarative Ajax and Flex Interop

Posted on July 3rd, 2007 by Dave Johnson. Filed under AJAX, Components, Declarative Programming, FABridge, Flash, Flex, Grid, RIA, Web2.0, XSLT.


This is some code that I wrote about a year ago at the Flex Component Developers Summit (and more recently presented at XTech) to show how declarative Ajax and Flex can work together to create dynamic, rich and compelling Internet applications.

The idea is simple. Take a single declaration - in this case XHTML - of some user-interface component and then use it to build a UI using either Ajax or Flex. All this from just one declaration.

What happens is that we take a single declarative data grid and converts it using XSLT on the client (so it only works Firefox, IE and soon Safari) into a declarative Nitobi Ajax Grid and to a Flex declarative MXML DataGrid. I use the FABridge to get the string of MXML generated from the XSL transformation into a stub Flex application where a Flex DataGrid is instantiated (deserialized) from the MXML declaration. It can an be seen live here (note: create the Flex grid first then the Ajax one - something funny that I can’t be bothered to fix ;)) and the code can be downloaded from here.

So by using a declarative approach and a little XSLT on the client we were able to quickly choose between using a Flex DataGrid or a Nitobi Ajax Grid to display our tabular data in!

Really the most interesting part is the MXML deserialization stuff. The only contents of the Flex application are two functions for performing the deserialization. I have listed the main part of the code that takes an XML document of an MXML DataGrid declaration and actually instantiates a DataGrid according to that declaration. It’s pretty quick and dirty but at least gets the right thing out! Essentially it just looks at each XML element and creates an Object out of it and sets all the properties on it from the XML element attributes and then recurses through the child elements doing the same. There are some special attributes though like datasources that need a little more care.


public function initGrid(html) {
  // setup a tagname to datatype hash - maybe this already exists somewhere
  controls['DataGrid'] = ‘mx.controls.DataGrid’;
  controls['ArrayCollection'] = ‘mx.collections.ArrayCollection’;
  controls['Object'] = ‘Object’;
  controls['columns'] = ‘Array’;
  controls['DataGridColumn'] = ‘mx.controls.dataGridClasses.DataGridColumn’;

  // load the HTML into XML DOM
  var mxml:XML = new XML(’<root>’+html+’</root>’);

  parseXml(AjaxBox, mxml);
}

public function parseXml(parent, mxml) {
  var item:String;
  // get all the elements in our XML doc - this should of course walk the xml tree recursively
  var itemList:XMLList = mxml.elements(’*');

  for (item in itemList) {
    // get the tag name of the XML node
    var tagName:String = itemList[item].localName();

    // get the class by using getDefinitionByName() method
    var ClassReference:Class = Class(getDefinitionByName(controls[tagName]));

    // create an instance of the class
    var myObject:Object = new ClassReference();

    // get all the attributes and set the properties
    var attrList:XMLList = XML(itemList[item]).attributes();
    for (var attr:String in attrList) {
      myObject[attrList[attr].localName()] = attrList[attr].toString();
    }

    // now parse the children of this node
    parseXml(myObject, itemList[item]);

    if (parent.hasOwnProperty(tagName)) {
      parent[tagName] = myObject;
    } else if (parent.hasOwnProperty(”length”)) {
      if (parent.hasOwnProperty(”source”)) {
        parent.source.push(myObject);
      } else {
        parent.push(myObject);
      }
    } else if (parent.hasOwnProperty(”dataProvider”) && tagName == “ArrayCollection”) {
      // This means we need to create a datasource for the Grid
      parent.dataProvider = myObject;
    } else {
      parent.addChild(DisplayObject(myObject));
    }
  }
}

.



* Messenger Bag Reviews

Posted on July 1st, 2007 by Dave Johnson. Filed under Uncategorized.


What an odd coincidence. I was going through my RSS feeds today and found that Web Worker Daily posted a link to the messenger bag review page that I was using just recently when looking to purchase a new messenger bag. I personally went for a Chrome bag. Most people seem to like Bailey Works, RELoad and Chrome.

Tags: .