Backgrid.js
Backgrid.js is a set of components for building semantic and easily stylable data grid widgets.
It offers a simple, intuitive programming interface that makes easy things easy, but hard things possible when dealing with tabular data.
The goal of Backgrid.js is to produce a set of core Backbone UI elements that offer you all the basic displaying, sorting and editing functionalities you'd expect, and to create an elegant API that makes extending Backgrid.js with extra functionalities easy.
Advantages
- No Hungarian notations.
- Fully reactive. Relevant parts of the grid re-renders automatically upon data changes.
- Semantic and easily stylable. Just style with plain CSS like you would a normal HTML table.
- Low learning curve. Works with plain old Backbone models and collections. Easy things are easy, hards things possible.
- Highly modular and customizable. Components are just simple Backbone View classes, customization is easy if you already know Backbone.
- Secure by default. All of the built-in cell types disallow arbitrary rendering of HTML to mitigate against XSS attacks.
- Lightweight. Extra features are separated into extensions, which keeps the bloat away.
- Good documentation.
- Well tested. Comes with 100s of test cases.
Supported browsers: [1]
- Internet Explorer 8 [2]
- Internet Explorer 9+
- Chrome 4+
- Safari 4+
- Firefox 4+
- Opera 9+
Prerequisites
Backgrid.js depends on 3 libraries to function:
- jquery >= 1.7.0
- underscore.js ~ 1.5.0
- backbone.js >= 1.1.0
- Various dependencies for each of the extensions
Installation
Since 0.3.0 Backgrid has introduced support for loading via AMD and CommonJS.
AMD
If you use AMD, it is recommended that you use Bower:
$ bower install backgrid
CommonJS
If you prefer CommonJS, Component is a good Web component manager that builds both your JS and CSS resources:
$ npm install backgrid
The Old-Fashioned Way
You can also download the Backgrid core and its various extensions and reference the relevant files in the HTML.
Collection and Model
Before you can display any tabular data in a grid, you must first obtain the data.
At the most basic level, Backgrid pretends that every row is a model object and the whole table is backed by a simple Backbone collection.
Suppose we have a list of territory info objects:
var Territory = Backbone.Model.extend({});
var Territories = Backbone.Collection.extend({
model: Territory,
url: "examples/territories.json"
});
var territories = new Territories();
Grid
The main entry point of the Backgrid package is the Backgrid.Grid class. You can create a default Backgrid by first defining some columns, and then put that list of columns and the collection of data into the Grid constructor like this:
var columns = [{
name: "id", // The key of the model attribute
label: "ID", // The name to display in the header
editable: false, // By default every cell in a column is editable, but *ID* shouldn't be
// Defines a cell type, and ID is displayed as an integer without the ',' separating 1000s.
cell: Backgrid.IntegerCell.extend({
orderSeparator: ''
})
}, {
name: "name",
label: "Name",
// The cell type can be a reference of a Backgrid.Cell subclass, any Backgrid.Cell subclass instances like *id* above, or a string
cell: "string" // This is converted to "StringCell" and a corresponding class in the Backgrid package namespace is looked up
}, {
name: "pop",
label: "Population",
cell: "integer" // An integer cell is a number cell that displays humanized integers
}, {
name: "percentage",
label: "% of World Population",
cell: "number" // A cell type for floating point value, defaults to have a precision 2 decimal numbers
}, {
name: "date",
label: "Date",
cell: "date"
}, {
name: "url",
label: "URL",
cell: "uri" // Renders the value in an HTML anchor element
}];
// Initialize a new Grid instance
var grid = new Backgrid.Grid({
columns: columns,
collection: territories
});
// Render the grid and attach the root to your HTML document
$("#example-1-result").append(grid.render().el);
// Fetch some countries from the url
territories.fetch({reset: true});
The list of column definitions Backgrid.Grid expects is simply a list of JSON objects, which you can hardcode into your HTML templates or retrieve from a server when the DOM is ready. Backgrid doesn't care where the column definitions come from, as long as you supply the list to the Grid constructor.
As expected, you now have a basic editable data grid displayed. All the columns headers are labeled and sortable by default. ID cells are not editable, and all other cell types have reasonable validation built in. If the table gets too large, you get a scroll bar.
Backgrid.js comes with 11 basic cell types in the core and many others as extensions. Cell types such as Select2Cell and MomentCell give you a much richer editing interface for option lists and datetime values on desktop browsers. In addition, there's a wide range of possibilities with how the data is converted for display and persistence by using formatters or customizing cell classes.
Complete Example
If you have a large result set like the above, you'd probably want to be able to paginate and filter your results. This is easily achieved in Backgrid.js.
Backgrid.js comes with a number of filters and a paginator extension which you can load into your own code.
To use the paginator, you must first declare your collections to be a Backbone.PageableCollection, which is a simple subclass of the Backbone.js Collection with added pagination behavior.
var PageableTerritories = Backbone.PageableCollection.extend({
model: Territory,
url: "examples/pageable-territories.json",
state: {
pageSize: 15
},
mode: "client" // page entirely on the client side
});
var pageableTerritories = new PageableTerritories();
// Set up a grid to use the pageable collection
var pageableGrid = new Backgrid.Grid({
columns: [{
// enable the select-all extension
name: "",
cell: "select-row",
headerCell: "select-all"
}].concat(columns),
collection: pageableTerritories
});
// Render the grid
var $example2 = $("#example-2-result");
$example2.append(pageableGrid.render().el)
// Initialize the paginator
var paginator = new Backgrid.Extension.Paginator({
collection: pageableTerritories
});
// Render the paginator
$example2.after(paginator.render().el);
// Initialize a client-side filter to filter on the client
// mode pageable collection's cache.
var filter = new Backgrid.Extension.ClientSideFilter({
collection: pageableTerritories,
fields: ['name']
});
// Render the filter
$example2.before(filter.render().el);
// Add some space to the filter and move it to the right
$(filter.el).css({float: "right", margin: "20px"});
// Fetch some data
pageableTerritories.fetch({reset: true});