Grid browser

We’re excited about the release of Dojo 1.0. In honor of the new release, I’m starting a series on one of the newest additions to the Dojo mix: the Dojo Grid.

When demonstrating Dojo, I prefer tying examples to real-world scenarios. Imagine for a moment that we work at a company that produces gaskets out of sheet material. Each of these gaskets has a part number, a minimum temperature rating, a maximum temperature rating, and maximum pressure rating. Each of these attributes needs to be a column so they can be displayed and sorted so customers can find the information they need in a timely manner. Let’s take a look at how the data looks:

var data = [
	/* part #, min T rtg, max T rtg, max P rtg */ 
	[ '4001', -946, 931, 647 ],
	[ '4002', -601, 1894, 208 ],
	[ '4003', 456, 791, 132 ],
	[ '4004', -259, 2433, 840 ],
	...
];

For the purposes of these exercises, we’ll put the entire set of data into a file data.js. As a disclaimer, the data was randomly generated and doesn’t represent anything real.

Suppose we want to display data in a tabular format and we select the feature-rich Dojo Grid. First, we need to create a model for the data. A quick review of the models the grid provides makes dojox.grid.data.Table a logical choice because it handles data as a list of lists. We’ll delve into the different models later, but for now, assume this is a suitable model.

var model = new dojox.grid.data.Table(null, data);

Next, we need to define the grid structure or layout. This represents the data view. Our structure object is:

var cell = { name: 'Cell Name' };
var subrow = [ cell ];
var view = { rows: subrow };
var structure = [ view ];

A structure is a list of views, a view is an object that contains a list of subrows named ‘rows’, and a subrow is a list of cells. When displaying our example, a list of gaskets, we need one view, one subrow, and four cells:

var subrow = [
	{ name: 'Part Number' },
	{ name: 'Minimum Temperature (F)' },
	{ name: 'Maximum Temperature (F)' },
	{ name: 'Maximum Pressure' }
];

var view = {
	rows: [ subrow ]
};

var structure = [
	view
];

Now that we have our data in the model and we’ve defined the data appearance, let’s create a grid:

We have a grid that displays our data. That’s just the beginning.

The first improvement suggested is temperatures are missing the degree symbol, °, so let’s add that. Each cell in a subrow can have a formatter property, a function to format the displayed data:

function formatDegrees(value){
	return value + '°';
}

var subrow = [
	{ name: 'Part Number' },
	{ name: 'Minimum Temperature (F)', formatter: formatDegrees },
	{ name: 'Maximum Temperature (F)', formatter: formatDegrees },
	{ name: 'Maximum Pressure' }
];

Our updated grid displays temperature units. This is great! We have a grid that sorts our data and displays it the way we want.

For our next order of buisness, suppose that the president of the company, Bob, wants the minimum temperature displayed above the maximum temperature. Not a problem!

Review the view and subrow. View has a property named rows which is an array of sub-rows which is itself an array of cells. The sub-rows form a mini table in each row of the grid. And just like HTML tables, the cells of sub-rows can be spanned across rows:

var subrow1 = [
	{ name: 'Part Number', rowSpan: 2 },
	{ name: 'Minimum Temperature (F)', formatter: formatDegrees },
	{ name: 'Maximum Pressure', rowSpan: 2 }
];
var subrow2 = [
	{ name: 'Maximum Temperature (F)', formatter: formatDegrees }
];

var view = {
	rows: [
		subrow1,
		subrow2
	]
};

Bob should be pleased with the resulting grid. But Bob is particular, and now suggests that the rating columns are a bit too wide, and the part number needs prominence. This requirement is easily satisfied by defining a width property on each cell of a sub-row that contains a valid CSS width:

var subrow1 = [
	{ name: 'Part Number', rowSpan: 2 },
	{ name: 'Min. Temp. (F)', formatter: formatDegrees, width: '60px' },
	{ name: 'Max. Pressure', rowSpan: 2, width: '60px' }
];
var subrow2 = [
	{ name: 'Max. Temp. (F)', formatter: formatDegrees, width: '60px' }
];

We have a grid that makes Bob happy, for now. Next week, we’ll tackle more feature requests from Bob, like inline images and sub-grids, and we’ll go over the different models that the Grid provides.

This article would not be complete without a gratuitous iPhone grid screenshot:

Grid iPhone