This page covers a next version of Handsontable, and is not published yet.

This page covers a non-latest version of Handsontable.

# Configuration options

Customize Handsontable with configuration options.

# About configuration options

Configuration options let you customize your Handsontable instance.

To apply configuration options, pass them as a second argument of the Handsontable constructor, using the object literal notation:

const container = document.getElementById('example');

const hot = new Handsontable(container, {
  // configuration options, in the object literal notation
  licenseKey: "non-commercial-and-evaluation",
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  width: 400,
  height: 300,
  colHeaders: true,
  rowHeaders: true,
  customBorders: true,
  dropdownMenu: true,
  multiColumnSorting: true,
  filters: true,
  manualRowMove: true,
});

Depending on your needs, you can apply configuration options to different elements of your grid, such as:

For the full list of available configuration options, see the configuration options' API reference.

# Cascading configuration

Handsontable's configuration cascades down:

When you modify the mid-level column options (using the columns option):

  • The options that you change overwrite the top-level grid options.
  • The options that you change cascade down to the bottom-level cell options.
  • Any unchanged options are inherited from the top-level grid options.

When you modify the bottom-level cell options (using the cell option):

  • The options that you change overwrite the top-level grid options.
  • The options that you change overwrite the mid-level column options.
  • Any unchanged options are inherited from the mid-level column options or the top-level grid options.

When you modify any options with the cells function, the changes overwrite all other options.

TIP

The cells option is a function invoked before Handsontable's rendering cycle. Implemented incorrectly, it can slow Handsontable down. Use the cells option only if the cell option, the columns option, and the setCellMeta() method don't meet your needs.

For more details on Handsontable's cascading configuration, see the MetaManager class (opens new window).

# Plugin options

Configuration options can come from:

If you use Handsontable through modules: to use an option that comes from a Handsontable plugin, you need to import and register that plugin when initializing your Handsontable instance.

To find out if an option comes from a plugin, check the Category label in the configuration options' API reference.

# Setting grid options

To apply configuration options to the entire grid:

  • Pass your options as a second argument of the Handsontable constructor, using the object literal notation.

For example, to set the entire grid's width and height:

const hot = new Handsontable(container, {
  // top-level grid options that apply to the entire grid
  width: 400,
  height: 300
});

TIP

If you use Handsontable through modules: to use an option that comes from a Handsontable plugin, import and register that plugin when initializing your Handsontable instance.

# Example

To configure each cell in the grid as read-only, apply the readOnly option as a top-level grid option.

The top-level grid options cascade down:

  • To the mid-level column options
  • To the bottom-level cell options

As a result, each cell in the grid is read-only:

const container = document.querySelector('#example1');

const hot = new Handsontable(container, {
  // configuration options, in the object literal notation
  licenseKey: 'non-commercial-and-evaluation',
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  // the `readOnly` option, applies to each cell of the entire grid
  readOnly: true,
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true
});

// check a cell's options
// returns `true`
hot.getCellMeta(0, 0).readOnly;

# Setting column options

