SitePen is excited to announce Stocker, which demonstrates some of the more advanced capabilities of Dojo, including the newly released DataChart, the DataGrid, Data Store, Comet, Persevere, and BorderContainer. SitePen is also offering a one-day workshop where you will learn how to create Stocker yourself, but I’m here to give you a sneak peak of what Stocker is and how it works.

Stocker uses these technologies to emulate a stock monitoring application. We’re using made up data, but that’s actually more interesting. The Persevere server generates new stock items at certain intervals, and then pushes them to the browser with Comet. Then the Data Store updates its items and triggers an onSet notification. The DataGrid and DataChart are both connected to the same store, and are listening to that event. They then update their displays and show the stock items and their latest data.

Stocker

Persevere

Persevere, which we chose to use inside the robust Jetty web server, allows us to quickly develop a data-driven web application that can directly interface with Dojo, without having to setup a relational database and create Ajax request handlers. It’s similar to Jaxer, in that it is a rich interactive server-side JavaScript environment (though Persevere uses Rhino), and is accessible via JSON-RPC, meaning Persevere is great for pure Ajax front-ends. SitePen’s Kris Zyp has a large number of articles explaining how Persevere works.

Persevere uses JSON Schema for defining the structure of class instances. Stocker uses one class schema definition that looks like this:

"name":"Stock",
"extends":"Object",
"schema":{
	"prototype":{},
	"instances":{"$ref":"../Stock/"},
	"extends":{"$ref":"../Class/Object"},
	"go":function(amount){
		startUpdateStock(amount);
	}
}

As you can see, you can even include methods in the schema, which can be used for a variety of things. The method go() shown here calls the server-side method startUpdateStock(). You can access this method from the command-line through this static class:

JS> Stock.go();

In the server-side code, we start with a set of simple objects on which we base the Stock data. An example of one such object looks like this:

{ symbol:"ANDT", name:"Anduct", price:3.13 }

Note: Stocker uses more properties than this, but it is edited for clarity.

When startUpdateStock() is fired the first time, these objects are read in, randomized, and then saved as a Stock instance. When saved, the instance is written to a table and persisted. Basically it works like this: think of Stock as your SQL table, and each instance as a row of data. The columns in the table are represented by the properties that you see in the object above, such as symbol or price. And all you have to do to write to this table is:

new Stock( { symbol:"ANDT", name:"Anduct", price:3.13 } );

And modifying the data is just as easy. We loop through all of the instances in the Stock class (or table) and change the properties of the object. Persevere even automatically commits the changes for you, so this is all you need to do:

Stock.instances.forEach(function(instance){
	var m = randomizeStockData(instance);
	for(var nm in m){
		instance[nm] = m[nm];
	}
});

Notice we were able to use forEach on the instance array. We’re able to use all the functionality of Mozilla JavaScript 1.7, like array functions or getters and setters, and don’t have to worry about cross-browser issues when writing server-side JavaScript in Persevere.

Comet

In Stocker, we created an arbitrary amount of six Stock instances. Once they are created, the client-side can now fetch them and access their properties using the dojox.data.PersevereStore. Of all the data stores available in Dojo, the PersevereStore is my favorite. You pretty much declare your store with a pointer to your class, do your fetch, and you’re done:

var store = new dojox.data.PersevereStore({target:"/Stock/"});
store.fetch({query:"[?symbol='*']", onComplete: function(_items){
	console.log("fetched:", items)
}});

PersevereStore provides you with a connection to the server via Comet. When we randomized our stock data on the Persevere server, this committed the change to the database. These changes are then pushed to the browser. You can listen for these changes in the onSet event of the PersevereStore:

dojo.connect(store, "onSet", function(data){
	console.log("onSet:", data);
});

DataGrid

Now it’s time to start wiring up the user interface, and believe it or not, things get easier here. The DataGrid is largely the work of Bryan Forbes and Nathan Toone, and is a first class user interface component. We started with the HTML structure that matched the properties we wanted to display from our Stock instances:

Stock Name Symbol Price

You could also add a store and fetch attribute, but we opted to hook this up within the code:

dojo.addOnLoad(function(){
	grid.setStore(store, "[?symbol='*']");
});

The DataGrid has a built in fetch which grabs the current stock instances from Persevere, and then updates the items when the store’s onSet event is fired.

We did some CSS styling so the Grid would match our Stocker theme, and we were done with the Grid!

DataChart

The DataChart is brand new for Dojo 1.3, was created by yours truly, and was built specifically for Stocker, as it was obvious that charting was missing the ease of implementation that DataGrid provides. DojoX has an amazing vector graphics charting system written mainly by Eugene Lazutkin. It has a rich API that allows for maximum customization. However, DojoX charts didn’t support data stores, and while heavy customization is good in some cases, it can also create a barrier of entry for new developers. DataChart provides that interface between the two, all while supporting Dojo Data. I did a full write-up of DataChart in a previous post. The intent was to make DataChart as easy to setup as the DataGrid:

chart = new dojox.charting.DataChart("lines", chartDefault.chart);
chart.setStore(store, "[?symbol='*']", "price");

There is also some custom code that places chart legends inline with their respective items in the Grid. There’s also some code that handles switching between some of the chart types (just to be fancy). But other than that, we were done with charts!

BorderContainer

To get the BorderContainer to work for you, you have to understand that it supports subsets of two different designs, headline or sidebar. If you want the sidebar pane to extend from the top of the layout to the bottom, you’d naturally use sidebar. If you want the header and footer to extend the entire width, you use headline. Within either layout you have five regions: top, bottom, left, right, and center. The center pane stretches to fit, so you set the widths or heights of all panes but that one. Each region can either be a ContentPane or another BorderContainer. Stocker is slightly more complicated than standard layouts allow, so we use a nested BorderContainer.

What follows is the structure of the Stocker layout. For readability, dojoType is type, BorderContainer is BC and ContentPane is CP. Stocker uses the headline design which is the default, so it need not be not set. Its center pane is another BorderContainer with a top and center.

Header
Sidebar
Grid
Chart
Footer

All children of a BorderContainer have an attribute region, which is the location in the design. BorderContainer’s have two other attributes: liveSplitters and gutters. Setting gutters to true puts a margin around it. The Stocker margins are handled in the CSS so these are set to false. The param liveSplitters indicates that one or more of the children will be resizable. A resizable pane acts much like the framesets of yesteryear, that had dividers between them that you could grab and drag to resize the frames.

Therefore, child panes can have the attribute splitter=true, which allows the user to resize it. It’s not obvious which child panes should get this attribute, since the splitter is shared amongst two panes. The trick to knowing is that the center pane, since it’s always stretchy, never gets this attribute—it is always applied to the pane that shares the splitter with it.

The DataGrid and DataChart were inserted in their proper ContentPane containers, the buttons for chart switching were placed in the sidebar, and the header and footer content was implemented. We launched the Persevere server, opened Stocker in our browser and watched the updates!

Conclusion

Stocker was created to show the power of Dojo and some of it’s more advanced components, and how easily they can be implemented in your site or web application. We’ll also be talking about Stocker and Dojo in a number of upcoming conference talks this year. If you’re interested in learning more about Stocker and how to put it together, drop us a line!

SitePen has workshops planned in various locations around world, and we’d love it if you could join us. You’ll learn everything you need to build Stocker and more at the following one-day Intro to Dojo, Charts, Grids, and Comet workshops:

Or, join us for a special two-day Dojo Workshop in Munich, Germany, May 7-8, 2009 with the uxebu team.