Apr 28

Kayak.com: Asynchronous Searching

Ajax, Tech, UI / UX No Comments »

Kayak.com is a website that allows you to search for airfare and travel needs.

It has an interesting search UI.

Go ahead and do a search for a flight, and you will see that instead of the usual:

“I am searching, be back in a minute”

you get:

  • I have done x out of y
  • Here they are
  • Feel free to stop me at any time if you have enough info
  • Oh, and I am done now so here is everything

The funky changing display on the left is fun too. This is a lot nicer for me the user. I get feedback at the right time (when available), and I am engaged.

Apr 04

Holy Google Satellite!

Ajax, Google, Tech, UI / UX 5 Comments »

A friend pointed out the new ‘Satellite’ link on Google Maps.

Go to an address and hit it to see it kick in!

That is very very cool.

Now I just want Google to be more personalized friendly… and let me save common places so I don’t have to type my damn home address in all the time when I do directions ;)

Oh, and it will be really nice to get more map data in there (satellite runs out in many places, and europe will be a nice addition too ;)

And, wouldn’t it be nice to have state lines, lines around cities, etc etc. It can be hard to know what you are looking at sometimes when all you see is Satellite data.

It doesn’t even remember what you have typed before.

It is cool how the satellite work can piggy back off of the standard maps. Instead of mt.google.com there is now kh.google.com which returns the squares as satellite images rather than 2D maps. It is also interesting to see the subtle Google copyright as a watermark.

Mar 15

Using Maven to modularize JavaScript development

Ajax, Builds, JavaScript 1 Comment »

A lot of developers ‘poo poo’ any code that is written in JavaScript.

  • “JavaScript isn’t a real programming language”
  • “JavaScript is just about browser hacker scripts”
  • “You can use it to focus(). Big deal.”
  • “JavaScript is for the HTML designers, not for REAL coders”

Giving thought to your JavaScript code

As such, any JavaScript code in a project, doesn’t get the thought that it deserves. Why would you be anal about unit testing your Java code, and ignoring your JavaScript code?

You no longer need too, as we have JsUnit, and other tools.

Dependencies are dependencies

As soon as you stop thinking of your JavaScript code as a bastard step-child, you can apply the same practices that we have in our other worlds (e.g. Java).

One of the problems with Java web applications, is that you can often do a search for files on a developers hard drive, and see MANY of the same files.

For example, you search for struts.jar, and there are 23 instances of it on the file system. Of course, they are not all the same size, since they are various versions (but you don’t know).

We get around that problem by using a tool such as Maven, or Ivy.

Now, we can define our project dependencies, and the correct versions are tracked, and downloaded automatically. Very nice.

WEB-INF/lib == /scripts

Why don’t we do this with JavaScript code? We have the same problem with commonscript.js as we do with struts.jar. So why not manage it?

Maven JS type

Maven has the base framework that we need to make this quite trivial. First, we can just agree on the ‘type’ of dependency. I am using js. Then you can just add dependencies as per normal:

<dependency>
<groupId>adigio</groupId>
<artifactId>xhr-test</artifactId>
<version>0.1</version>
<type>js</type>
</dependency>

This means that maven will try to grab:

/[groupId]/[type]s/[artifactId]-[version].[type]

or in the example above:

/adigio/jss/xhr-text-0.1.js

from the various repositories that you have setup in your project.properties:

maven.repo.remote=http://adigio.com/maven,http://www.ibiblio.org/maven,http://www.codeczar.com/maven,http://xdoclet.sourceforge.net/repository,http://dist.codehaus.org

NOTE: ‘[type]s’ is hard-coded. There is no way to map “when you see type ‘js’ look in directory ’scripts’, or something like that. This means that ‘jss’ looks a lil’ silly :).

maven-war-javascript

So, we didn’t have to do anything to get Maven to start grabbing dependencies for us. But, in our projects we don’t just want to grab some JavaScript modules and put them in your local repository. We want to use them :)

Rather than writing some manual goals to handle this, I wrote a Maven plugin which piggy-backs on the war plugin.

The maven-war-javascript-plugin offers a war:js / war:js:copy-scripts goal. This manually looks through your dependencies, and copies any JavaScript modules to your web app (in the scripts directory by default. To change, use the maven.war.javascript.dir property).

However, although you have a goal in which you can kick off this task, in practice you don’t need to use it. The plugin registers itself with the war module, and whenever it is invoked, it sneaks in and does the copy. So, it is a seemless introduction!

Installation

To download and install the plugin, you can simply:

  • Add: http://www.adigio.com/maven to maven.repo.remote
  • Run the commmand: % maven -DartifactId=maven-war-javascript-plugin -DgroupId=adigio -Dversion=0.1 plugin:download

