Defining Grid Structures
In the Hello dgrid tutorial, we explored the basic single-row column structures that dgrid has to offer, and in this tutorial we aim to demonstrate further options for arranging columns.
For the examples in this tutorial, we will be creating a grid with
various column structures containing information on hall of fame
batters. We will start off with a simple baseline grid containing just
the batters' first and last names. We'll store our batter information in
a JSON file and use the dstore/RequestMemory
module to pull it in.
<div id="grid" class="grid"></div>
require([ 'dstore/RequestMemory', 'dgrid/OnDemandGrid' ], function (RequestMemory, OnDemandGrid) { var grid = new OnDemandGrid({ collection: new RequestMemory({ target: 'hof-batting.json' }), columns: [ { field: 'first', label: 'First' }, { field: 'last', label: 'Last' } ] }, 'grid'); grid.startup(); });View Demo
Remember to call startup
since we are creating this grid
programmatically.
Parts of the Grid
The structure of a grid is comprised of multiple parts. Let's look at these parts in detail.
Header
The header contains cells which display the label of each column. It can
be disabled by setting showHeader: false
in the arguments
object passed to the Grid constructor; it can also be displayed or
hidden later using set("showHeader", ...)
Content
This is the region where rows are rendered for each data item.
Column Set
The dgrid/ColumnSet
mixin provides functionality which
divides a grid's column structure into multiple distinct sets, each of
which manages its columns' horizontal scrolling independently. This
makes it possible to keep certain columns in view even while others are
scrolled out of viewing range.
Usage of column sets is completely opt-in; this will be further explained later in this tutorial.
Row
The content section contains multiple rows of data. Each row represents a single data item.
Sub-row
Sub-rows allow for breaking up the representation of each item across multiple rows, which can aid in readability when there are many fields to display. Since each item's full representation is already commonly referred to as a "row", we refer to each of these rows within each item as "sub-rows" to distinguish between the two concepts.
Cell
The smallest element of the grid, each cell typically represents one field of a single data item.
Defining Sub-rows
Sub-rows can be useful when there are many fields to display. To
define a sub-row, we pass an array of arrays via the subRows
property of the arguments object. Each inner array defines the columns
for a single sub-row, in order; thus, in the following example, the first
inner array defines the top sub-row and the second array defines the bottom
sub-row:
require([ 'dstore/RequestMemory', 'dgrid/OnDemandGrid' ], function (RequestMemory, OnDemandGrid) { var grid = new OnDemandGrid({ collection: new RequestMemory({ target: 'hof-batting.json' }), subRows: [ [ { field: 'first', label: 'First', rowSpan: 2 }, { field: 'last', label: 'Last', rowSpan: 2 }, { field: 'bats', label: 'Bats', rowSpan: 2 }, { field: 'throws', label: 'Throws', rowSpan: 2 }, { field: 'totalG', label: 'G' }, { field: 'totalAB', label: 'AB' }, { field: 'totalR', label: 'R' }, { field: 'totalRBI', label: 'RBI' }, { field: 'totalBB', label: 'BB' }, { field: 'totalK', label: 'K' } ], [ { field: 'totalGAB', label: 'Games as Batter', colSpan: 2 }, { field: 'totalH', label: 'H' }, { field: 'total2B', label: '2B' }, { field: 'total3B', label: '3B' }, { field: 'totalHR', label: 'HR' } ] ] }, 'grid'); grid.startup(); });View Demo
When subRows
is specified, it supersedes columns
.
In fact, defining subRows
with a single
inner array is equivalent to defining columns
as an array.
You may have noticed that due to the widths of the columns in this example, the entire grid horizontally scrolls. This can tend to happen when there are many fields to display. Next we'll explore an alternative solution to situations such as this one.
Defining Column Sets
Column sets allow us to define complex grid structures involving multiple independently-scrolling sets of columns, each containing one or more sub-rows. Column set functionality is provided via a separate mixin, since it is a feature that isn't necessarily used in the majority of cases.
Thus, to incorporate support for column sets into a grid, we must first
use dojo/_base/declare
to create a grid constructor which
includes the functionality from the ColumnSet mixin. We can then use the
custom constructor the same way we used OnDemandGrid, and additionally
specify the columnSets
property:
require([ 'dstore/RequestMemory', 'dgrid/OnDemandGrid', 'dojo/_base/declare', 'dgrid/ColumnSet' ], function (RequestMemory, OnDemandGrid, declare, ColumnSet) { var CustomGrid = declare([ OnDemandGrid, ColumnSet ]); var grid = new CustomGrid({ collection: new RequestMemory({ target: 'hof-batting.json' }), columnSets: [ /* ... */ ] }, 'grid'); grid.startup(); });
Like subRows
, the columnSets
property accepts
a nested array; however, this array contains three levels of
arrays (column sets, sub-rows, then individual columns). This can be a
confusing concept, so let's see a working example of it:
require([ 'dstore/RequestMemory', 'dgrid/OnDemandGrid', 'dojo/_base/declare', 'dgrid/ColumnSet' ], function (RequestMemory, OnDemandGrid, declare, ColumnSet) { var CustomGrid = declare([ OnDemandGrid, ColumnSet ]); var grid = new CustomGrid({ collection: new RequestMemory({ target: 'hof-batting.json' }), columnSets: [ [ [ { field: 'first', label: 'First'}, { field: 'last', label: 'Last' } ], [ { field: 'bats', label: 'Bats' }, { field: 'throws', label: 'Throws' } ] ], [ [ { field: 'totalG', label: 'G' }, { field: 'totalAB', label: 'AB' }, { field: 'totalR', label: 'R' }, { field: 'totalRBI', label: 'RBI' }, { field: 'totalBB', label: 'BB' }, { field: 'totalK', label: 'K' } ], [ { field: 'totalGAB', label: 'Games as Batter', colSpan: 2 }, { field: 'totalH', label: 'H' }, { field: 'total2B', label: '2B' }, { field: 'total3B', label: '3B' }, { field: 'totalHR', label: 'HR' } ] ] ] }, 'grid'); grid.startup(); }); });View Demo
Each individual column set will have a horizontal scrollbar if its columns' widths exceed the width of the column set itself. This allows one column set to scroll while the others remain stationary.
To better understand the way we can style this grid to allow the second column set to scroll, let's take a look at the CSS used for the example:
.grid { width: 700px; margin: 10px; } /* Default all cells to 80px width */ .grid .dgrid-cell { width: 80px; } /* Make the columns for first/last name wider */ .grid .field-first, .grid .field-last { width: 100px; } /* For the column set example, make each column set occupy half the total grid width. */ .grid .dgrid-column-set-cell { width: 50%; }
In this example, the total grid width is 700px
. Since the
combined widths of the columns in the right column set exceed the total
width allotted to that column set, the content overflows and a scrollbar appears.
Unlike the previous sub-row example, however, in this case only the
content within the right column set scrolls.
As seen in the above example, the most common way to set the width of a
specific column is by using the .field-<fieldname>
CSS class.
Defining Spanned Column Headings with the CompoundColumns Extension
In addition to the standard column structures explained previously, a
more recent addition to the dgrid project is the CompoundColumns extension.
This extension adds the ability to define a column structure which includes
additional spanning header cells above the actual columns in the grid.
It is used the same way as a mixin; the only difference is it lives in the
extensions
subfolder since it is a less common feature:
require([ 'dstore/RequestMemory', 'dgrid/OnDemandGrid', 'dojo/_base/declare', 'dgrid/extensions/CompoundColumns' ], function (RequestMemory, OnDemandGrid, declare, CompoundColumns) { var CustomGrid = declare([ OnDemandGrid, CompoundColumns ]); var grid = new CustomGrid({ collection: new RequestMemory({ target: 'hof-batting.json' }), columns: [ { label: 'Full Name', children: [ { field: 'first', label: 'First' }, { field: 'last', label: 'Last' } ] }, { field: 'totalGAB', label: 'Games as Batter' } ] }, 'grid'); grid.startup(); });View Demo
Conclusion
dgrid offers powerful components for efficiently presenting data. Whether just displaying a few simple columns, or many fields in a complex structure, dgrid has you covered. This tutorial has provided simple examples of each of the types of structures dgrid supports. For more information, see the respective pages of the dgrid documentation.