Skip to main content
About Project Overview Contributing Getting Started Installation Usage Themes Customizing Frameworks React Vue Angular GitHub Light Dark System

Data Grid

<terra-data-grid> | TerraDataGrid
Since 1.0 experimental

A flexible data grid component built on AG Grid with support for various data sources and row models.

<terra-data-grid id="basic-grid"></terra-data-grid>

<script>
    const grid = document.querySelector('#basic-grid')
    grid.columnDefs = [
        { field: 'name', headerName: 'Name', flex: 1 },
        { field: 'age', headerName: 'Age', flex: 1 },
        { field: 'email', headerName: 'Email', flex: 2 },
    ]
    grid.rowData = [
        { name: 'John Doe', age: 30, email: 'john.doe@example.com' },
        { name: 'Jane Smith', age: 25, email: 'jane.smith@example.com' },
        { name: 'Bob Johnson', age: 35, email: 'bob.johnson@example.com' },
    ]
</script>

Examples

Basic Client-Side Grid

The simplest way to use the data grid is with client-side row data:

<terra-data-grid id="grid"></terra-data-grid>

<script>
    const grid = document.querySelector('#grid')
    grid.columnDefs = [
        { field: 'title', headerName: 'Title', flex: 3 },
        { field: 'size', headerName: 'Size (MB)', flex: 1 },
        { field: 'date', headerName: 'Date', flex: 1 },
    ]
    grid.rowData = [
        { title: 'File 1', size: 10.5, date: '2024-01-15' },
        { title: 'File 2', size: 25.3, date: '2024-01-16' },
        { title: 'File 3', size: 8.2, date: '2024-01-17' },
    ]
</script>

Infinite Scroll Grid

For large datasets, use the infinite scroll row model with a datasource:

<terra-data-grid id="grid-infinite" row-model-type="infinite" height="600px"></terra-data-grid>

<script>
    const grid = document.querySelector('#grid-infinite')
    grid.columnDefs = [
        { field: 'title', flex: 3 },
        { field: 'size', headerName: 'Size (MB)', sortable: false, searchable: false },
        { field: 'date', headerName: 'Date', sortable: false, filterable: false },
    ]

    grid.datasource = {
        rowCount: undefined, // Unknown total row count
        getRows: async params => {
            //! You would fetch data from your API doing something like this
            //! await fetch(`/api/data?start=${params.startRow}&end=${params.endRow}`)
            //! We're going to mock a response instead
            const data = {
                total: 1000,
                items: [],
            }

            for (var i = params.startRow + 1; i <= params.endRow; i++) {
                data.items.push({
                    title: `File ${i}`,
                    size: i * Math.random(),
                    date: randomDate(),
                })
            }

            const lastRow = data.total <= params.endRow ? data.total : -1

            // mock a delay
            setTimeout(() => params.successCallback(data.items, lastRow), 500)
        },
    }

    function randomDate() {
        const startTime = new Date(2010, 0, 1).getTime();
        const endTime = new Date(2021, 11, 31).getTime();

        const randomTimestamp = startTime + Math.random() * (endTime - startTime);

        return new Date(randomTimestamp);
    }
</script>

With Grid Options

You can pass a complete gridOptions object for advanced configuration:

<terra-data-grid id="grid-options"></terra-data-grid>

<script>
    const grid = document.querySelector('#grid-options')
    grid.gridOptions = {
        columnDefs: [
            { field: 'name', sortable: true, filter: true },
            { field: 'age', type: 'numberColumn' },
            { field: 'email', editable: true },
        ],
        rowData: [
            { name: 'John', age: 30, email: 'john@example.com' },
            { name: 'Jane', age: 25, email: 'jane@example.com' },
        ],
        pagination: true,
        paginationPageSize: 20,
        rowSelection: 'multiple',
        onRowClicked: event => {
            console.log('Row clicked:', event.data)
        },
    }
</script>

Event Handling

Listen to grid events:

<terra-data-grid id="grid-events"></terra-data-grid>