Conclusion

So, now I can take JavaScript more seriously, and can start managing my JS dependencies with the care and loving touch that I do with the immense amount of open source library bloat :)

From Ajaxian.com

Mar 14

XMLterm: The marriage of the command line and rich ui

Ajax, HTML, JavaScript, Tech, UI / UX 200 Comments »

A friend pointed me to a (seemingly old) project called XMLTerm. XMLTerm is a mozilla based “A graphical command line interface”.

At first you may laugh, and ignore some of the security implications for now, but this could actually be quite cool.

Ajax could also come in to really help this out.

Some thoughts:

  • % du: When you do a ‘du’, wouldn’t it be cool to show a pie chart usage as well as the numbers?
  • % ssh [TAB]: tcsh came up with the ‘complete’ command, which lets you get smart with your tabbing. We can take that to a new level with a bit of UI integration. If you hit TAB after typing a command that needs a host (e.g. ssh, scp) then a select list can appear with your list of hosts
  • % history: Since we can place cool widgets in places, we could have a history bar which would allow you to click on an item to rerun it. Command Line Suggest could also get pulled up if you TAB at the beginning of a command, showing a drop down on history.

The XMLTerm site itself has ideas on graphical ls which shows thumbnails, and a special cat which groks HTML, images, etc.

In theory, this could be an interesting marriage of the command line interface (power), and richer functionality (not just text).

Mar 14

Announcing Ajaxian.com

Ajax, JavaScript, Tech, UI / UX 1 Comment »

Ben and I have had great feedback from the presentations that we have given on Ajax, so we created Ajaxian.com, as a place to talk about all things Ajax.

For instance, today we wrote about Handling usability concerns, such as the back/forward buttons, and bookmarking in the browser.

The entry talks about the opensource Dojo Toolkit, and its new bind() mechanism.

Mar 10

Instant Edit: a look at the Wiki of the future?

Ajax, JavaScript, Tech 4 Comments »

If you check out Instant Edit you see an example of changing a couple of pieces of content on a web page.

What if you extrapolate that a little, and think of a Confluence Wiki?

Wouldn’t it be amazing, if I could be viewing my Confluence install, and on any page I can just double click, or ctrl-click, or something… to open up the area that I am on in edit mode.

Then I type in my changes, drag an image to the area, and it is all saved.

This is a holy grail of Wiki for me. No software needed. WYSIWYG. Simple enough for non-techies to work with (even CamelCase is too much for some ;).

Another example is Live Preview. Right now, there could be a preview pane, and as you type, it groks your Wiki Syntax and converts to the HTML view… all on the fly!

Mar 07

Google AdSense XmlHttpRequest Prediction

Ajax, Google, JavaScript, Tech 4 Comments »

I currently never see a Google Ad from AdSense. This is because I have installed AdBlock for Firefox.

I have blocked the iframe, and nothing from the google ad servers is shown.

How can Google get around this problem? One solution would be to use XmlHttpRequest:

  • Have XHR go back to the servers to get the ad content
  • Add this content to a <div> dynamically

Of course, this isn’t a solution. We could then block those div elements based on IDs. So, Google would probably want to randomly create div ids for the content.

Also, there are many other possibilities. The ads could change dynamically based on:

  • Where you are on the page
  • If you are mouse over a div with a given rel tag, the ad could change to something relevant to that area even
  • “Those who were here, also went there”
  • etc..
Mar 06

Applying concerns to JavaScript with Ajax

Ajax, JavaScript, Tech 28 Comments »

You tend to see a lot of copy ‘n paste reuse in JavaScript usage. It just seems to be that kind of mentality. One example of this, is asking for ‘permissions’ from the browser that you may do when building a rich application.

For example, Ben and I had to do this for RSSBling (rich javascript RSS viewer with dynamic offline capabilities).

Security Management with Mozilla

Mozilla needs permission to open up the platform (such as reading from disk, writing to disk, talking to different hosts, etc).

This is where you can sign your code.

You need to ask permission to use these features, which can look something like:

try {
if (netscape.security.PrivilegeManager.enablePrivilege) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
}
} catch (ex) { // eat it
}

Security Code Duplication

You often see duplication such as:

function getFeeds() {
try {
if (netscape.security.PrivilegeManager.enablePrivilege) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
}
} catch (ex) { // eat it
}

var xhr = new XMLHttpRequest();
xhr.open("GET", ((useProxy) ? proxyBaseUrl : "http://") + baseUrl + "/listsubs", true);
xhr.onreadystatechange = function() {
parseFeeds(xhr);
};
xhr.send(null);
}

