Generic Ajax Widget

As part of this article, I've included a generic Ajax widget that simply grabs a URL and parses out a small section of the DOM that I'm interested in.It’s a good jumping off point to get going with an Ajaxified widget.

Stability

Dashcode is particularly ropy with Safari 3. With Safari 2 it’s much more stable. Since there is the occasional crash from Dashcode, I would recommend constantly saving your project as you're coding. I found more than 10% of the time, Dashcode would crash and result in a total loss of my code from the last save point.

Also, I've noticed that dumping a lot to the run log, when viewing the log, can cause Dashcode to slow right down to almost hanging. Best to avoid dumping large amounts of HTML to the log.

However - and this is a big one - the upside of programming with Dashcode is worth the risk of the crash, because it’s takes most work out of the design process.

Since you're using it’s GUI to drag and drop your design and how the user will interact with it, rather than having to code the look and feel by hand.

Designing Widgets

The interface and the library component of Dashcode makes it possibly the strongest app for developing widgets. It’s 2 minutes work to create a glass effect on your widget, or to place the elements on the window and get going.

I would strongly recommend studying other widgets, and reading through the Dashcode design recommendations as it’s easy to design a widget that works, but twice the work to design a widget that’s usable and works well.

You'll find you can place widget-type objects on your widget, like scroll areas or gauges - but to handle them in the code isn't entirely intuitive, which is why the best source of understand how these interface elements work, is by opening up other widgets that already make use of the element.

Controls

Dashcode offers the easy integration of bespoke elements such as the scrollarea, gauges and other such sexy components.They're pretty easy to drop on to the widget from Dashcode, but until you're coding, they're not immediately obvious how they work.The help is limited, so I would recommend to develop by tutorial, in particular, look for the 'refresh()' methods - as this seems to be a fairly standard way to redraw objects.

I used this technique in my HTML entities widget to keep the widget small when it’s dropped in to the Dashboard, but to allow it to grow dynamically when the user searched for a particular HTML entity.

Running system commands

This is one of the few areas that’s well documented in the provided API.

You can run system commands using the following type of command:

widget.system('ps -auxww | grep ' + myCommand, null);

What you should keep in mind, is that you can run any command through the system method. This includes Perl, Ruby, AppleScript and anything else that suits your needs. Using these commands I've recently been able to create a widget that queries Mail’s SQLite’s database via Perl. It was a case of running the system method and capturing the output (and in my case, eval'ing it from a JSON output).

Ajax in the widget

You widget supports a variation of the Ajax object (or rather xmlhttprequest object).

This version isn't bound by the usual security constraints of a browser - most importantly, it can request content from any domain.

To execute any Ajax requests from your widget, ensure you have the Allow Network Access attribute turned on - otherwise the Ajax will fail without any given reason.

For example, you could use Ajax to pull your film page from IMDb and then parse the XML for the elements of interest.

However, if you do want to pull some data from a web page and process it using the DOM returned you have to fiddle the request - in particular the responseXMLwill be null because the page being returned isn't text/xml - it’s text/html. You can do it using the following (in jQuery syntax):

This getDOM function is pretty horrible - but it works. I tried using DOMParser and tried using Ajax local data trick and I tried using an iframe to inject the XLM - but neither would load the XML properly (in fact it would be blank).

The iframe would not load properly because it was still loading the entire frame while I was trying to access it.