<script>
    const grid = document.querySelector('#grid-events')

    grid.gridOptions = {
        columnDefs: [
            { field: 'name', sortable: true, filter: true },
            { field: 'age', type: 'numberColumn' },
            { field: 'email', editable: true },
        ],
        rowData: [
            { name: 'John', age: 30, email: 'john@example.com' },
            { name: 'Jane', age: 25, email: 'jane@example.com' },
        ],
        pagination: true,
        paginationPageSize: 20,
        rowSelection: 'multiple',
        onRowClicked: event => {
            console.log('Row clicked:', event.data)
        },
    }

    grid.addEventListener('terra-grid-ready', event => {
        console.log('Grid is ready!', event.detail)
    })

    grid.addEventListener('terra-row-clicked', event => {
        console.log('Row clicked:', event.detail.data)
    })

    grid.addEventListener('terra-selection-changed', event => {
        const selectedRows = event.detail.api.getSelectedRows()
        console.log('Selected rows:', selectedRows)
    })
</script>

Programmatic Control

Access the grid API for programmatic control:

<terra-data-grid id="grid-prog"></terra-data-grid>
<button id="refresh-btn">Refresh</button>
<button id="export-btn">Export CSV</button>

<script>
    const grid = document.querySelector('#grid-prog')
    grid.columnDefs = [{ field: 'name' }, { field: 'value' }]
    grid.rowData = [
        { name: 'Item 1', value: 100 },
        { name: 'Item 2', value: 200 },
    ]

    function refreshGrid() {
        grid.refresh()
    }

    function exportCsv() {
        grid.exportToCsv({ fileName: 'export.csv' })
    }

    document.getElementById('refresh-btn').click(refreshGrid)
    document.getElementById('export-btn').click(exportCsv)
</script>

[component-metadata:terra-data-grid]

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/@nasa-terra/components@0.0.138/cdn/components/data-grid/data-grid.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/@nasa-terra/components@0.0.138/cdn/components/data-grid/data-grid.js';

To import this component using a bundler:

import '@nasa-terra/components/dist/components/data-grid/data-grid.js';

To import this component as a React component:

import TerraDataGrid from '@nasa-terra/components/dist/react/data-grid';

Properties

Name Description Reflects Type Default
gridOptions AG Grid options configuration object. This is the primary way to configure the grid. Must be set via JavaScript (not as an attribute). GridOptions | undefined -
columnDefs Column definitions for the grid. Alternative to setting columnDefs in gridOptions. Must be set via JavaScript (not as an attribute). ColDef[] | undefined -
rowData Row data for client-side row model. Must be set via JavaScript (not as an attribute). T[] | undefined -
datasource Datasource for infinite scroll row model. Must be set via JavaScript (not as an attribute). IDatasource | undefined -
height Height of the grid in pixels or CSS units. Default: 400px string '400px'
rowModelType
row-model-type
Row model type: ‘clientSide’, ‘infinite’, or ‘serverSide’. Default: ‘clientSide’ 'clientSide' | 'infinite' | 'serverSide' 'clientSide'
theme Theme for AG Grid: ‘alpine’, ‘alpine-dark’, ‘balham’, ‘balham-dark’, ‘material’, ‘quartz’. Default: ‘alpine’ string 'alpine'
showLoading
show-loading
Whether to show loading overlay when data is being fetched. Default: false boolean false
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
terra-grid-ready onTerraGridReady Emitted when the grid is initialized and ready. -
terra-selection-changed onTerraSelectionChanged Emitted when row selection changes. -
terra-sort-changed onTerraSortChanged Emitted when column sorting changes. -
terra-filter-changed onTerraFilterChanged Emitted when column filters change. -
terra-row-clicked onTerraRowClicked Emitted when a row is clicked. -
terra-row-double-clicked onTerraRowDoubleClicked Emitted when a row is double-clicked. -
terra-cell-clicked onTerraCellClicked Emitted when a cell is clicked. -
terra-cell-value-changed onTerraCellValueChanged Emitted when a cell value is edited. -

Learn more about events.

Methods

Name Description Arguments
getGridApi() Get the AG Grid API instance. Useful for programmatic control of the grid. -
refresh() Refresh the grid data. For infinite scroll, purges cache and refetches. -
exportToCsv() Export grid data to CSV. options: CsvExportParams
exportToExcel() Export grid data to Excel. Note: Requires AG Grid Enterprise license. options: ExcelExportParams

Learn more about methods.

Custom Properties

Name Description Default
--terra-data-grid-height The height of the grid (default: 400px).
--terra-data-grid-border-color Border color using HDS tokens.
--terra-data-grid-header-background Header background color.

Learn more about customizing CSS custom properties.

Parts

Name Description
base The component’s base wrapper.
grid The AG Grid container element.
loading The loading overlay container.

Learn more about customizing CSS parts.

Dependencies

This component automatically imports the following dependencies.

  • <ag-grid-community>
  • <terra-loader>