Array, object and function data sources

This page shows how to use Handsontable with various data sources:

Please take note that Handsontable will change the original data source. More about this here: Understanding binding as reference.

Array data source

Most of the people use array of arrays data source with Handsontable.

A
B
C
D
E
KiaNissanToyotaHonda
200810111213
200920111413
200930151213
A
B
C
D
E

var
  data = [
    ['', 'Kia', 'Nissan', 'Toyota', 'Honda'],
    ['2008', 10, 11, 12, 13],
    ['2009', 20, 11, 14, 13],
    ['2009', 30, 15, 12, 13]
  ],
  container1 = document.getElementById('example1'),
  hot1;

hot1 = new Handsontable(container1, {
  data: data,
  startRows: 5,
  startCols: 5,
  colHeaders: true,
  minSpareRows: 1
});

Array data source (with hidden columns)

Let's say, you want the same data source, but without the Kia column.

A
B
C
D
NissanToyotaHonda
2008111213
2009111413
2009151213
A
B
C
D

var
  hiddenData = [
    ['', 'Kia', 'Nissan', 'Toyota', 'Honda'],
    ['2008', 10, 11, 12, 13],
    ['2009', 20, 11, 14, 13],
    ['2009', 30, 15, 12, 13]
  ],
  container = document.getElementById('example2'),
  hot2;

hot2 = new Handsontable(container, {
  data: hiddenData,
  startRows: 5,
  startCols: 5,
  colHeaders: true,
  columns: [
    {data: 0},
    {data: 2},
    {data: 3},
    {data: 4}
  ],
  minSpareRows: 1
});

Object data source

With version 0.7.0, comes possibility to use array of objects data source.

A
B
C
1Ted Right
2Frank Honest
3Joan Well
A
B
C

var
  objectData = [
    {id: 1, name: 'Ted Right', address: ''},
    {id: 2, name: 'Frank Honest', address: ''},
    {id: 3, name: 'Joan Well', address: ''}
  ],
  container3 = document.getElementById('example3'),
  hot3;

hot3 = new Handsontable(container3, {
  data: objectData,
  startRows: 5,
  startCols: 3,
  colHeaders: true,
  minSpareRows: 1
});

Object data source (nested, with column mapping)

Some people have nested objects. They can also be used at the data source with a little bit of column mapping.

The mapping is done using the columns option.

A
B
C
D
1TedRight
2
3JoanWell
A
B
C
D

var
  nestedObjects = [
    {id: 1, name: {first: "Ted", last: "Right"}, address: ""},
    {id: 2, address: ""}, // HOT will create missing properties on demand
    {id: 3, name: {first: "Joan", last: "Well"}, address: ""}
  ],
  container4 = document.getElementById('example4'),
  hot4;

hot4 = new Handsontable(container4, {
  data: nestedObjects,
  startRows: 5,
  startCols: 4,
  colHeaders: true,
  columns: [
    {data: 'id'},
    {data: 'name.first'},
    {data: 'name.last'},
    {data: 'address'}
  ],
  minSpareRows: 1
});

Object data source (custom data schema)

When you use object data binding, Handsontable needs to know the data structure to create when you add a new row.

If your data source contains at least one row, Handsontable will figure out the data structure based on the first row.

In case you want to start with an empty data source, you will need to provide the dataSchema option that contains the data structure for any new row added to the grid.

The below example shows custom data schema with an empty data source:

ID
First Name
Last Name
Address
ID
First Name
Last Name
Address

var
  container = document.getElementById('example5'),
  hot5;

hot5 = new Handsontable(container, {
  data: [],
  dataSchema: {id: null, name: {first: null, last: null}, address: null},
  startRows: 5,
  startCols: 4,
  colHeaders: ['ID', 'First Name', 'Last Name', 'Address'],
  columns: [
    {data: 'id'},
    {data: 'name.first'},
    {data: 'name.last'},
    {data: 'address'}
  ],
  minSpareRows: 1
});

Function data source and schema (to reach where arrays and objects can't reach)

If your dataSchema is actually a constructor of an object that doesn't directly expose its members, like a Backbone.js model, you can specify functions for the data member of each columns item.

The below example shows a small example of using such objects:

ID
Name
Address
1Ted Right
2Frank Honest
3Joan Well
ID
Name
Address

var
  container6 = document.getElementById('example6'),
  hot6;

hot6 = new Handsontable(container6, {
  data: [
    model({id: 1, name: 'Ted Right', address: ''}),
    model({id: 2, name: 'Frank Honest', address: ''}),
    model({id: 3, name: 'Joan Well', address: ''})
  ],
  dataSchema: model,
  startRows: 5,
  startCols: 3,
  colHeaders: ['ID', 'Name', 'Address'],
  columns: [
    {data: property('id')},
    {data: property('name')},
    {data: property('address')}
  ],
  minSpareRows: 1
});

function model(opts) {
  var
    _pub = {},
    _priv = {
      "id": undefined,
      "name": undefined,
      "address": undefined
    };

  for (var i in opts) {
    if (opts.hasOwnProperty(i)) {
      _priv[i] = opts[i];
    }
  }

  _pub.attr = function (attr, val) {
    if (typeof val === 'undefined') {
      window.console && console.log("\t\tGET the", attr, "value of", _pub);
      return _priv[attr];
    }
    window.console && console.log("SET the", attr, "value of", _pub);
    _priv[attr] = val;

    return _pub;
  };

  return _pub;
}

function property(attr) {
  return function (row, value) {
    return row.attr(attr, value);
  }
}