Dojo's Industrial-Strength Grid Widget

Dojo's grid widget provides a fierce alternative to the paginated table that has become such a mainstay of modern-day Web application interfaces.
Common Grid Operations

Although the DataGrid's selection property provides useful methods, such as getSelection, that facilitate accessing dojo.data items that back the interface, the DataGrid itself offers myriad methods of its own that provide more direct and finely grained access to the grid and the data that backs it. Here's a quick synopsis of just a few common ones:

  • getItem(/*Integer*/ idx): returns a dojo.data item reflected in the row index.

  • setQuery(/*Object*/ query, /*Object*/ queryOptions): filters the data in the table by executing the query and query options against the store that backs the grid.

  • setStore(/*Object*/ store, /*Object*/ query, /*Object*/ queryOptions): disposes of references to the existing store and attaches a new one, optionally passing in a query and query options for filtering.

  • onRowClick(/*Event*/ evt): called when a cell is clicked; evt is a decorated W3C Event object.

  • onCellClick(/*Event*/ evt): called when a cell is clicked; evt is a decorated W3C Event object.

  • onCellFocus(/*Object*/ cell, /*Integer*/ rowIdx): called when a cell receives focus.

  • setStructure(/*Object|Array*/ structure): provides a row of changing the grid's layout after it is initially rendered.

  • scrollToRow(/*Index*/ idx): scrolls the grid to the row index.

  • setSortInfo(/*Object*/ obj): called to set sorting criteria.

  • sort(): sorts the grid according to the information supplied by setSortInfo.

  • columnReordering: a property that allows for drag-and-drop column reordering on the grid.

As usual, once the API has been unearthed, the implementation details of putting the grid to work are usually straightforward enough. Here are a few examples to get the wheels turning:

/* Filter the grid such that only row items having
 * a name that starts with the letter B appear */
dijit.byId("gridNode").setQuery({name : "B*"});

/* Get the item reflected in row 23 */
dijit.byId("gridNode").getItem(23);

dijit.byId("gridNode").onRowClick = function(evt) {
  /* Display interesting parts of the decorated Event Object */
  console.log("onRowClick: cell", evt.cell);
  console.log("onRowClick: cellIndex", evt.cellIndex);
  console.log("onRowClick: row", evt.row);
  console.log("onRowClick: rowIndex", evt.rowIndex);
  console.log("onRowClick: grid", evt.grid);
};

Editable Data

Given that a grid widget often is nothing more than a visual interface into a data store, it won't be long before you'll not only want to view the data in the store, but also edit it and persist it back to the server. A great testament to the flexibility of Dojo's data APIs is how the grid's architecture builds directly upon the Write and Notification APIs in particular to make this as easy as it should be—meaning, so long as your store implements Read, Identity, Write and Notification, a grid that you attach to it is capable of providing editable cells that “just work”. In other words, the reason you can attach a stock component like an ItemFileWriteStore to the DataGrid and get editable data isn't because of specialized logic that binds the two together, but simply because the ItemFileWriteStore implements the full spectrum of dojo.data APIs. Although the ItemFileReadStore is used for pedagogical purposes, numerous highly useful store implementations are included as part of the dojox.data module.

The necessary changes to the minimal example we have been working with in the previous Listings are surprisingly simple; just change the store to an implementation that supports the Write and Notification APIs and provide a couple extra attributes in the markup for any columns that should be editable. The dojox.grid.cells module provides lightweight wrappers around many common form widgets from Dijit, so let's take a look at a simple change that would make the Label column editable by introducing a select box:


<body class="tundra">
  <!--Remember to have dojo.require'd the ItemFileWriteStore -->
  <span dojoType="dojo.data.ItemFileWriteStore"
        jsId="gridStore"
        url="data.json">
  </span>

  <table id="gridNode"
         dojoType="dojox.grid.DataGrid"
         store="gridStore">
    <thead>
      <tr>
        <th width="50%" field="id">ID</th>
        <th width="50%" field="label"
            cellType="dojox.grid.cells.Select"
            options="foo,bar,baz,qux"
            editable="true">Label</th>
      </tr>
    </thead>
  </table>
</body>

As you might imagine, the DataGrid's custom event handlers, such as onFocus, onBlur, onApplyEdit, onCancelEdit and so on, become increasingly useful for an editable interface. As always, you also may attach event handlers to the store that backs the grid if handling changes at the data level seems more appropriate for your application than tracking UI-related events. Figure 4 shows the editable grid.

Figure 4. An Example of an Editable Interface in the DataGrid

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Excellent article

siva's picture

Excellent article .

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState