-
Notifications
You must be signed in to change notification settings - Fork 295
Core Components
dgrid's primary components fall into the following top-level modules.
This provides the basic facilities for taking an array of objects and rendering as rows
of HTML in a scrollable area. This will automatically include touch scrolling capabilities
(via the TouchScroll
module) on mobile devices.
The List can be used to render an array of data. For example:
require(["dgrid/List"], function(List){
// attach to a DOM element indicated by its ID
var list = new List({}, "list");
// render some data
list.renderArray(arrayOfData);
});
The base List class (inherited by all other classes) exposes the following methods:
-
get(property)
: Returns the value of a given property. Supports custom getter implementations via the pattern_getProperty
(which would map toget("property")
). -
set(property, value)
: Sets the value of a given property. Supports custom setter implementations via the pattern_setProperty
(which would map toset("property", ...)
). -
row(target)
: This will look up the requested row and return a Row object. The single parameter may be a DOM event, DOM node, or in the case of store-backed components, a data object or its ID. The returned Row object has the following properties:-
id
: the data object's id -
data
: the data object represented by the row -
element
: the row's DOM element
-
-
up(row[, steps])
: Given a row object (or something that resolves to one via therow
method), returns a row object representing the row locatedsteps
rows above (wheresteps
defaults to 1) -
down(row[, steps])
: Same asup()
, but operating downward -
on(event, listener)
: Basic event listener functionality; simply delegates to the top-level DOM element of the List, using standarddojo/on
behavior. -
renderArray(array, beforeNode, options)
: This can be called to render an array directly into the list. ThebeforeNode
parameter can be used to render at a specific point in the list. Note that when using store-backed components, this is called automatically. -
renderRow(item, options)
: This method can be overridden to provide custom rendering logic for rows. (The Grid module, introduced next, actually overrides this method.)item
refers to the record from the grid’s data store for the row. -
removeRow(rowElement, justCleanup)
: This method can be extended/aspected to perform cleanup logic when an individual row is removed. -
set("sort", property, descending)
: This can be called to sort the List by a given property; if the second parameter is passedtrue
, the sort will be in descending order. Multiple sort criteria can be specified in the format expected by stores'queryOptions
(an array of objects withattribute
anddescending
properties); this is also the formatget("sort")
will return in. The Grid and OnDemandList modules further extend sort functionality. -
showHeader
: Whether to display the header area; normallyfalse
for lists andtrue
for grids. Can be reset later viaset("showHeader", ...)
. -
showFooter
: Whether to display the footer area;false
by default, but enabled and used by some extensions (e.g. Pagination). Can be reset later viaset("showFooter", ...)
. -
scrollTo(options)
: scrolls to a given point in the grid. Acceptsx
andy
properties; if one is not given, position along that axis is not modified. -
getScrollPosition()
: returns the current position that the grid is scrolled to, in the form of an object containingx
andy
properties.
Lists, as well as all other dgrid components, maintain the following DOM references:
-
domNode
: The top-level DOM node of the component (much like thedomNode
property of Dijit widgets). -
headerNode
: The DOM node representing the header region; mainly applicable to grid components. -
bodyNode
: The DOM node representing the body region (the area which will show rows for each item). -
contentNode
: The DOM node immediately under thebodyNode
, which may potentially be scrolled to accommodate more content than the component's height will allow to fit. -
footerNode
: A DOM node appearing below thebodyNode
; initially empty and not displayed by default.
Grid extends List to provide tabular display of data items, with different fields arranged into columns.
In addition to the List methods outlined above, Grid also exposes the following:
-
cell(target[, columnId])
: Analogous to therow
method, but at thecell
level instead. Thecell
method can look up based on an event or DOM element, or alternatively, a data item (or ID thereof) and the ID of a column. Returns an object containing the following properties:-
row
: a Row object (as would be obtained from therow
method) for the row the cell is within -
column
: the column definition object for the column the cell is within -
element
: the cell's DOM element
-
-
left(cell[, steps])
: Given a cell object (or something that resolves to one via thecell
method), returns a cell object representing the cell locatedsteps
cells to the left (wheresteps
defaults to 1), wrapping to previous rows if necessary -
right(cell[, steps])
: Same asleft()
, but operating towards the right, wrapping to subsequent rows if necessary -
column(target)
: Returns the column definition object for the given column ID; typically analogous tocell(...).column
-
styleColumn(columnId, css)
: Programmatically adds styles to a column, by injecting a rule into a stylesheet in the document. Returns a handle with aremove
function, which can be called to later remove the added style rule.
In the simplest cases, the columns of the grid are defined via the columns
property.
This property can be a hash (object) or array, containing column definition objects.
When columns
is an object, each property's key represents the id and field of the column,
and each value is the column definition object. When columns
is an array,
the numeric indices become the column IDs; fields must be specified within each definition.
Generally, using object notation is slightly more concise and convenient. However, it's worth noting that doing so relies on the order of enumeration employed by the JavaScript runtime. Typically this isn't a problem, as it matches the order in which properties are specified, but one common exception is in the case of keys coercible to numbers.
For example, we could create a grid like so:
require(["dgrid/Grid"], function(Grid){
var columns = {
first: {
label: "First Name"
},
last: {
label: "Last Name"
},
age: {
label: "Age",
get: function(object){
return (new Date() - object.birthDate) / 31536000000;
}
}
};
var grid = new Grid({ columns: columns }, "grid"); // attach to a DOM id
grid.renderArray(arrayOfData); // render some data
...
});
Alternatively, the same columns as above could be defined in an array, as follows:
var columns = [
{
label: "First Name",
field: "first"
},
{
label: "Last Name",
field: "last"
},
{
label: "Age",
field: "age",
get: function(object){
return (new Date() - object.birthDate) / 31536000000;
}
}
];
A column definition may also be specified simply as a string, in which case the value of the string is interpreted as the label of the column. Thus, the simplest column structures can be more succinctly written:
var grid = new Grid({
columns: {
first: "First Name",
last: "Last Name",
...
},
...
}, ...);
Each individual column definition object may have the following properties (all are optional):
-
field
: The property from the object in the list to display in the body of the grid (unless otherwise overridden via theget
function, explained below). In cases wherecolumns
is passed an object, the key of each property represents the field name, and thus this property is normally ommitted. -
label
: The label to show in the header of the grid. Defaults to the value offield
. -
className
: A CSS class to assign to the cells in the column. If unspecified, a default class name of the formfield-<field>
is used, where<field>
is the value of thefield
property. -
id
: The id of the column; normally this is determined automatically from the keys or indices in thecolumns
object or array. -
sortable
: Indicates whether or not the grid should allow sorting by values in this field, by clicking on the column's header cell. Defaults totrue
.- Note that it is always possible to programmatically sort a Grid by a given
field by calling
set("sort", property, descending)
regardless ofsortable
status or even visible presence in the Grid altogether.
- Note that it is always possible to programmatically sort a Grid by a given
field by calling
-
get(item)
: An optional function that, given a data item, will return the value to render in the cell. -
set(item)
: An optional function that, given a data item, will return the value to set for that column on that item. If no value is returned, the originally set value will be used. -
formatter(value)
: An optional function that, given the value to be displayed, will return a string of HTML for rendering. -
renderCell(object, value, node, options)
: An optional function that will be called to render the value into the target cell.object
refers to the record from the grid’s store for the row, andvalue
refers to the specific value for the current cell (which may have been modified by the column definition’sget
function).node
refers to the table cell that will be placed in the grid if nothing is returned byrenderCell
; ifrenderCell
returns a node, that returned node will be placed in the grid instead. (Note: ifformatter
is specified,renderCell
is ignored.) -
renderHeaderCell(node)
: An optional function that will be called to render the column's header cell. LikerenderCell
, this may either operate on the node directly, or return a node to be placed within it.
The Grid component also supports structures with multiple "subrows";
that is, it supports the idea of rendering multiple rows for each data item.
Specification of multiple subrows is very much like specifying columns, except
that one uses the subRows
property instead of columns
, and it receives an
array of columns objects/arrays.
Both the columns
and subRows
properties can be later reset by using the
central set
method.
By default, the Grid renders a header, containing cells which display the
label of each column. This can be disabled by setting showHeader: false
in the arguments object to the Grid; it can also be changed later using
set("showHeader", ...)
.
Some developers prefer specifying column layouts in an actual table structure
because it is more convenient or semantically clearer. dgrid supports this
via the GridFromHtml module. When using this module, a table
element should
be specified as the source node for the grid instance; it then scans for th
nodes within rows (typically placed inside the thead
) to determine columns.
Column properties are specified within the th
, primarily via the
data-dgrid-column
attribute, which should contain a JavaScript object.
Properties which coincide with standard HTML attributes can also be specified
as such, e.g. class
, rowspan
, and colspan
. The innerHTML of the th
is
interpreted as the column's label
by default.
Note that unlike data-dojo-props
, data-dgrid-column
requires that you
include the surrounding curly braces around the object - this allows
alternatively specifying a column plugin instead of just a straight-up object.
(Note, however, that referencing column plugins requires that they be exposed
in the global scope, perhaps under a namespace.)
Examples of creating grids from HTML can be found in the
GridFromHtml.html
and complex_columns.html
test pages.
It is also possible to specify columnsets (for the ColumnSet
mixin) via
HTML tables by using the GridWithColumnSetsFromHtml
module. ColumnSets are
expressed in HTML via colgroup
tags. See the complex_columns.html
test
page for an example of this as well.
The following note applies to Dojo 1.7 only; in Dojo 1.8 this becomes easier
thanks to data-dojo-type
supporting module IDs (see
Dojo ticket #13778).
Additionally, data-dojo-mixins
can be used to declaratively compose dgrid
instances including mixins.
Using the parser in Dojo 1.7 with modules designed purely in the AMD format can
be a bit unwieldy, since the parser still expects data-dojo-type
values to reference variables accessible from the global context. While existing
Dojo 1.x components currently continue to expose globals, dgrid does not do so
by default, since it is written purely in AMD format. Thus, when intending to
parse over dgrid components, it is necessary to expose the components via a
global namespace first. For example:
require(["dgrid/GridFromHtml", "dojo/parser", ..., "dojo/domReady!"],
function(GridFromHtml, parser, ...) {
window.dgrid = { GridFromHtml: GridFromHtml };
parser.parse();
});
This can be seen in practice in some of the test pages, such as
GridFromHtml.html
and dijit_layout.html
.
OnDemandList extends List to provide on-demand lazy loading of data as the user scrolls through the list. This provides a seamless, intuitive interface for viewing large sets of data in scalable manner.
OnDemandList inherits the _StoreMixin module, which implements a basis for
interacting with a Dojo object store
for querying of data. At minimum, this implementation expects a store supporting
the get
, getIdentity
, and query
methods.
OnDemandList requires that a store be specified via the store
property,
and will call the query
method on the store to retrieve the data to be rendered.
OnDemandList will call query
with start and count options so as to only retrieve
the necessary objects needed to render the visible rows. As the list or grid is
scrolled, more query
calls will be made to retrieve additional rows,
and previous rows will be pruned from the DOM as they are scrolled well out of view.
When working with a writable store, for best results, the store should
return query results with an observe
method, which enables the list to keep
its display up to date with any changes that occur in the store after the items
are rendered. The dojo/store/Observable
module can prove useful for adding this functionality.
OnDemandList inherits the following properties and methods from _StoreMixin:
-
noDataMessage
: An optional message to be displayed when no results are returned by a query. -
loadingMessage
: An optional message to be displayed in the loading node which appears when a new page of results is requested. -
getBeforePut
: if true (the default), anysave
operations will re-fetch the item from the store via aget
call, before applying changes represented by dirty data. -
query
: An object to be passed when issuing store queries, which may contain filter criteria. -
queryOptions
: An object to be passed along withquery
when issuing store queries. Note that the standardstart
,count
, andsort
properties are already managed by OnDemandList itself. -
store
: An instance of adojo/store
implementation, from which to fetch data. -
set("query", query[, queryOptions])
: Specifies a newquery
object (and optionally, alsoqueryOptions
) to be used by the list when issuing queries to the store. -
set("store", store[, query[, queryOptions]])
: Specifies a new store (and optionally, alsoquery
andqueryOptions
) for the list to reference. -
refresh()
: Clears the component and re-requests the initial page of data. -
set("sort", property, descending)
: _StoreMixin's version of this defers sorting to the store. -
updateDirty(id, field, value)
: Updates an entry in the component's dirty data hash, to be persisted to the store on the next call tosave()
. -
save()
: Instructs the list to relay any dirty data back to the store. Returns a promise which resolves when all necessary put operations have completed successfully (even if the store operates synchronously). -
revert()
: Clears the dirty data hash without updating the store, and refreshes the component.
OnDemandList also implements the following properties and methods, in addition to those inherited from _StoreMixin:
-
minRowsPerPage
: The minimum number of items that will be requested at one time while scrolling; default is25
. -
maxRowsPerPage
: The maximum number of items that will be requested at one time while scrolling; default is250
. -
maxEmptySpace
: The maximum size (in pixels) of unrendered space below or above the rendered portion of the component; default isInfinity
, which indicates that the size of unrendered space should approximate the total space which would be occupied by all items in the result set. -
bufferRows
: The number of rows to keep rendered beyond each end of the currently visible area of the component; default is10
. -
farOffRemoval
: The minimum distance (in pixels) which must exist between the currently visible area and previously-rendered rows before they are removed from the DOM; default is2000
, but this can be adjusted based on a known maximum height in cases where keeping fewer nodes in the DOM is preferable. -
queryRowsOverlap
: Specifies the number of items to "overlap" between queries, which helps ensure consistency of observed updates to items at page boundaries. The default is1
. -
pagingDelay
: Specifies the minimum number of milliseconds between processing of scroll position changes (and thus also potential store requests when scrolling rapidly); default is15
. -
renderQuery(query)
: Renders the given query into the list. Called automatically upon refresh.
If something should go wrong within OnDemandList's logic, _StoreMixin is
equipped to emit a dgrid-error
event, including the following properties:
-
grid
: The Grid (or List) instance on which the error occurred -
error
: The error which occurred
OnDemandList emits a dgrid-error
event for any error that occurs while
querying the store for data in reaction to scrolling or a refresh
call.
This module is simply the composition of Grid and OnDemandList. For example:
define(["dgrid/OnDemandGrid"], function(Grid){
grid = new Grid({
store: myStore, // a Dojo object store
columns: [
{label: "Column 1", field: "col1", sortable: false},
{label: "Column 2", field: "col2"},
...
]
}, "grid");
...
});