Dojo Data Grid – Part 9: Multi-Row Entries

Up to this point, our grids have been standard tabular structures displaying a single row for each entry, but it’s possible to span multiple rows with each entry. In this post, I’ll show you how to implement it and work with the formatting.

Dojo Data Grid Series

Dojo Data Grid Row Control

Along with the Dojo Data Grid control and the Dojo Data Grid Column control, there is a Dojo Data Grid Row control, which is optional to use when laying out a grid.


Once you add one or more row controls to the grid, you can add columns inside of them. The row control contains an editable area into which you can drag and drop column controls.

However, it is important to note that if you use row controls, all columns must be inside of a row control or they will not all display. When I have a few columns displayed directly in the grid control and a few more in a row control, the ones in the row control are not displayed in the grid.

For the sake of comparison, this screen shot shows a grid that renders exactly the same with and without a row control.



To have an entry span multiple rows, just add multiple row controls and add columns to them. Here’s an example of displaying a person’s name on one line and their address on a second line:


The grid stacks the column headers and displays the data like this:

But there’s supposed to be 4 columns in the second row!

Grid Alignment Caveat

It appears that the grid will show as many columns as are in the first row. There should have been 4 columns in the second row, but they aren’t displayed. (I tested changing the auto-width attribute and setting column widths, but that had no effect on the outcome.)

If I flip the rows so that the address row (with more columns) comes first, then I see all of the data:


Example 2

If I want to take my example a step further and make it look more like a mailing label, I can add another row and move the city, state, and zip down to the third row.

However, that still leaves me with 3 columns in the last row and only two columns in the first row. The good news is that I found that I can just add an empty column to the first row in order to provide space for the third column in the last row.

Grid Column Widths

If you specify column widths in the same column in multiple rows, the width set on the column in the first row will take precedence.

Spanning multiple cells

In this case, we would really want the address line to take up more space, so we could condense the column widths and make the grid entries look more natural.

When you add multiple rows to a grid, it generates a table inside the <div>for the entry to provide the multiple row layout:


Even though I can see that each cell has a colspan attribute, I was unable to find an easy way to tell the column in the second row to span multiple columns. I tried adding attributes and dojo attributes in the source. I used the themeId property and tried to pass settings that work on plain tables, but they were not used by the grid. (It appears that when the dojo code runs to build the grid, it loses the theme ID, because none of the properties are picked up.)

Fortunately, there is a solution. The grid has an onStyleRow event that fires on each row (a) when the grid is created and (b) when you interact with the row (eg hover over it, etc).

Code in this method automatically receives an object that can be accessed via arguments[0] and it provides these properties: index, node, odd, selected, over, customStyles, customClasses. The index is the grid entry index. The odd property is true for every odd-numbered row. The selected and over properties track the state of the row (selected or mouse hover). The customStyles and customClasses properties allow you to dynamically change the styles and/or classes of the row.

The node property is a handle to the DOM node for the grid entry. This is great, because it gives us a starting point to look for any table cells that we need to modify.

In this case, I want the table cell (td) in the second row of the entry to have a colspan of 3. I can locate and modify the setting with this line of dojo code:

dojo.query("tr:nth-child(2) td", arguments[0].node).forEach(function(node) {node.colSpan="3";});

So, I just need to add it to the onStyleRow event of the grid and it will execute on every grid entry.

But, be careful how you add the code. If you select the grid and then go to the Events view and enter code in the onStyleRow event, it doens’t add it to the page properly. It adds this:

<xe:eventHandler event="onStyleRow" submit="false">
  <xe:this.script><![CDATA[dojo.query("tr:nth-child(2) td", arguments[0].node).forEach(function(node) {node.colSpan="3";});]]></xe:this.script>

Make sure you select the grid, use the Properties view >> All Properties > events > onStyleRow and click the button in that property to enter the code and it will add it properly like this:

  <![CDATA[dojo.query("tr:nth-child(2) td", arguments[0].node).forEach(function(node) {node.colSpan="3";});]]>

You can see that the address line now spans 3 columns in the screen shot on the left (the screen shot on the right is the default alignment):

Caveat to adding onStyleRow code

When you add any code to the onStyleRow even, you lose the default styling for every other row and when a row is hovered over.

You can easily replace that style logic by making use of the odd property and over event state of the object in onStyleRow and adding a class or setting the style directly.

Multiple Rows and Sorting

Breaking up grid entries across multiple rows has no bearing on sorting. You can still click column headers to sort and it works just fine.

Up Next

In the next post, we’ll look at full-text and field-specific searching to filter the grid results.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: