SlickGrid
What it is
Quite simply, SlickGrid is a JavaScript grid/spreadsheet component.
Some highlights:
- Virtual scrolling/rendering (hundreds of thousands of rows)
- Extremely fast rendering speed
- Configurable & customizable
- Full keyboard navigation
- Resizable/reorderable columns
- Custom cell formatters & editors
- Support for editing and creating new rows.
- "GlobalEditorLock" to manage concurrent edits in cases where multiple Views on a page can edit the same data.
Why?
This is pretty much a work-in-progress prototype, so I don't feel like spending a lot of time documenting it at this stage. I do think it is quite promising though, so I'm putting it up for everybody to see and play with. In its current form, it satisfies nearly all of the requirements for the project I am working on where I am utilizing it in an MVC application, so I'm not sure how much time I can afford on turning SlickGrid into something that would work for everybody. If you are willing to help out - let me know, and I'll add you to the project so that you can contribute.
Discussion
I started a small discussion with a call for contributors on the jQuery Google Group - http://groups.google.com/group/jquery-en/browse_thread/thread/e533efae60ec8166
Examples
Basic use: http://slickgrid.googlecode.com/svn/trunk/examples/example1-simple.html
Adding some formatting: http://slickgrid.googlecode.com/svn/trunk/examples/example2-formatters.html
Turning it into a spreadsheet: http://slickgrid.googlecode.com/svn/trunk/examples/example3-editing.html
Using a simple Model (filtered data view) to drive the grid: http://slickgrid.googlecode.com/svn/trunk/examples/example4-model.html
Adding tree functionality (expand/collapse) to the grid: http://slickgrid.googlecode.com/svn/trunk/examples/example5-collapsing.html
AJAX-loading data (shows all Apple-related Digg stories): http://slickgrid.googlecode.com/svn/trunk/examples/example6-ajax-loading.html
A more comprehensive test page: http://slickgrid.googlecode.com/svn/trunk/examples/grid.html
What makes it different
Virtual rendering
SlickGrid utilizes virtual rendering to enable you to easily work with hundreds of thousands of items without any drop in performance. In fact, there is no difference in performance between working with a grid with 10 rows versus a 100'000 rows. This is achieved through virtual rendering where only what's visible on the screen plus a small buffer is rendered. As the user scrolls, DOM nodes are continuously being created and removed. These operations are highly tuned to provide optimal performance under all browsers (on my laptop, FireFox 3.0.7 takes less than 1ms to render one row). The grid also adapts to the direction and speed of scroll to minimize the number of rows that need to be swapped out and to dynamically switch between synchronous and asynchronous rendering.
It does a few other things to maximize performance, such as dynamically generating and updating CSS rules, so that resizing a column does not change the grid DOM tree and only causes one reflow, and loading cell editors asynchronously to maximize keyboard navigation speed.
Grid vs Data
The key difference is between SlickGrid and other grid implementation I have seen (jqGrid, DataTables, TableSorter, etc) is that they focus too much on being able to understand and work with data (search, sort, parse, ajax load, etc.) and not enough on being a better "grid" (or, in case of editable grids, a spreadsheet). It's great if all you want to do is "spruce up" an HTML TABLE or slap a front end onto a simple list, but too inflexible for anything else.
Data is complicated. It has business rules. It has non-intrinsic properties. Editing one property of an element can lead to cascading changes modifying other properties or even other elements. It has dependencies. What I'm saying, is that dealing with data is best left to the developer using the grid control. Trying to fit all of that into the grid implementation and API will only limit its applicability and add considerable bloat.
SlickGrid takes a different approach. In the simplest scenario, it accesses data through an array interface (i.e. using "dataitem" to get to an item at a given position and "data.length" to determine the number of items), but the API is structured in such a way that it is very easy to make the grid react to any possible changes to the underlying data.
Filtered DataView (Model)
... coming soon ...
Editor control
... coming soon ...
API
function SlickGrid($container,data,columns,options) { ... }
Column definition options:
| Column definition option | Description | Default |
| id | Column ID. | - |
| name | Column name to put in the header. | - |
| field | Property of the data context to bind to. | - |
| formatter | Function responsible for rendering the contents of a cell. | defaultFormatter |
| editor | An Editor class responsible for editing the value of a cell. | - |
| validator | An extra validation function to be passed to the editor. | - |
| unselectable | If true, the cell cannot be selected (and therefore edited). | false |
| cannotTriggerInsert | If true, a new row cannot be created from just the value of this cell. | false |
| setValueHandler | A custom function to be called to set field value instead of setting contextfield | - |
| width | Width of the column in pixels. | Options.defaultColumnWidth |
| resizable | If false, the column cannot be resized. | true |
| minWidth | Minimum allowed column width for resizing. | - |
| maxWidth | Maximum allowed column width for resizing. | - |
| cssClass | A CSS class to add to the cell. | - |
| rerenderOnResize | Rerender the column when it is resized (useful for columns relying on cell width or adaptive formatters). | false |
Options:
| Options | Description | Default |
| rowHeight | Row height in pixels. | 24 |
| enableAddRow | If true, a blank row will be displayed at the bottom - typing values in that row will add a new one. | true |
| manualScrolling | Disable automatic rerender on scroll. Client will take care of calling SlickGrid.scroll(). | false |
| editable | If false, no cells will be switched into edit mode. | true |
| editOnDoubleClick | Cells will be switched into edit mode on double-click instead of a single click. Single click will select a cell. | false |
| enableCellNavigation | If false, no cells will be selectable. This also disables editing. | true |
| defaultColumnWidth | Default column width in pixels. | 80 |
| enableColumnReorder | Allows the user to reorder columns. | true |
| asyncEditorLoading | Makes cell editors load asynchronously after a small delay. This greatly increases keyboard navigation speed. | true |
Methods:
| Method | Description |
| setOptions | Changes grid options and rerenders. |
| setData | Bind the grid to a new datasource. |
| destroy | Destroys the grid and cleans up. |
| getViewport | Gets the visible portion of the grid. |
| render | Makes sure all visible rows are rendered. |
| resizeViewport | Resizes the virtual canvas to match the size of the datasource. |
| scroll | If manualScrolling option is enabled, makes the grid respond to the new scroll position. |
| updateRow | Updates a given row. |
| updateCell | Updates a given cell. |
| removeRow | Removes a given row. |
| removeAllRows | Removes all rows. |
| gotoCell | Makes a given sell active. |
| editCurrentCell | Switches the active cell into edit mode. |
| getSelectedRows | Returns the indexes of selected rows. |
| setSelectedRows | Selects given rows. |
| setColumnHeaderCssClass | Updates a CSS class on a given column header (mostly used to indicated a sort column). |
| getColumnIndex | Gets an ordinal index of a column (since it may have been changed by the user). |
| commitCurrentEdit | Commits the current edit and switches the cell into normal mode. |
| cancelCurrentEdit | Cancels the current edit and switches the cell into normal mode. | |
Events:
| Event | Description |
| onColumnHeaderClick | |
| onClick | |
| onContextMenu | |
| onKeyDown | |
| onAddNewRow | |
| onValidationError | |
| onViewportChanged | |
| onSelectedRowsChanged | |
| onColumnsReordered |
Documentation
See comments at the top of http://slickgrid.googlecode.com/svn/trunk/slick.grid.js.