Code Design and Approach for the Next Grid

By on August 5, 2011 10:17 am

Viewing a collection of data in tabular or list form is one of the central components of many applications. We are working on a new design to fulfill the need for a grid to quickly navigate sets of data with familiar controls for productive user interaction in the new world of mobile, lightweight applications. The Dojo DataGrid has long provided a comprehensive grid for Dojo users, but years of Dojo evolution have reached their limit with this component. What was originally a stand-alone, full-featured grid has been migrated to using Dojo modules, asynchronous dojo.data stores, and more. Consequently the DataGrid is suboptimal and difficult to customize and extend. The time has come for a fresh start on the grid. We have been collaborating with IBM on a new grid, and I wanted to share some of the design goals of our development before actually demonstrating the new grid.

Mobile-Ready

The first goal is a grid that can easily be used in mobile applications. This means the grid needs to support mobile-style touch scrolling, including inertia-based scrolling, bouncing at limits, and hovering scrollbars on scroll. Mobile-ready does not mean that the grid is mobile-only. One should easily be able to create applications that are beautiful on the desktop and mobile devices without having to create separate applications. The “mobile context” is quickly becoming the new evil “built for Internet Explorer 6.0” of the web, but applications need to have appropriate controls for touch devices. The next implication of mobile-ready is that components need to be lightweight…

Lightweight

As mentioned before, the existing Dojo DataGrid is large. Minified it is over 150KB with dependencies. We set out to create a grid that can be minified to less than 30KB. The new grid is also designed to take advantage of “baseless” Dojo. This means that it explicitly depends on specific Dojo modules and can actually be built with a subset of Dojo base rather than relying on full Dojo. Minified Dojo base is around 90KB, but the new grid works with a small subset of this. Your total application JavaScript can be remarkably small with this new grid, giving you blazing fast load times.

Modular and Composable

The new grid is also designed to be highly modular. The grid package is designed to consist of various different modules or plugins that can be combined by the developer to create a grid with exactly the functionality that is needed. This furthers the goal of being lightweight. This also makes it much easier to work with the grid. The grid package is designed to consist of clean, modular classes, each being only a couple hundred lines or less of well-commented code, making it easy to understand the existing codebase. And because grids are created with straightforward class/mixin composition with dojo.declare, it is very simple to extend existing modules or create new modules to add functionality to the grid.

Dojo Object Store Driven

The new grid is designed to be driven by the new object store API. It improves on the existing dojo.data API, is very simple, easy to use, and standards-based (based on the standard HTML5 IndexedDB object store API), and will be fully supported by the new grid.

Performance

The new grid is designed be fast. Very fast. The new lightweight design for quick loading is one of the most important aspects, but the grid also employs the latest techniques for performance optimization at runtime. Perhaps most importantly is reduction of layout measurements, one of the most expensive operations that can possibly be executed on the browser. These operations force browser layout overhead and substantially harm performance. The existing DataGrid performs significant measurement operations, often measuring every single row. The new grid is designed to only measure when absolutely necessary, with only one or two measurements being performed in a typical setup.

DOM-based Element Creation

The existing DataGrid was also built in the day when innerHTML was the fastest way to create DOM structures. Now our most performance sensitive environment is on the mobile device running WebKit where innerHTML sets are actually much slower than DOM element creation calls. Using DOM-based operations can also greatly simplify code. Typically most elements that are created need to be referenced for various operations like setting event handlers. The old innerHTML methods are extremely brittle and difficult to extend, typically require complicated refactors to do string manipulations and timeout-based querying to retrieve element handles. By using DOM operations, it is easy to track references and build extensions that can naturally modify individual elements.

CSS-Driven

Rather than programmatic measurement-driven layout, the new grid is designed to rely on CSS to layout the grid. Not only does this perform much better, it makes it much easier to style the grid and customize the look and layout. The existing DataGrid relies too much on programmatic styling which involves setting inline styles. This is rightly considered harmful as it puts in place styles with the highest level of specificity, making it very painful to override the styles in user stylesheets.

CSS Modularity

The new grid is designed to utilize CSS best practices with proper separation of structure and skin. The new grid utilizes a new CSS plugin to auto-load the structural CSS (no more manual addition of component-specific styles!), and generic skin CSS can be applied to give different color schemes and themes.

Simple List Support

Often applications need to render a list of data, but don’t want to use column-based grids. The grid package will use a general purpose list base class that can be used to simply display a set of data in rows (with any custom row rendering) while still leveraging functionality like touch scrolling, store interaction, sorting, virtual scrolling/paging, and performance optimizations!

The new grid is also designed to easily render from a simple JavaScript array of data without having to go through an object store. While object stores can be a powerful tool for abstracting away the complexity of server interaction, paging, sorting, and object manipulation, being able to use a simple array can make simple lists and grids much easier to create.