function buildFeeds(feedXML) {
showLoading();

try {
if (netscape.security.PrivilegeManager.enablePrivilege) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
}
} catch (ex) { // eat it
}

var outlines = feedXML.getElementsByTagName('outline');

...
}

etc etc, duplicating the security piece

Security Code Encapsulation

Firstly, we don’t want to have all of those lines of code. You could fall into the trap of coming up with:

function securePrivilege(priv) {
// insert the try/catch code from above, plus anything for the other browsers
}

Then you could make sure that you call securePrivilege('UniversalBrowserRead') before you need it. This will not work at all, as the way that enablePrivilege does its job, is that the privilege that you secure, is only applied in that scope. This means that the priviledge is only even around INSIDE securePrivilege(priv), and is thus useless :)

Security Code Encapsulation with Closures

Luckily, JavaScript has some nice features which allow us to get around this problem. What you can end up doing, instead of calling securePrivilege(..), you call a method which:

  • Takes the function to call
  • Sets up the priviledge
  • Calls the function

This could look something like this:

function applyPriviledge(priviledge, functionCallback) {
// -- enablePriviledge first
try {
if (netscape.security.PrivilegeManager.enablePrivilege) {
netscape.security.PrivilegeManager.enablePrivilege(priviledge);
}
} catch (ex) { // eat it
}

// -- Call the function itself
functionCallback()
}

// -- Helper functions for particular priviledges
function applyReadPriviledge(functionCallback) {
applyPriviledge('UniversalBrowserRead', functionCallback);
}

You would use this with something like:

function getCount() {
applyReadPriviledge(setupXHR);
}

function setupXHR() {

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://sqlaop.com/xhr/counter.jsp", true);
xhr.onreadystatechange = function() {
countCallback(xhr);
}
xhr.send(null);
}

function countCallback(xhr) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
applyReadPriviledge(function() {
updateCountDom(xhr.responseXML)
});
} else if (xhr.status == 401) {
alert("Username or password incorrect");
} else {
alert("Some kind of HTTP-related glitch occured.");
}
}
}

Encapsulated, but not rid of the cross cutting concern

This is certainly a lot nicer than copying and pasting the lines of code all over, but wouldn’t it be nice if I could say:

Whenever I make a call to XMLHttpRequest, or working with a DOM back from it, or … then please apply the security first

What am I asking for? Well. JavaScript AOP of course! ;)

Mar 05

RE: AJaX: Two steps forward… Two steps back?

Ajax, JavaScript 1 Comment »

John Reynolds is worried about the idea of having JavaScript run rampant with Ajax.

I totally understand the concerns however, I have a couple of comments:

  • JavaScript and Ajax isn’t the problem. It is how you deal with it. For too long JavaScript == ‘for the web developer to hack away’. We do need tools, and we need practices to help manage them. I would love a clean way to declare “this JavaScript wants to import FooModule version 2.3″ and it is all managed for me (for example).
  • Don’t use the technology for the sake of it. Compare the effort to your other choices. E.g. look at Google Suggest. Would it be better for them to have a FLASH version to do the work? or use Ajax?
  • Frameworks will be here to help. A lot of components can be written to grok this technology so you don’t have to write the JavaScript. We will just have richer widgets.
  • XMLHttpRequest isn’t new!

Development is all about tradeoffs. I think that there are situations where the correct tradeoffs mean that Ajax is a good solution.

Mar 01

TheServerSide Symposium, Microsoft Dev Summit, and AOSD

AOP, Ajax, Conference, Java, Microsoft, Tech, Travel 1 Comment »

I have a fun and busy couple of weeks coming up:

TheServerSide Symposium

This week I will be in Vegas for the 3rd TSS Symposium. It is always a pleasure to see everyone, have some good geek talk, and some drinks ;)

I am going to be presenting on AJaX technology, Groovy, and may even be on a panel ;)

Microsoft Developer Technology Summit

I am really looking forward to the Microsoft summit, with the likes of Matt Raible, Ben Galbraith, and everyone else. It will be really interesting to see what Microsoft has to say to us, how they pitch it, etc. I am going to soak up having the time to spend looking at Indigo and the like.

I was even going to see if Don would like to bring in his kids to do some Ruby, but I guess now It’s down to Scheme or Logo :)

AOSD

AOSD is in Chicago this year, which is nicely down the road. I will be chairing a panel, and spending time with great guys to discuss libraries for AspectJ 5, which I am really excited about.

All, in all, a great few weeks! I hope to see some of you there!