To apply configuration options to an individual column (or a range of columns), use the columns option.

  1. Within Handsontable constructor's second argument, add an option called columns.
    const hot = new Handsontable(container, {
      // top-level grid options that apply to the entire grid
      width: 400,
      height: 300,
      // the `columns` option
      columns: []
    });
    
  2. Set the columns option to an array of objects.
    Each object represents one column.
    The objects' order represents the columns' order (i.e. the columns' physical indexes).
    const hot = new Handsontable(container, {
      columns: [
        {}, // column options for the first (by physical index) column
        {}, // column options for the second (by physical index) column
        {}, // column options for the third (by physical index) column
      ],
    });
    
  3. In the object that represents your required column, add your column options.
    For example, to make each cell of the third column read-only:
    const hot = new Handsontable(container, {
      columns: [
        {},
        {},
        // column options, apply to each cell of the third (by physical index) column
        {
          readOnly: true,
        },
      ],
    });
    

TIP

If you use Handsontable through modules: to use an option that comes from a Handsontable plugin, import and register that plugin when initializing your Handsontable instance.

# Example

In the example below, the columns option is set to a function.

The function applies the readOnly: true option to each column that has a physical index of either 2 or 8.

The modified mid-level column options:

  • Overwrite the top-level grid options
  • Cascade down to the bottom-level cell options

As a result, each cell in the third and ninth columns is read-only:

const container = document.querySelector('#example2');

const hot = new Handsontable(container, {
  // top-level grid options
  licenseKey: 'non-commercial-and-evaluation',
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  // in the top-level grid options, all cells are editable
  readOnly: false,
  columns(index) {
    return {
      type: index > 0 ? 'numeric' : 'text',
      readOnly: index === 2 || index === 8
    }
  }
});

// check a cell's options
// returns `false`
hot.getCellMeta(0, 0).readOnly;

// returns `true`
hot.getCellMeta(0, 2).readOnly;

# Setting row options

To apply configuration options to an individual row (or a range of rows), use the cells option.

Any options modified through cells overwrite all other options.

TIP

The cells option is a function invoked before Handsontable's rendering cycle. Implemented incorrectly, it can slow Handsontable down. Use the cells option only if the cell option, the columns option, and the setCellMeta() method don't meet your needs.

  1. Within Handsontable constructor's second argument, add an option called cells, and set it to a function.
    const hot = new Handsontable(container, {
      // top-level grid options that apply to the entire grid
      width: 400,
      height: 300,
      // the `cells` option
      cells() {
    
      };
    });
    
  2. The function can take three arguments:
    • row: a row coordinate (a physical index)
    • col: a column coordinate (a physical index)
    • prop: if your data is an array of objects, prop is a property name for a column's data source object.
      If your data is an array of arrays, prop is the same as col.
    const hot = new Handsontable(container, {
      // the `cells` option set to a function
      cells(row, col, prop) {
        // the `cells` function's body
      }
    });
    
  3. In the cells function's body, implement a logic that selects your required row(s).
    For example, to make each cell of the first row and each cell of the fourth row read-only:
    const hot = new Handsontable(container, {
      // the `cells` options overwrite all other options
      cells(row, col, prop) {
        if (row === 1 || row === 4) {
          return {
            // row options, apply to each cell of the first row
            // and to each cell of the fourth row
            readOnly: true,
          };
        }
      }
    });
    

TIP

If you use Handsontable through modules: to use an option that comes from a Handsontable plugin, import and register that plugin when initializing your Handsontable instance.

# Example

In the example below, the cells option sets each cell in the first and fourth row as readOnly.

Options modified through cells overwrite all other options.

const container = document.querySelector('#example3');

const hot = new Handsontable(container, {
  // top-level grid options that apply to the entire grid
  licenseKey: 'non-commercial-and-evaluation',
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  // the `cells` options overwrite all other options
  // apply only to each cell of rows 1 and 4, as specified in the function's body
  cells(row) {
    if (row === 1 || row === 4) {
      return {
        readOnly: true,
      };
    }
  },
});

// check a cell's options
// returns `false`
hot.getCellMeta(0, 0).readOnly;

// returns `true`
hot.getCellMeta(0, 1).readOnly;

# Setting cell options

To apply configuration options to individual cells, use the cell option.

  1. Within Handsontable constructor's second argument, add an option called cell.
    const hot = new Handsontable(container, {
      // top-level grid options that apply to the entire grid
      width: 400,
      height: 300,
      // the `cell` option
      cell: []
    });
    
  2. Set the cell option to an array of objects.
    const hot = new Handsontable(container, {
      // the `cell` option set to an array of objects
      cell: [
        {},
        {}
      ],
    });
    
  3. In each object, set your configuration options for one particular cell.
    To select a cell, use the row and col coordinates.
    For example, to make cells A1 (0, 0) and B2 (1, 1) read-only:
    const hot = new Handsontable(container, {
      cell: [
        {
          // cell options, apply only to a cell with coordinates (0, 0)
          row: 0,
          col: 0,
          readOnly: true,
        },
        {
          // cell options, apply only to a cell with coordinates (1, 1)
          row: 1,
          col: 1,
          readOnly: true,
        }
      ],
    });
    

TIP

If you use Handsontable through modules: to use an option that comes from a Handsontable plugin, import and register that plugin when initializing your Handsontable instance.

# Example

In the example below, the cell option sets cell A1(0, 0) and cell B2(1, 1) as readOnly.

The modified cell options:

  • Overwrite the top-level grid options
  • Overwrite mid-level column options
const container = document.querySelector('#example4');

const hot = new Handsontable(container, {
  // top-level grid options that apply to the entire grid
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  licenseKey: 'non-commercial-and-evaluation',
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  readOnly: false,
  cell: [
    {
      // bottom-level cell options overwrite the top-level grid options
      // apply only to a cell with coordinates (0, 0)
      row: 0,
      col: 0,
      readOnly: true,
    },
    {
      // bottom-level cell options overwrite the top-level grid options
      // apply only to a cell with coordinates (1, 1)
      row: 1,
      col: 1,
      readOnly: true,
    }
  ]
});

// check a cell's options
// returns `true`
hot.getCellMeta(0, 0).readOnly;

// returns `false`
hot.getCellMeta(0, 1).readOnly;

# Reading cell options

When Handsontable is running, you can check a cell's current options, using the getCellMeta() method.

The getCellMeta() method returns an object with:

For example:

const container = document.querySelector('example');

const hot = new Handsontable(container, {
  // top-level grid options that apply to the entire grid
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  licenseKey: 'non-commercial-and-evaluation',
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  // in the top-level grid options, all cells are read-only
  readOnly: false,
  cell: [
    {
      // bottom-level cell options overwrite the top-level grid options
      // apply only to a cell with coordinates (1, 1)
      row: 1,
      col: 1,
      readOnly: true,
    }
  ]
});

// for cell (0, 0), the `readOnly` option is the default (`false`)
// returns `false`
hot.getCellMeta(0, 0).readOnly;

// for cell (1, 1), the `cell` option overwrote the default `readOnly` value
// returns `true`
hot.getCellMeta(1, 1).readOnly;

# Changing cell options

When Handsontable is running, you can change the initial cell options, using the setCellMeta() method.

For example:

const container = document.querySelector('example');

const hot = new Handsontable(container, {
  // top-level grid options that apply to the entire grid
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  licenseKey: 'non-commercial-and-evaluation',
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  // in the top-level grid options, all cells are read-only
  readOnly: false,
  cell: [
    {
      // bottom-level cell options overwrite the top-level grid options
      // apply only to a cell with coordinates (1, 1)
      row: 1,
      col: 1,
      readOnly: true,
    }
  ]
});

// for cell (0, 0), the `readOnly` option is the default (`false`)
// returns `false`
hot.getCellMeta(0, 0).readOnly;

// for cell (1, 1), the `cell` option overwrote the default `readOnly` value
// returns `true`
hot.getCellMeta(1, 1).readOnly;

// change the `readOnly` option of cell (1, 1) back to `false`
hot.setCellMeta(1, 1, 'readOnly', false);

// returns `false`
hot.getCellMeta(1, 1).readOnly;

# Implementing custom logic

You can apply configuration options to individual grid elements (columns, rows, cells), based on any logic you implement, using the cells option.

The cells option overwrites all other options.

TIP

The cells option is a function invoked before Handsontable's rendering cycle. Implemented incorrectly, it can slow Handsontable down. Use the cells option only if the cell option, the columns option, and the setCellMeta() method don't meet your needs.

  1. Within Handsontable constructor's second argument, add an option called cells, and set it to a function.
    const hot = new Handsontable(container, {
      // top-level grid options that apply to the entire grid
      width: 400,
      height: 300,
      // the `cells` option
      cells() {
    
      };
    });
    
  2. The function can take three arguments:
    • row: a row coordinate (a physical index)
    • col: a column coordinate (a physical index)
    • prop: if your data is an array of objects, prop is a property name for a column's data source object.
      If your data is an array of arrays, prop is the same as col.
    const hot = new Handsontable(container, {
      // the `cells` option set to a function
      cells(row, col, prop) {
        // the `cells` function's body
      }
    });
    
  3. In the cells function's body, implement a logic that selects your required columns, rows, or cells (as combinations of row and col coordinates).
    For example:
    const hot = new Handsontable(container, {
      cells(row, col) {
        if ((row === 1 || row === 5) && col === 1) {
          return {
            readOnly: true,
          };
        }
      }
    });
    

# Example

In the example below, the modified cells options overwrite the top-level grid options.

const container = document.querySelector('#example5');

const hot = new Handsontable(container, {
  // top-level grid options that apply to the entire grid
  licenseKey: 'non-commercial-and-evaluation',
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  // the `cells` option overwrites the top-level grid options
  // apply only to cells selected by your custom logic
  cells(row, col) {
    if ((row === 1 || row === 3) && col === 1) {
      return {
        readOnly: true,
      };
    }
  }
});

# Configuration example

In the example below, some cells are read-only, and some cells are editable:

  • By default, all cells are read-only (as set in the top-level grid options).
  • For the first column, the mid-level column options overwrite the top-level grid options.
    As a result, the first column cells are editable.
  • For cell A1 (0, 0), the bottom-level cell options overwrite both the mid-level column options, and the top-level grid options.
    As a result, cell A1 (0, 0) is read-only, despite being part of the editable first column.
  • For cell C3 (3, 3), the cells option overwrites all other options.
    As a result, cell C3 (3, 3) is editable, despite not being part of the editable first column.
const container = document.querySelector('#example6');

const hot = new Handsontable(container, {
  // top-level grid options that apply to the entire grid
  licenseKey: 'non-commercial-and-evaluation',
  data: Handsontable.helper.createSpreadsheetData(5, 10),
  // in the top-level grid options, all cells are read-only
  readOnly: true,
  width: 'auto',
  height: 'auto',
  rowHeaders: true,
  colHeaders: true,
  // mid-level column options overwrite the top-level grid options
  columns: [
    // each cell in the first (by physical index) column is editable
    {
      readOnly: false,
      className: '',
    },
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
  ],
  // bottom-level cell options overwrite the mid-level column options
  // and ovewrite the top-level grid-options
  cell: [
    {
      // cell (0, 0) is read-only
      row: 0,
      col: 0,
      readOnly: true,
    },
  ],
  // the `cells` option's logic overwrites all other options
  cells(row, col) {
    // cell (2, 2) is editable
    if (row === 2 && col === 2) {
      return {
        readOnly: false,
        className: '',
      }
    }
  },
});