New Event Support

The new grid is designed to leverage the new event handling capabilities in Dojo 1.7. This includes the succinct on() method for listening to events, and the new grid will also fire native DOM events for actions like data changes and row/cell selection.

Tree Module

The new grid will include a tree module to make it easy to create expanding grids. The tree plus grid is a powerful combination for display of hierarchical data.

Hopefully you are looking forward to the new grid. Next we will take a look at the actual grid and see how we can use it today.

Comments

  • Ron MacCracken

    This sounds great, and I’m very glad that we have not yet refactored our own table widget with the existing dojo Grid since it still seems to be evolving. I would like to as a few questions that would help remove the need for our own widget.

    1) Will this table support frozen headers? Currently our widget only provides this support if using FF3 since table-body scrolling was removed in FF4. I don’t like this restriction, but it was the best we could do with using just a single HTML table.

    2) Will this table support frozen columns as in Excel? We currently allow you to freeze up to the first 3 columns. The remainder do not scroll, but we have arrow buttons and keyboard shortcuts to move left and right. We do this simply by hiding and showing columns using CSS.

    3) Will this table support automatic layout rather than fixed column widths? We currently use a single HTML table rather than using two (or even one per row as I believe is done in the existing Grid widget). Automatic layout is very important for us as we have hundreds of tables in our application, and each can be customized to include any number of attributes, and having the user control the size of each column is just too much flexibility and overhead for the user.

    4) Will this table support row and column spans? We have many use cases for showing multiple sub-items (rows) per item (row) for various columns.

    Thanks for any feedback.

  • @Ron: 1) Yes, if you mean keeping the headers in place while the body vertically scrolls, that is a basic functionality.
    2) Yes, full horizontal scrolling with locked columns is supported
    3) No, if you mean content-driven layout, it doesn’t currently support that. The new grid uses table-layout: fixed. Using a table without fixed layout is a big performance problem for any sizable grid, as it forces the table to be rerendered on virtually row addition, and is not viable for scaling. We could potentially add support for that, but it would be much slower. However, if you aren’t referring to content-driven layout, but simply width: auto (or percent based) type layout where the columns are adjusted for the variable width of the table, that is supported.
    4) Yes

  • Laura_

    When will the new grid be released?

  • Can’t wait! Do you dare to make a prediction in which dojo version we can expect the next grid?

  • Mark

    Hi

    I’ve been having a play with this on the iPad and first glance it is great.
    Couple of questions:

    1. The main issue seems to be around the scrolling aspect – It puts up the standard scroll bar which is add odds with the way mobile lists etc work. Essentially we were planning to use dgrid as a template but use some of the scrollable view & dojox.mobile.list stuff to get it behaving as we expect. Since you are saying this will be mobile friendly are we heading in the wrong direction????

    2. Also our code require swapping out one store for another (including different columns). To get it to work properly I ended up having to delete the innerHTML of the container div because multiple headers etc were being created when I called refresh, and then instantiating a new grid. Could you consider adding a more complete refresh that can handle a completely different store? Or am I handling it correctly?

    3. In all the examples it uses the new 1.7 commonJS means of accessing dojo module code i.e rather than just call grid = dojox.dgrid.OnDemandGrid in an onReady function a ‘Grid’ reference is passed in the the function after dojo.require array, then the call is simply grid = new Grid(…
    What I don’t understand about this new method is how to create a grid somewhere else in your code e.g. if I want to dynamically create a grid on a button click? I am currently handling it by saving the ‘Grid’ reference to a global var in that initial function but this feels terribly wrong.

    Thanks

  • Grid

    “Hopefully you are looking forward to the new grid. Next we will take a look at the actual grid and see how we can use it today.”

    Where is it? Can you provide a link?

  • The new grid is on Kris’s Github account: https://github.com/kriszyp/dgrid — warning, it’s obviously still in very active development (dozens of commits in the past few days alone).

  • @Simon: New projects are not going in dojox, there are going in the Dojo package repository. And dgrid is already there.

    @Mark: I don’t see any standard scroll bars on an iPad with the dgrid. I don’t think I have ever seen any standard scroll bars on the iPad. We’ll take a look at the refresh() issue. And you should still be able to use dojo.require(“dgrid.Grid”) with Dojo loader in sync mode (we can add some tests for that).

  • Eve

    Does this grid support pagination?

  • Katie

    So… dgrid in the package repository requires dojo 1.7.0b5, but dijit only goes to 1.7.0b3. Is dgrid incompatible with dijit at this time, or is the package repo just a touch behind and I should go hunting tarballs?

  • Pingback: Introducing the Next Grid: dgrid()

  • Pingback: dgrid: Getting down to the nitty griddy | Blog | SitePen()