API Reference
Navigation
Resources
? API Reference
? Grid
? Grid Options
? Column Options
? Grid Events
? DataView
? Examples
? Providing data to the grid
? Plugins & Third-party packages
Learning
? Getting Started
? Handling Selection
? Data-Driven Grid Customization
? Writing Custom Cell Editors
Tests
? Unit Tests
Contact/Support
? Ask for Help
? Report a Bug
? SlickGrid on Twitter
Wiki ? API Reference
This is the API reference for SlickGrid.
Slick.Grid
l Constructor - Slick.Grid constructor
l Core - Core grid functionality
l Columns - Initializing and customizing columns
l Cells - Manipulating cell data and styling
l Rendering - Rendering methods
l Headers - Column header methods
DataView
Slick.Data.RemoteModel
Slick.Event
Slick.EventData
Slick.EditorLock
Slick.GlobalEditorLock
Slick.Range
Slick.CellRangeDecorator
Slick.CellRangeSelector
Table of Contents
l Constructor
l new Slick.Grid
l Core
l init
l getData
l setData
l getDataItem
l getSelectionModel
l setOptions
l Columns
l autosizeColumns
l getColumnIndex
l getColumns
l setSortColumn
l setSortColumns
l updateColumnHeader
l Cells
l addCellCssStyles
l canCellBeActive
l canCellBeSelected
l editActiveCell
l getActiveCell
l getCellEditor
l getCellFromEvent
l getCellFromPoint
l getCellNode
l getCellNodeBox
l gotoCell
l navigateDown
l navigateLeft
l navigateNext
l navigatePrev
l navigateRight
l navigateUp
l removeCellCssStyles
l resetActiveCell
l setActiveCell
l setCellCssStyles
l Rendering
l getCanvasNode
l getRenderedRange
l getViewport
l invalidate
l invalidateRow
l invalidateRows
l resizeCanvas
l scrollCellIntoView
l scrollRowIntoView
l scrollRowToTop
l updateCell
l updateRow
l updateRowCount
l Headers
l getHeaderRow
l getHeaderRowColumn
l getSortColumns
l setHeaderRowVisibility
# Constructor
# var grid = new Slick.Grid(container, data, columns, options);
container - Container node to create the grid in. This can be a DOM Element, a jQuery node, or a jQuery selector.
data - Databinding source. This can either be a regular JavaScript array or a custom object exposing getItem(index) and getLength() functions.
columns - An array of column definition objects. See Column Options for a list of options that can be included on each column definition object.
options - Additional options. See Grid Options for a list of options that can be included.
Create an instance of the grid.
Example usage, taken from the basic Slickgrid example:
var grid;
var columns = [
{id: "title", name: "Title", field: "title"},
{id: "duration", name: "Duration", field: "duration"},
{id: "%", name: "% Complete", field: "percentComplete"},
{id: "start", name: "Start", field: "start"},
{id: "finish", name: "Finish", field: "finish"},
{id: "effort-driven", name: "Effort Driven", field: "effortDriven"}
];
var options = {
enableCellNavigation: true,
enableColumnReorder: false
};
$(function () {
var data = [];
for (var i = 0; i < 500; i++) {
data[i] = {
title: "Task " + i,
duration: "5 days",
percentComplete: Math.round(Math.random() * 100),
start: "01/01/2009",
finish: "01/05/2009",
effortDriven: (i % 5 == 0)
};
}
grid = new Slick.Grid("#myGrid", data, columns, options);
# Core
# grid.init()
Initializes the grid. Called after plugins are registered. Normally, this is called by the constructor, so you don't need to call it. However, in certain cases you may need to delay the initialization until some other process has finished. In that case, set the explicitInitialization option to trueand call the grid.init() manually.
# grid.getData()
Returns an array of every data object, unless you're using DataView in which case it returns a DataView object.
# grid.getDataItem(index)
index - Item index.
Returns the databinding item at a given position.
// Get the id of the 15th item
var id15 = grid.getDataItem(14).id;
# grid.setData(newData, scrollToTop)
data - New databinding source. This can either be a regular JavaScript array or a custom object exposing getItem(index) and getLength() functions.
scrollToTop - If true, the grid will reset the vertical scroll position to the top of the grid.
Sets a new source for databinding and removes all rendered rows. Note that this doesn't render the new rows - you can follow it with a call to render() to do that.
# grid.getDataLength()
Returns the size of the databinding source.
// Create an array of just the ids from every data item
var ids = [];
for (var i=0; iHere is a subheader!
")
.appendTo(grid.getTopPanel());
// Show the top panel
grid.setTopPanelVisibility(true);
# grid.setHeaderRowVisibility(visible)
DataView
Core concepts
SlickGrid is very flexible in how it consumes the data. The data is passed to the grid via the constructor and can also be accessed using the setData(data) and getData() methods. Data itself can be either an array-like object with a length property and an indexer (data[index]) or a custom data provider implementing the following interface:
l getLength() - returns the number of data items in the set
l getItem(index) - returns the item at a given index
l getItemMetadata(index) - returns the metadata for the item at a given index (optional)
DataView (Slick.Data.DataView included in slick.dataview.js) is one such data provider and it is part of the SlickGrid package.
If all of the data is available on the client (i.e. in a JavaScript array), DataView can provide many useful features that the grid itself doesn't have. (This fact that the grid lacks these features is by design - SlickGrid tries to keep the core lean and simple while encouraging modular design and data abstraction in its API.)
DataView works by taking in your data and acting as a data provider that you pass to SlickGrid instead of your original data array. For example, if you make DataView group data, it makes the grid think that the "group" rows are just regular data items, so the grid doesn't need to be aware of them. DataView tells the grid that those items have a custom display and behavior and provides implementations of both. You then wire up DataView's onRowCountChanged and onRowsChangedevents to update the grid and voila.
Here's a rough list of features that DataView adds to the grid:
l Paging.
l Multi-column sorting.
l Search.
l Multi-level grouping with totals.
l Expand/collapse groups.
DataView also enables very efficient updates in response to the changing data. Whenever something changes, it detects which rows need updating, and passes them in theonRowCountChanged and onRowsChanged events that it fires, so instead of rerendering the entire grid, you can simply invalidate the updated rows.
Getting started
To use the DataView, include slick.dataview.js:
// Create the DataView.
var dataView = new Slick.Data.DataView();
// Pass it as a data provider to SlickGrid.
var grid = new Slick.Grid(containerEl, dataView, columns, options);
// Make the grid respond to DataView change events.
dataView.onRowCountChanged.subscribe(function (e, args) {
grid.updateRowCount();
grid.render();
});
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render();
});
Now we're ready to initialize it with some data. One important requirement that DataView imposes on the data it consumes is that every item has a unique identifier. DataView uses it to uniquely identify items and compare them to each other. By default, DataView uses the id property of the data item, but you can specify a different one by passing it in via an optional second argument in the setItems(data, [objectIdProperty]). The id value must be serializable to a string.
var data = [
{'id': 'l1', 'lang': 'Java'},
{'id': 'l2', 'lang': 'JavaScript'},
{'id': 'l3', 'lang': 'C#'},
{'id': 'l4', 'lang': 'Python'}];
// This will fire the change events and update the grid.
dataView.setItems(data);
You can call getItems() to get the data array back.
Mapping rows vs items
Ok, let's reiterate - DataView takes in a data array as an input, manipulates it, and presents the results to the grid by acting as a data provider, i.e. exposing the data provider methodsgetItem(index), getLength() and getItemMetadata(index). In handling grid events, it's important to always keep in mind that the row indexes the grid refers to are, in fact, the indexes into the output of the DataView! For example, if you're handling a grid onClick event and it's giving you a row index, to look up the data item, you need to call dataView.getItem(rowIndex) and notdata[rowIndex].
In general, whenever we talk about rows, we mean the data as the grid sees it, so, if you're using a DataView, that would the output of the DataView (dataView.getItem(index)). Whenever we talk about items, we mean the input of the DataView (data[index] or dataView.getItems()[index]). You'll notice that it is somewhat confusing that getItem(index) returns a row while getItems()returns items. Unfortunately, it's this way for historical reasons. getItem(index) is part of the data provider interface. In retrospect, it would be better if the DataView exposed a getDataProvider()method.
Since each item has a unique id, they are often used to keep track of items/rows and to map one to another. DataView exposes several methods in order to map rows to items:
l getItems() - Returns the original data array.
l getIdxById(id) - Returns the index of an item with a given id.
l getRowById(id) - Returns the index of a row with a given id.
l getItemById(id) - Returns the item with a given id.
l getItemByIdx(index) - Returns the item at a given index. Equivalent to getItems()[index].
l mapIdsToRows(idArray) - Maps an array of ids into row indexes.
l mapRowsToIds(rowArray) - Maps an array of row indexes into ids.
These methods are exposed by the DataView as part of the data provider interface:
l getItem(index) - Returns the item at a given index.
l getItemMetadata(index) - Returns the item metadata at a given index.
l getLength() - Returns the number of items.
Synchronizing selection & cell CSS styles
One of the most common questions about DataView is how to synchronize the selection or cell CSS styles state on DataView changes. Let's say that the user selected a row. If they then change the filter on the DataView to hide some items, the grid gets a call to invalidate all changed rows, including the selected one, but it doesn't know that the item that was displayed there has moved somewhere else. What we need to do, is to store the ids of items that were selected, and to update the selection on the grid any time the DataView is modified.
Luckily, there is a helper method on the DataView that can take care of that:
l syncGridSelection(grid, preserveHidden) - Synchronizes grid's selected rows with the DataView by subscribing to the grid's onSelectedRowsChanged event as well as the DataView's onRowsChanged & onRowCountChanged events. If preserveHidden is true, it will preserve selected items even if they are not visible as rows. For example, if you select an item, change the DataView filter so that that item is no longer presented to the grid and then change it back, the item will remain selected. If preserveHidden is false, all selected items that can't be mapped onto rows are dropped.
The implementation is really simple, and I'll include it here for the reference:
function syncGridSelection(grid, preserveHidden) {
var self = this;
var selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());;
var inHandler;
function update() {
if (selectedRowIds.length > 0) {
inHandler = true;
var selectedRows = self.mapIdsToRows(selectedRowIds);
if (!preserveHidden) {
selectedRowIds = self.mapRowsToIds(selectedRows);
}
grid.setSelectedRows(selectedRows);
inHandler = false;
}
}
grid.onSelectedRowsChanged.subscribe(function(e, args) {
if (inHandler) { return; }
selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());
});
this.onRowsChanged.subscribe(update);
this.onRowCountChanged.subscribe(update);
}
NOTE: This only works with the RowSelectionModel. CellSelectionModel isn't supported yet (I'm open to pull requests!).
There is a similar helper method to synchronize the cell CSS styles:
function syncGridCellCssStyles(grid, key) {
var hashById;
var inHandler;
// since this method can be called after the cell styles have been set,
// get the existing ones right away
storeCellCssStyles(grid.getCellCssStyles(key));
function storeCellCssStyles(hash) {
hashById = {};
for (var row in hash) {
var id = rows[row][idProperty];
hashById[id] = hash[row];
}
}
function update() {
if (hashById) {
inHandler = true;
ensureRowsByIdCache();
var newHash = {};
for (var id in hashById) {
var row = rowsById[id];
if (row != undefined) {
newHash[row] = hashById[id];
}
}
grid.setCellCssStyles(key, newHash);
inHandler = false;
}
}
grid.onCellCssStylesChanged.subscribe(function(e, args) {
if (inHandler) { return; }
if (key != args.key) { return; }
if (args.hash) {
storeCellCssStyles(args.hash);
}
});
this.onRowsChanged.subscribe(update);
this.onRowCountChanged.subscribe(update);
}
Sorting
Sorting is pretty simple:
// Subscribe to the grid's onSort event.
// It only gets fired for sortable columns, so make sure your column definition has `sortable = true`.
grid.onSort.subscribe(function(e, args) {
// args.multiColumnSort indicates whether or not this is a multi-column sort.
// If it is, args.sortCols will have an array of {sortCol:..., sortAsc:...} objects.
// If not, the sort column and direction will be in args.sortCol & args.sortAsc.
// We'll use a simple comparer function here.
var comparer = function(a, b) {
return (a[args.sortCol.field] > b[args.sortCol.field]) ? 1 : -1;
}
// Delegate the sorting to DataView.
// This will fire the change events and update the grid.
dataView.sort(comparer, args.sortAsc);
});
Note that calling sort() on the DataView modifies the original data array that was passed in tosetItems(data)!
There's also a fastSort(field, isAscending) method on the DataView to do a fast lexicographic search that is especially handy for older versions of IE.
Updating data
Since DataView can't automatically detect when you're changing the data, you'll need to make these updates via the DataView. These updates will be applied directly to the original data array.
// Delete item with id 'l3' ('C#').
dataView.deleteItem('l3');
// Append item to the end.
dataView.addItem({'id': 'l5', 'lang': 'CoffeeScript'});
// Insert item at the beginning.
dataView.insertItem(0, {'id': 'l6', 'lang': 'TypeScript'});
// Update an existing item.
var item = dataView.getItemById('l4');
item['lang'] = 'Clojure';
dataView.updateItem('l4', item);
Each one of these updates will fire change events and the grid will get updated automatically.
Batching updates
Notice that in the example above, each update will result in the DataView recalculating its data and firing change events, resulting in the grid rerendering affected rows. If you need to make multiple changes, you should batch them up to avoid unnecessary operations:
// Suspend recalculations until endUpdate() is called.
dataView.beginUpdate();
dataView.addItem(...);
dataView.addItem(...);
dataView.sort(...);
// Indicate that we're done updating.
dataView.endUpdate();
Filtering
Paging
Grouping
Advanced topics
API reference
Grid Options
As included in the examples or described in stable releases.
Option
Default
Description
asyncEditorLoading
false
Makes cell editors load asynchronously after a small delay. This greatly increases keyboard navigation speed.
asyncEditorLoadDelay
100
Delay after which cell editor is loaded. Ignored unless asyncEditorLoading is true.
asyncPostRenderDelay
50
autoEdit
true
Cell will not automatically go into edit mode when selected.
autoHeight
false
This disables vertical scrolling.
cellFlashingCssClass
“flashing”
A CSS class to apply to flashing cells via flashCell().
cellHighlightCssClass
“selected”
A CSS class to apply to cells highlighted via setHighlightedCells().
dataItemColumnValueExtractor
null
defaultColumnWidth
80
defaultFormatter
defaultFormatter
editable
false
editCommandHandler
queueAndExecuteCommand
Not listed as a default under options in slick.grid.js
editorFactory
null
A factory object responsible to creating an editor for a given cell. Must implement getEditor(column).
editorLock
Slick.GlobalEditorLock
A Slick.EditorLock instance to use for controlling concurrent data edits.
enableAddRow
false
If true, a blank row will be displayed at the bottom - typing values in that row will add a new one. Must subscribe to onAddNewRow to save values.
enableAsyncPostRender
false
If true, async post rendering will occur and asyncPostRender delegates on columns will be called.
enableCellRangeSelection
null
**WARNING**: Not contained in SlickGrid 2.1, may be deprecated
enableCellNavigation
true
Appears to enable cell virtualisation for optimised speed with large datasets
enableColumnReorder
true
enableRowReordering
null
**WARNING**: Not contained in SlickGrid 2.1, may be deprecated
enableTextSelectionOnCells
false
explicitInitialization
false
See:Example: Explicit Initialization
forceFitColumns
false
Force column sizes to fit into the container (preventing horizontal scrolling). Effectively sets column width to be 1/Number of Columns which on small containers may not be desirable
forceSyncScrolling
false
formatterFactory
null
A factory object responsible to creating a formatter for a given cell. Must implement getFormatter(column).
fullWidthRows
false
Will expand the table row divs to the full width of the container, table cell divs will remain aligned to the left
headerRowHeight
25
leaveSpaceForNewRows
false
multiColumnSort
false
See:Example: Multi-Column Sort
multiSelect
true
rowHeight
25
selectedCellCssClass
“selected”
showHeaderRow
false
syncColumnCellResize
false
If true, the column being resized will change its width as the mouse is dragging the resize handle. If false, the column will resize after mouse drag ends.
topPanelHeight
25
Column Options
Options which you can apply to the columns objects.
Option
Default
Description
asyncPostRender
null
This accepts a function of the formfunction(cellNode, row, dataContext, colDef)and is used to post-process the cell’s DOM node / nodes
behavior
null
Used by the the slick.rowMoveManager.js plugin for moving rows. Has no effect without the plugin installed.
cannotTriggerInsert
null
In the “Add New” row, determines whether clicking cells in this column can trigger row addition. If true, clicking on the cell in this column in the “Add New” row will not trigger row addition.
cssClass
””
Accepts a string as a class name, applies that class to every row cell in the column.
defaultSortAsc
true
When set totrue, the first user click on the header will do a descending sort. When set tofalse, the first user click on the header will do an ascending sort.
editor
null
The editor for cell edits {TextEditor, IntegerEditor, DateEditor…} Seeslick.editors.js
field
””
The property name in the data object to pull content from. (This is assumed to be on the root of the data object.)
focusable
true
When set tofalse, clicking on a cell in this column will not select the row for that cell. The cells in this column will also be skipped during tab navigation.
formatter
null
This accepts a function of the formfunction(row, cell, value, columnDef, dataContext)and returns a formatted version of the data in each cell of this column. For example, settingformattertofunction(r, c, v, cd, dc) { return “Hello!”; }would overwrite every value in the column with “Hello!” SeedefaultFormatterinslick.grid.jsfor an example formatter.
headerCssClass
null
Accepts a string as a class name, applies that class to the cell for the column header.
id
””
A unique identifier for the column within the grid.
maxWidth
null
Set the maximum allowable width of this column, in pixels.
minWidth
30
Set the minimum allowable width of this column, in pixels.
name
””
The text to display on the column heading.
rerenderOnResize
false
If set to true, whenever this column is resized, the entire table view will rerender.
resizable
true
Iffalse, column can no longer be resized.
selectable
true
Iffalse, when a row is selected, the CSS class for selected cells (“selected” by default) is not applied to the cell in this column.
sortable
false
Iftrue, the column will be sortable by clicking on the header.
toolTip
””
If set to a non-empty string, a tooltip will appear on hover containing the string.
width
Width of the column in pixels. (May often be overridden by things like minWidth, maxWidth, forceFitColumns, etc.)
Last edited by dholcombe, 8 months ago
Grid Events
SlickGrid exposes the following events:
l onScroll
l onSort
l onHeaderContextMenu
l onHeaderClick
l onMouseEnter
l onMouseLeave
l onClick
l onDblClick
l onContextMenu
l onKeyDown
l onAddNewRow
l onValidationError
l onViewportChanged
l onColumnsReordered
l onColumnsResized
l onCellChange
l onBeforeEditCell
l onBeforeCellEditorDestroy
l onHeaderCellRendered
l onBeforeHeaderCellDestroy
l onBeforeDestroy
l onActiveCellChanged
l onActiveCellPositionChanged
l onDragInit
l onDragStart
l onDrag
l onDragEnd
l onSelectedRowsChanged
l onCellCssStylesChanged
You can subscribe to the above events using a syntax similar to:
gridInstance.onXYZEvent.subscribe(function(e,args){
//event handling code.
});
Event handlers can also be removed with
gridInstance.onXYZEvent.unsubscribe(fn);
Last edited by matma, 10 months ago
Providing data to the grid
Overview
The data is passed to the grid via the constructor and can also be accessed using thesetData(data) and getData() methods. Data itself can be either an array-like object with alength property and an indexer (data[index]) or a custom data provider implementing the following interface:
l getLength() - returns the number of data items in the set
l getItem(index) - returns the item at a given index
l getItemMetadata(index) - returns the metadata for the item at a given index (optional)
Item Metadata
getItemMetadata provides a powerful way of specifying additional information about a data item that let the grid customize the appearance and handling of a particular data item. The method should return null if the item requires no special handling, or an object in the following general format:
{
// properties describing metadata related to the item (i.e. grid row) itself
"
": value,
"": value,
// properties describing metadata related to individual columns
"columns": {
"": {
// metadata indexed by column index
"": value,
"": value
},
"": {
// metadata indexed by column id
"": value,
"": value
}
}
}
Row-level properties
l cssClasses (string) - One or more (space-separated) CSS classes to be added to the entire row.
l focusable (boolean) - Whether or not any cells in the row can be set as "active".
l selectable (boolean) - Whether or not a row or any cells in it can be selected.
Column-level properties
l focusable (boolean) - Whether or not a cell can be set as "active".
l selectable (boolean) - Whether or not a cell can be selected.
l formatter (Function) - A custom cell formatter.
l editor (Function) - A custom cell editor.
l colspan (number|string) - Number of columns this cell will span. Can also contain "*" to indicate that the cell should span the rest of the row.
Order of checks
When looking up a property, the grid checks in the following order:
1. Row-level item metadata.
2. Column-level item metadata by column id.
3. Column-level item metadata by column index.
4. Column definition.
5. Grid options.
6. Grid defaults.
Examples
See colspan example.
Plugins & Third party packages
(List your plugins / extensions / third-party packages here.)
External Copy manager (copy/paste from Excel)
AutoFilter and Fill Down Plugins
Filter
Adds a filter option to a column header allowing multiple values to be selected/un-selected as well as a Sort Ascending/Sort Descending option.
Fill Down
Provides additional spreadsheet style decorators for the cell, row header, and column header and enables Fill Down functionality on editable columns
Example of both plugins with Excel styling
Example of both plugins with Google Docs styling
Repository
Getting Started
Although the source of the first example is self-explanatory, it's worth pointing out the basics of SlickGrid. The following line:
var slickgrid = new Slick.Grid(container, rows, columns, options);
initializes and renders SlickGrid, and assigns its interface to the slickgrid var. Now we can useslickgrid.someMethod() in order to interact with it.
Container
container (an Element or a jQuery selector) points to the HTML element where the grid will be created, typically being an empty . The
should have explicit dimensions (height and width) specified via CSS or the style attribute. The grid will be sized to occupy all available space.
Rows
rows is an array of data objects. Example:
var rows = [
{
field_1: "value1",
field_2: "value2"
}, {
field_1: "value3",
field_2: "value4"
}
];
Providing data to the grid is explained in more detail here.
As it is passed by reference to the grid, you can modify it directly, but since the grid doesn't know when the data has changed, you need to let it know that it needs to rerender:
slickgrid.invalidate();
This forces all the rows to be destroyed and recreated, but since the grid only renders the rows in the viewport (plus a small buffer), the performance of this method is constant and does not depend on the number of rows in the dataset. If you want to be more efficient, however, you can let the grid know exactly which rows need to be rerendered and whether the number of rows has changed:
slickgrid.invalidateRows([4, 7]);
slickgrid.updateRowCount();
slickgrid.render();
Doing that will make the grid rerender rows 4 and 7 (0-based) as well as update the number of rows (new rows will be rendered and rows no longer in the dataset will be removed).
This is one of key strengths of SlickGrid which allows for extremely efficient UI updates.
Columns
columns is an array of objects, having at least the following fields:
l name - The name to be displayed in the view.
l field - The field name used in the data row objects.
l id - An unique identifier for each column in the model, allowing to set more than one column reading the same field.
Other fields include:
resizable
sortable
selectable
focusable
width
minWidth
maxWidth
rerenderOnResize
headerCssClass
formatter
editor
etc.
Example:
var columns = [
{
name: "Address",
field: "address",
id: "address", // In most cases field and id will have the same value.
sortable: true
},
{
name: "Rating, in %",
field: "rating", // This and the following column read the same data, but can present it in a different way.
id: "rating_percent",
resizable: false
},
{
name: "Rating, in stars",
field: "rating",
id: "rating_stars"
}
];
Options
options allows you to specify additional options.
Events
SlickGrid has its own simple implementation of events. To subscribe to an event, callevent.subscribe() and pass in a function that will take two parameters - an event object that contains the browser event, if any, and an additional args object that contains data passed from the grid.
An example:
slickgrid.onDblClick.subscribe(function(e, args){
var args.item; // object containing name, field, id, etc
});
See the events for the full list.
Basic sorting
It can be achieved by listening the onSort method:
slickgrid.onSort.subscribe(function(e, args){ // args: sort information.
var field = args.sortCol.field;
rows.sort(function(a, b){
var result =
a[field] > b[field] ? 1 :
a[field] < b[field] ? -1 :
0;
return args.sortAsc ? result : -result;
});
slickgrid.invalidate();
});
Last edited by yeonhoyoon, 2 months ago
Handling selection
Selecting cells in SlickGrid is handled by a selection model.
Selection models are controllers responsible for handling user interactions and notifying subscribers of the changes in the selection. Selection is represented as an array of Slick.Range objects.
You can get the current selection model from the grid by calling getSelectionModel() and set a different one using setSelectionModel(selectionModel). By default, no selection model is set.
The grid also provides two helper methods to simplify development - getSelectedRows() andsetSelectedRows(rowsArray), as well as an onSelectedRowsChanged event.
SlickGrid includes two pre-made selection models - Slick.CellSelectionModel andSlick.RowSelectionModel, but you can easily write a custom one.
A selection model must expose:
init function init(grid)
An initializer function that will be called with an instance of the grid whenever a selection model is registered with setSelectionModel. The selection model can use this to initialize its state and subscribe to grid events.
destroy function destroy()
A destructor function that will be called whenever a selection model is unregistered from the grid by a call to setSelectionModel with another selection model or whenever a grid with this selection model is destroyed. The selection model can use this destructor to unsubscribe from grid events and release all resources (remove DOM nodes, event listeners, etc.).
onSelectedRangesChanged Slick.Event
An event that is fired whenever the selected ranges are changed. When a selection model is registered with the grid, the grid will subscribe to this event and use it to update the internal state and decorate selected cells with selectedCellCssClass. The event must be fired with the following data in event args:
l ranges - An array of Slick.Range objects representing the selection.
Below is a simplistic example of a single cell selection model that only reacts to mouse clicks:
function SingleCellSelectionModel() {
var self = this;
this.init = function(grid) {
self._grid = grid;
self._grid.onClick.subscribe(self.handleGridClick);
};
this.destroy = function() {
self._grid.onClick.unsubscribe(self.handleGridClick);
};
this.handleGridClick = function(e, args) {
var cell = self._grid.getCellFromEvent(e);
if (!cell || !self._grid.canCellBeSelected(cell.row, cell.cell)) {
return;
}
self.onSelectedRangesChanged.notify([new Slick.Range(cell.row, cell.cell, cell.row, cell.cell)]);
};
}
Last edited by bighuggies, a year ago
Writing custom cell editors
Basic interface
function IEditor(args) {
// initialize the UI
/*********** REQUIRED METHODS ***********/
this.destroy = function() {
// remove all data, events & dom elements created in the constructor
};
this.focus = function() {
// set the focus on the main input control (if any)
};
this.isValueChanged = function() {
// return true if the value(s) being edited by the user has/have been changed
return false;
};
this.serializeValue = function() {
// return the value(s) being edited by the user in a serialized form
// can be an arbitrary object
// the only restriction is that it must be a simple object that can be passed around even
// when the editor itself has been destroyed
return "";
};
this.loadValue = function(item) {
// load the value(s) from the data item and update the UI
// this method will be called immediately after the editor is initialized
// it may also be called by the grid if if the row/cell being edited is updated via grid.updateRow/updateCell
};
this.applyValue = function(item,state) {
// deserialize the value(s) saved to "state" and apply them to the data item
// this method may get called after the editor itself has been destroyed
// treat it as an equivalent of a Java/C# "static" method - no instance variables should be accessed
};
this.validate = function() {
// validate user input and return the result along with the validation message, if any
// if the input is valid, return {valid:true,msg:null}
return { valid: false, msg: "This field is required" };
};
/*********** optional METHODS***********/
this.hide = function() {
// if implemented, this will be called if the cell being edited is scrolled out of the view
// implement this is your UI is not appended to the cell itself or if you open any secondary
// selector controls (like a calendar for a datepicker input)
};
this.show = function() {
// pretty much the opposite of hide
};
this.position = function(cellBox) {
// if implemented, this will be called by the grid if any of the cell containers are scrolled
// and the absolute position of the edited cell is changed
// if your UI is constructed as a child of document BODY, implement this to update the
// position of the elements as the position of the cell changes
//
// the cellBox: { top, left, bottom, right, width, height, visible }
};
}
Constructor arguments
The editor constructor receives an args object which has the following fields:
l column — column definition object
l container — DOM-object for cell container
l grid — grid instance
l gridPosition — object describing grid position
l item — data item for edited row
l position — object describing cell position
l cancelChanges() — grid method to discard changes
l commitChanges() — grid method to store changes
Compound editors
In most cases, there will be a one-to-one relationship between the fields of your data objects and cells in the grid.
Occasionally, though, you may want to combine several fields into one cell in order to improve the usability of your application. A custom formatter can easily pull information from multiple fields of your data object and present it in one cell. SlickGrid handles edition those cells by using theloadValue(), serializeValue() and applyValue() methods of your editor. While it may seem more complicated than a simple getValue() and setValue(), without them, compound editors would not have been possible.
A sample compound editor is implemented in example 3a (source, demo).
Intercepting cell edits
You can easily use the onCellChange event to run some code after the cell has been edited. You can also intercept all cell edits and have complete control over how and when those edits are committed by specifying a custom handler by setting the editCommandHandler grid option. Due to the disconnected nature of applyValue() and serializeValue(), you can even undo your changes after you commit them. This can be especially handy if you are editing a remote data source – you can apply the changes and make an AJAX call passing the undo callback as the error handler, so that your data doesn’t get out of sync if the server cannot save the values. You can also queue up the edit commands and implement undo/redo functionality in just a few lines of code.