- Data grid
- Examples
- With default column definitions and custom size
- Different filtering types
- Custom theme
- Loading state
- Change detection
- Row selection (with checkboxes)
- Compact and loose row height
- Pinned/sticky columns
- Pagination
- Export data as .csv file
- Dragging and dropping cells
- Changing column order and saving the state
- Localization
- Importing
- Properties
- Dependencies
Datagrid
<mo-datagrid> | MODatagrid
Data grid is a component to display, organize and edit data in table form of rows and columns.
If you do not need the advanced functionality of the data grid, or you need more than just simple string and number values for the data (e.g., icons/inputs etc. inside the table/grid), consider using the table component.
The datagrid implementation in Modes UI is based on ag-grid (community). Their documentation pages provides exhaustive documentation on customization options beyond those available here. Note that some documentation and features are limited to the enterprise license, which is not available here in Modes UI.
<mo-datagrid id="first-example"></mo-datagrid> <br/> <mo-button id="randomize">Randomize data</mo-button> <script> const grid = document.querySelector('#first-example'); const btn = document.querySelector('#randomize'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; } const rowData = createMockData(30); btn.addEventListener('click', () => { grid.grid.setGridOption('rowData', createMockData(30)); }) const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; }; const rowData = createMockData(30); const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; const App = () => <MODatagrid options={gridOptions}></MODatagrid>;
Since Modes UI 4.3 the mo-datagrid
no longer uses icon fonts internally to render the icons.
As such the icon fonts are no longer included in the light.css
and
dark.css
files. If you want to use them elsewhere in your code, you can import them from the
themes
folder:
import '@metsooutotec/modes-web-components/dist/themes/icon-font.css';
Examples
With default column definitions and custom size
The columns do not have to have individual configuration, and instead they will use a global default if it
is defined in the options
. The default height of a grid is 350px
and the default
width is the full width of the container. The height
property must be a static value.
This example features re-sizable and editable columns, with “floating” filter boxes.
<mo-datagrid id="default"></mo-datagrid> <script> const grid = document.querySelector('#default'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; } const rowData = createMockData(30); const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1, filter: true, floatingFilter: true, suppressHeaderMenuButton: true }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn', resizable: false } ], rowData: rowData }; grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; }; const rowData = createMockData(30); const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1, filter: true, floatingFilter: true, suppressHeaderMenuButton: true }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn', resizable: false } ], rowData: rowData }; const App = () => <MODatagrid options={gridOptions}></MODatagrid>;
Different filtering types
Filtering for dates and numbers has some different options than filtering for strings. This example shows how to compare and format dates properly.
<mo-datagrid id="filters"></mo-datagrid> <script> const grid = document.querySelector('#filters'); const picker = document.querySelector('#picker'); function randomDate(start, end) { return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); } function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000), date: randomDate(new Date(2022, 0, 1), new Date()) }); }); return data; } const rowData = createMockData(30); function dateFormatter(date) { return date.toLocaleDateString('en-us', { year: 'numeric', month: 'short', day: 'numeric' }); } const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1, filter: true }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', filter: 'agNumberColumnFilter', type: 'numberColumn' }, { headerName: 'Posting date', minWidth: 200, field: 'date', type: 'dateColumn', filter: 'agDateColumnFilter', valueFormatter: params => dateFormatter(params.data.date), filterParams: { filterOptions: [ 'equals', 'notEqual', { displayKey: 'before', displayName: 'Before', predicate: ([filterValue], cellValue) => cellValue == null || cellValue < filterValue }, { displayKey: 'after', displayName: 'After', predicate: ([filterValue], cellValue) => cellValue == null || cellValue > filterValue }, { displayKey: 'betweenExclusive', displayName: 'Between (Exclusive)', predicate: ([fv1, fv2], cellValue) => cellValue == null || (fv1 < cellValue && fv2 > cellValue), numberOfInputs: 2 }, { displayKey: 'betweenInclusive', displayName: 'Between (Inclusive)', predicate: ([fv1, fv2], cellValue) => cellValue == null || (fv1 <= cellValue && fv2 >= cellValue), numberOfInputs: 2 } ], comparator: (filterLocalDateAtMidnight, cellDate) => { if (cellDate > filterLocalDateAtMidnight) { return 1; } else if (cellDate < filterLocalDateAtMidnight) { return -1; } return 0; } } } ], rowData: rowData }; grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const randomDate = (start, end) => { return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); }; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000), date: randomDate(new Date(2022, 0, 1), new Date()) }); }); return data; }; const rowData = createMockData(30); const dateFormatter = date => { return date.toLocaleDateString('en-us', { year: 'numeric', month: 'short', day: 'numeric' }); }; const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1, filter: true }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', filter: 'agNumberColumnFilter', type: 'numberColumn' }, { headerName: 'Posting date', minWidth: 200, field: 'date', type: 'dateColumn', filter: 'agDateColumnFilter', valueFormatter: params => dateFormatter(params.data.date), filterParams: { filterOptions: [ 'equals', 'notEqual', { displayKey: 'before', displayName: 'Before', predicate: ([filterValue], cellValue) => cellValue == null || cellValue < filterValue }, { displayKey: 'after', displayName: 'After', predicate: ([filterValue], cellValue) => cellValue == null || cellValue > filterValue }, { displayKey: 'betweenExclusive', displayName: 'Between (Exclusive)', predicate: ([fv1, fv2], cellValue) => cellValue == null || (fv1 < cellValue && fv2 > cellValue), numberOfInputs: 2 }, { displayKey: 'betweenInclusive', displayName: 'Between (Inclusive)', predicate: ([fv1, fv2], cellValue) => cellValue == null || (fv1 <= cellValue && fv2 >= cellValue), numberOfInputs: 2 } ], comparator: (filterLocalDateAtMidnight, cellDate) => { if (cellDate > filterLocalDateAtMidnight) { return 1; } else if (cellDate < filterLocalDateAtMidnight) { return -1; } return 0; } } } ], rowData: rowData }; const App = () => <MODatagrid options={gridOptions}></MODatagrid>;
Custom theme
You can use the theme
attribute to further customize the style and spacing inside the grid.
<mo-datagrid id="theme-example"></mo-datagrid> <script> const grid = document.querySelector('#theme-example'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; } const rowData = createMockData(30); const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; const customTheme = { columnBorder: false, rowBorder: false, rowVerticalPaddingScale: 0.5, headerVerticalPaddingScale: 0.5, cellHorizontalPadding: 'var(--mo-spacing-x-small)', horizontalCellPadding: 'var(--mo-spacing-large)', oddRowBackgroundColor: "var(--mo-color-neutral-95)", }; grid.options = gridOptions; grid.theme = customTheme; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; }; const rowData = createMockData(30); const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; const customTheme = { columnBorder: false, rowBorder: false, rowVerticalPaddingScale: 0.5, headerVerticalPaddingScale: 0.5, cellHorizontalPadding: 'var(--mo-spacing-x-small)', horizontalCellPadding: 'var(--mo-spacing-large)', oddRowBackgroundColor: "var(--mo-color-neutral-95)", }; const App = () => <MODatagrid options={gridOptions} theme={customTheme}></MODatagrid>;
The configurable options are dictated by Modes and added to the ag-grid theme configuration. See the
ConfigurableThemeParams
for a list of all options. If you need more configuration options,
raise an issue in GitHub.
Loading state
You can use the loading
property to show the loading message if you are still fetching your
data. Setting it back to false
will hide the message overlay.
<mo-datagrid loading id="loading-example"></mo-datagrid> <br /> <mo-button id="loading-btn">Toggle loading state</mo-button> <script> const grid = document.querySelector('#loading-example'); const btn = document.querySelector('#loading-btn'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; } const rowData = createMockData(30); const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; btn.addEventListener('click', () => { if (grid.loading) { grid.removeAttribute('loading'); } else { grid.setAttribute('loading', true); } }); grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; }; const rowData = createMockData(30); const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; // Implement property toggling logic here const App = () => ( <> <MODatagrid options={gridOptions}></MODatagrid> <br /> <MOButton>Toggle loading state</MOButton> </> );
If you are using the mo-datagrid
in vanilla HTML, you will have to toggle the attribute by
removing it altogether and adding it back in. This is due to the way
boolean attributes are handled by default.
Change detection
You can use the onCellValueChanged
callback in the options api to detect changes made to cells
and run your own logic accordingly. This simple example shows how to retrieve the previous and new value of
the cell when changes occur. See the full return type
here.
<mo-datagrid id="change-example"></mo-datagrid> <pre id="changed-values"></pre> <script> const grid = document.querySelector('#change-example'); const pre = document.querySelector('#changed-values'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; } const rowData = createMockData(30); const cellChanged = e => { pre.textContent = `Change detected!\nOld: ${e.oldValue}\nNew: ${e.value}`; }; const gridOptions = { onCellValueChanged: cellChanged, defaultColDef: { editable: true, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; }; const rowData = createMockData(30); const cellChanged = e => { pre.textContent = `Change detected!\nOld: ${e.oldValue}\nNew: ${e.value}`; }; const gridOptions = { onCellValueChanged: cellChanged, defaultColDef: { editable: true, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; const App = () => <MODatagrid options={gridOptions}></MODatagrid>;
See the ag-grid change detection documentation for more information on what changes can be detected.
Row selection (with checkboxes)
By default hovering and selecting is limited to cells. However, row selection can be enabled with a few simple options.
Rows can be selected by:
- clicking on a single row to select a single row
- using the checkboxes or Command/Control + click to select multiple rows
- Shift + click on two rows to select all rows between the two clicked rows
<mo-datagrid id="row-selection"></mo-datagrid> <div style="display: flex; justify-content: flex-end; gap: 8px; margin: 16px;"> <mo-button id="row-selection-btn" variant="primary" style="margin-bottom: 8px;">Export selected rows</mo-button> </div> <mo-textarea label="Selected rows" readonly placeholder="Data from the selected rows will be here" id="selected-rows-area" ></mo-textarea> <script> const grid = document.querySelector('#row-selection'); const rowSelectionBtn = document.querySelector('#row-selection-btn'); const textAreaRows = document.querySelector('#selected-rows-area'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; } const rowData = createMockData(30); const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true, }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData, rowSelection: { headerCheckbox: true, checkboxes: true, mode: 'multiRow', enableClickSelection: true } }; rowSelectionBtn.addEventListener('click', () => { const selectedRows = grid.grid.getSelectedRows(); textAreaRows.value = JSON.stringify(selectedRows, null, ' '); }); grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const [textValue, setTextValue] = useEffect(''); const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; }; const rowData = createMockData(30); const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true, suppressRowClickSelection: true, }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Price', field: 'price', sortable: true, type: 'numberColumn' } ], rowSelection: { headerCheckbox: true, checkboxes: true, mode: 'multiRow', enableClickSelection: true }, rowData: rowData }; const getSelectedRows = () => { const selectedRows = grid.grid.getSelectedRows(); setTextValue(JSON.stringify(selectedRows, null, ' ')); } const App = () => ( <> <MODatagrid options={gridOptions}></MODatagrid> <div style={{ display: "flex", justifyContent: "flex-end "gap: "8px", margin: "16px" }}> <MOButton variant="primary" style={{ marginBottom: "8px" }}> Export selected rows </MOButton> </div> <MOTextarea label="Selected rows" readonly placeholder="Data from the selected rows will be here" value={textValue} ></MOTextarea> </> );
The options
property must include rowSelection: { mode: 'multiRow' }
to enable
selection of multiple rows. See all documentation on row selection
here.
Compact and loose row height
The default row height is 40px, but users can choose to use either compact
(32px) or
loose
(48px) rows.
Compact
Loose
<div style="display: flex; flex-direction: column; gap: 8px;"> <h4 style="margin: 0">Compact</h4> <mo-datagrid compact id="compact"></mo-datagrid> <mo-divider></mo-divider> <h4 style="margin: 0">Loose</h4> <mo-datagrid loose id="loose"></mo-datagrid> </div> <script> const gridCompact = document.querySelector('#compact'); const gridLoose = document.querySelector('#loose'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; } const rowData = createMockData(30); const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn' } ], rowData: rowData }; // copy options to create new reference const gridOptionsLoose = { ...gridOptions }; gridCompact.options = gridOptions; gridLoose.options = gridOptionsLoose; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000) }); }); return data; }; const rowData = createMockData(30); const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn' } ], rowData: rowData }; // copy options to create new reference const gridOptionsLoose = { ...gridOptions }; const App = () => ( <> <MODatagrid compact options={gridOptions}></MODatagrid> <MODatagrid loose options={gridOptionsLoose}></MODatagrid> </> );
Pinned/sticky columns
It is possible to pin certain columns to allow users to keep track of key column values when scrolling through a long list of columns.
<mo-datagrid id="pinned"></mo-datagrid> <script> const grid = document.querySelector('#pinned'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000), year: Math.ceil(2000 + Math.random() * 22), odometer: Math.max(Math.ceil(Math.random() * 160000), 10000), fuel: Math.random() > 0.5 ? 'Diesel' : 'Gasoline', condition: Math.random() > 0.5 ? 'Good' : 'Bad' }); }); return data; } const rowData = createMockData(50); const gridOptions = { defaultColDef: { flex: 0 }, columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true, pinned: 'left' }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Year', field: 'year', sortable: true, type: 'numberColumn' }, { headerName: 'Fuel', field: 'fuel' }, { headerName: 'Condition', field: 'condition' }, { headerName: 'Odometer', field: 'odometer', sortable: true, type: 'numberColumn' }, { headerName: 'Price', field: 'price', sortable: true, editable: true, type: 'numberColumn' } ], rowData: rowData }; grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.max(Math.ceil(Math.random() * 100000), 5000), year: Math.ceil(2000 + Math.random() * 22), odometer: Math.max(Math.ceil(Math.random() * 160000), 10000), fuel: Math.random() > 0.5 ? 'Diesel' : 'Gasoline', condition: Math.random() > 0.5 ? 'Good' : 'Bad' }); }); return data; }; const rowData = createMockData(50); const gridOptions = { defaultColDef: { flex: 0 }, columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true, pinned: 'left' }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Year', field: 'year', sortable: true, type: 'numberColumn' }, { headerName: 'Fuel', field: 'fuel' }, { headerName: 'Condition', field: 'condition' }, { headerName: 'Odometer', field: 'odometer', sortable: true, type: 'numberColumn' }, { headerName: 'Price', field: 'price', sortable: true, editable: true, type: 'numberColumn' } ], rowData: rowData }; const App = () => <MODatagrid options={gridOptions}></MODatagrid>;
Pagination
Pagination can be enabled by simply setting it to true
in the options
object. The
price column in this example is editable
and its numerical values have been formatted using the
valueFormatter
column definition. See source code for examples.
<mo-datagrid id="grid-pagination"></mo-datagrid> <script> const grid = document.querySelector('#grid-pagination'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000), year: Math.ceil(2000 + Math.random() * 22), odometer: Math.ceil(10000 + Math.random() * 160000) }); }); return data; } const rowData = createMockData(36540); function currencyFormatter(price, sign) { var sansDec = parseInt(price).toFixed(0); var formatted = sansDec.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return sign + `${formatted}`; } function distanceFormatter(price, unit) { var sansDec = parseInt(price).toFixed(0); var formatted = sansDec.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return `${formatted}` + unit; } const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Year', field: 'year', sortable: true, type: 'numberColumn' }, { headerName: 'Odometer', field: 'odometer', sortable: true, type: 'numberColumn', valueFormatter: params => distanceFormatter(params.data.odometer, ' km') }, { headerName: 'Price', field: 'price', sortable: true, editable: true, type: 'numberColumn', valueFormatter: params => currencyFormatter(params.data.price, '$') } ], rowData: rowData, pagination: true }; grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000), year: Math.ceil(2000 + Math.random() * 22), odometer: Math.ceil(10000 + Math.random() * 160000) }); }); return data; }; const rowData = createMockData(36540); const currencyFormatter = (price, sign) => { var sansDec = parseInt(price).toFixed(0); var formatted = sansDec.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return sign + `${formatted}`; }; const distanceFormatter = (price, unit) => { var sansDec = parseInt(price).toFixed(0); var formatted = sansDec.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return `${formatted}` + unit; }; const gridOptions = { columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Year', field: 'year', sortable: true, type: 'numberColumn' }, { headerName: 'Odometer', field: 'odometer', sortable: true, type: 'numberColumn', valueFormatter: params => distanceFormatter(params.data.odometer, ' km') }, { headerName: 'Price', field: 'price', sortable: true, editable: true, type: 'numberColumn', valueFormatter: params => currencyFormatter(params.data.price, '$') } ], rowData: rowData, pagination: true }; const App = () => <MODatagrid options={gridOptions}></MODatagrid>;
Editing a price of one row also modifies the price of other rows with the same make, model, etc. The grid automatically indexes rows, but it fails if multiple rows have duplicate data.
Export data as .csv file
Data from the data grid can be exported in to a .csv format, and downloaded. These can be achieved by using
the grid.grid
functions getDataAsCsv
and exportDataAsCsv
.
<mo-datagrid id="csv"></mo-datagrid> <div style="display: flex; justify-content: flex-end; gap: 8px; margin: 16px;"> <mo-button id="textarea-btn" variant="secondary" style="margin-bottom: 8px;">Export data to text field</mo-button> <mo-button id="export-btn" style="margin-bottom: 8px;">Download exported csv data</mo-button> </div> <mo-textarea label="CSV output" readonly placeholder="CSV data will be here" id="csv-output"></mo-textarea> <script> const moGrid = document.querySelector('#csv'); const textarea = document.querySelector('#csv-output'); const exportBtn = document.querySelector('#export-btn'); const textareaBtn = document.querySelector('#textarea-btn'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000) }); }); return data; } const rowData = createMockData(30); const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn' } ], rowData: rowData }; textareaBtn.addEventListener('click', () => { textarea.value = moGrid.grid.getDataAsCsv(); }); exportBtn.addEventListener('click', () => { moGrid.grid.exportDataAsCsv(); }); moGrid.options = gridOptions; </script>
import { MODatagrid, MOButton, MOTextarea } from '@metsooutotec/modes-web-components/dist/react'; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000) }); }); return data; }; const rowData = createMockData(30); const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make' }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn' } ], rowData: rowData }; const getData = () => { textarea.value = grid.grid.getDataAsCsv(); }; const exportData = () => { grid.grid.exportDataAsCsv(); }; const App = () => ( <> <MODatagrid options={gridOptions}></MODatagrid> <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px', margin: '16px' }}> <MOButton onClick={getData} variant="secondary" style={{ marginBottom: '8px' }}> Export data to text field </MOButton> <MOButton onClick={exportData} style={{ marginBottom: '8px' }}> Download exported csv data </MOButton> </div> <MOTextarea label="CSV output" readonly placeholder="CSV data will be here"></MOTextarea> </> );
Dragging and dropping cells
The data grid supports dragging and dropping of cells. Drag and drop can be enabled by setting the value of
dndSource
to true
in the column definitions. This example shows how the grid can
be combined with a mo-drop-handler
to extract data out of the cell/row.
<div class="container"> <mo-datagrid height="100%" id="reordering"></mo-datagrid> <mo-icon class="arrow-icon" name="arrow-down"></mo-icon> <mo-drop-handler id="drop-handler"> <div id="message" class="drop-handler-content">Drop cells here</div> </mo-drop-handler> <mo-textarea placeholder="Dropped items will be shown here" label="Dropped items" readonly id="dropped-items" ></mo-textarea> </div> <script> const grid = document.querySelector('#reordering'); const dropHandler = document.querySelector('#drop-handler'); const message = document.querySelector('#message'); const textarea = document.querySelector('#dropped-items'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000) }); }); return data; } const rowData = createMockData(500); dropHandler.addEventListener('mo-drop', event => { const cellJson = event.detail.event.dataTransfer.getData('application/json'); const currentValue = textarea.value; const newValue = currentValue.concat(`${currentValue.length !== 0 ? ',\n' : ''}` + cellJson); textarea.value = newValue; }); const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make', dndSource: true }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn' } ], rowData: rowData, rowDragManaged: true, animateRows: true }; grid.options = gridOptions; </script> <style> .container { display: flex; gap: 16px; height: 800px; flex-direction: column; } .arrow-icon { font-size: 48px; margin-left: calc(16.5% - 24px); } .drop-handler-content { padding: 1rem 1.5rem; border: 1px dashed var(--mo-color-secondary-70); transition: all var(--mo-transition-medium) ease-in-out; } mo-drop-handler[dragged] .drop-handler { border-color: var(--mo-color-secondary-30); background-color: var(--mo-color-secondary-90); } </style>
import { MODatagrid, MODropHandler, MOIcon, MOTextarea } from '@metsooutotec/modes-web-components/dist/react'; const css = ` .container { display: flex; gap: 16px; flex-direction: column; } .arrow-icon { font-size: 48px; margin-left: calc(16.5% - 24px); } .drop-handler-content { padding: 1rem 1.5rem; border: 1px dashed var(--mo-color-secondary-70); transition: all var(--mo-transition-medium) ease-in-out; } mo-drop-handler[dragged] .drop-handler { border-color: var(--mo-color-secondary-30); background-color: var(--mo-color-secondary-90); } `; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000) }); }); return data; }; const rowData = createMockData(500); const onDrop = event => { const cellJson = event.detail.dataTransfer.getData('application/json'); const currentValue = textarea.value; const newValue = currentValue.concat(`${currentValue.length !== 0 ? ',\n' : ''}` + cellJson); textarea.value = newValue; }; const gridOptions = { defaultColDef: { editable: true, resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make', dndSource: true }, { headerName: 'Model', field: 'model' }, { headerName: 'Price', field: 'price', type: 'numberColumn' } ], rowData: rowData, rowDragManaged: true, animateRows: true }; const App = () => ( <> <div class="container"> <MODatagrid height="100%"></MODatagrid> <MOIcon class="arrow-icon" name="arrow-down"></MOIcon> <MODropHandler onMoDrop={event => onDrop(event)}> <div class="drop-handler-content">Drop cells here</div> </MODropHandler> <MOTextarea placeholder="Dropped items will be shown here" label="Dropped items" readonly></MOTextarea> </div> <style>{css}</style> </> );
The example above is showing the maximum amount of rows that can rendered on one page, which is 500. In general if you have hundreds of entries, we recommend using pagination to show the data.
Changing column order and saving the state
As mentioned above, unfortunately dragging and dropping columns to re-order them is not functional in this
version of ag-grid
. However, column order can still be changed programmatically, and the state
of the column order and sorting can be saved, reset or restored.
Column control
State control
<mo-datagrid id="save-state"></mo-datagrid> <mo-divider style="margin: 2em 0;"></mo-divider> <div style="display: flex; justify-content: space-between;"> <div> <p style="margin: 0; font-family: GT-Eesti">Column control</p> <mo-button-group> <mo-button id="price-first">Price first</mo-button> <mo-button id="make-last">Model last</mo-button> <mo-button id="sort-odometer">Sort by Odometer</mo-button> </mo-button-group> </div> <div> <p style="margin: 0; text-align: end; font-family: GT-Eesti">State control</p> <mo-button-group> <mo-tooltip id="save-tooltip" content="Save"> <mo-button id="save-btn"><mo-icon name="save"></mo-icon></mo-button> </mo-tooltip> <mo-tooltip content="Restore"> <mo-button id="restore-btn"><mo-icon name="reload"></mo-icon></mo-button> </mo-tooltip> <mo-tooltip content="Reset"> <mo-button id="reset-btn"><mo-icon name="refresh"></mo-icon></mo-button> </mo-tooltip> </mo-button-group> </div> </div> <script> const moGrid = document.querySelector('#save-state'); const priceFirst = document.querySelector('#price-first'); const modelLast = document.querySelector('#make-last'); const sortOdometer = document.querySelector('#sort-odometer'); const saveBtn = document.querySelector('#save-btn'); const restoreBtn = document.querySelector('#restore-btn'); const resetBtn = document.querySelector('#reset-btn'); const saveTooltip = document.querySelector('#save-tooltip'); function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000), year: Math.ceil(2000 + Math.random() * 22), odometer: Math.ceil(10000 + Math.random() * 160000) }); }); return data; } const rowData = createMockData(150); const gridOptions = { defaultColDef: { resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Year', field: 'year', sortable: true, type: 'numberColumn' }, { headerName: 'Odometer', field: 'odometer', sortable: true, type: 'numberColumn' }, { headerName: 'Price', field: 'price', sortable: true, editable: true, type: 'numberColumn' } ], rowData: rowData }; priceFirst.addEventListener('click', () => { moGrid.grid.moveColumn('price', 0); // redraw rows to make cell borders render correctly moGrid.grid.redrawRows(); }); modelLast.addEventListener('click', () => { moGrid.grid.moveColumn('model', 4); // redraw rows to make cell borders render correctly moGrid.grid.redrawRows(); }); sortOdometer.addEventListener('click', () => { moGrid.grid.applyColumnState({ state: [{ colId: 'odometer', sort: 'asc' }], defaultState: { sort: null } }); }); saveBtn.addEventListener('click', () => { localStorage.setItem('colState', JSON.stringify(moGrid.grid.getColumnState())); saveTooltip.content = 'State saved succesfully.'; setTimeout(() => { saveTooltip.content = 'Save'; }, 2000); }); restoreBtn.addEventListener('click', () => { if (localStorage.getItem('colState')) { moGrid.grid.applyColumnState({ state: JSON.parse(localStorage.getItem('colState')), applyOrder: true }); } }); resetBtn.addEventListener('click', () => { moGrid.grid.resetColumnState(); }); moGrid.options = gridOptions; </script>
import { MODatagrid, MOButtonGroup, MOButton, MOIcon, MOTooltip, MODivider } from '@metsooutotec/modes-web-components/dist/react'; const [saveContent, setSaveContent] = useState('Save'); const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000), year: Math.ceil(2000 + Math.random() * 22), odometer: Math.ceil(10000 + Math.random() * 160000) }); }); return data; }; const rowData = createMockData(150); const gridOptions = { defaultColDef: { resizable: true, minWidth: 100, flex: 1 }, columnDefs: [ { headerName: 'Make', field: 'make', sortable: true, filter: true }, { headerName: 'Model', field: 'model', sortable: true }, { headerName: 'Year', field: 'year', sortable: true, type: 'numberColumn' }, { headerName: 'Odometer', field: 'odometer', sortable: true, type: 'numberColumn' }, { headerName: 'Price', field: 'price', sortable: true, editable: true, type: 'numberColumn' } ], rowData: rowData }; const priceFirst = () => { grid.grid.moveColumn('price', 0); // redraw rows to make cell borders render correctly grid.grid.redrawRows(); }; const modelLast = () => { grid.grid.moveColumn('model', 4); // redraw rows to make cell borders render correctly grid.grid.redrawRows(); }; const sortOdometer = () => { grid.grid.applyColumnState({ state: [{ colId: 'odometer', sort: 'asc' }], defaultState: { sort: null } }); }; const saveState = () => { localStorage.setItem('colState', JSON.stringify(grid.grid.getColumnState())); setSaveContent('State saved succesfully.'); setTimeout(() => { setSaveContent('Save'); }, 2000); }; const restoreState = () => { if (localStorage.getItem('colState')) { grid.grid.applyColumnState({ state: JSON.parse(localStorage.getItem('colState')), applyOrder: true }); } }; const resetState = () => { grid.grid.resetColumnState(); }; const App = () => ( <> <MODatagrid options={gridOptions}></MODatagrid> <MODivider style={{ margin: '2em 0' }}></MODivider> <div style={{ display: 'flex', justifyContent: 'space-between' }}> <div> <p style={{ margin: 0, fontFamily: 'GT-Eesti' }}>Column control</p> <MOButtonGroup> <MOButton onClick={priceFirst()}>Price first</MOButton> <MOButton onClick={modelLast()}>Model last</MOButton> <MOButton onClick={sortOdometer()}>Sort by Odometer</MOButton> </MOButtonGroup> </div> <div> <p style={{ margin: 0, textAlign: 'end', fontFamily: 'GT-Eesti' }}>State control</p> <MOButtonGroup> <MOTooltip content={saveContent}> <MOButton> <MOIcon onClick={saveState()} name="save"></MOIcon> </MOButton> </MOTooltip> <MOTooltip content="Restore"> <MOButton onClick={restoreState()}> <MOIcon name="reload"></MOIcon> </MOButton> </MOTooltip> <MOTooltip content="Reset"> <MOButton onClick={resetState()}> <MOIcon name="refresh"></MOIcon> </MOButton> </MOTooltip> </MOButtonGroup> </div> </div> </> );
Note that in order to see the numeric sorting icon, you must set the column type to
numberColumn
(or dateColumn
for dates).
Localization
All the displayed text in the grid is customisable for the purposes of localisation. This is done by
providing locale information to the grid for the required language. Either provide an object of key/value
pairs via the localeText
property, or provide a getLocaleText
callback to hook the
grid up to your application’s localisation.
<div style="display: flex; justify-content: flex-end"> <mo-select id="locale-select" style="width: 125px" label="Choose locale" value="fin"> <mo-option value="en">English</mo-option> <mo-option value="fin">Suomi</mo-option> </mo-select> </div> <br /> <mo-datagrid id="grid-localization"></mo-datagrid> <script> const grid = document.querySelector('#grid-localization'); const select = document.querySelector('#locale-select'); let locale = 'fin'; const localeTextEN = { // custom specific make: 'Make', model: 'Model', price: 'Price', // Set Filter selectAll: '(Select All)', selectAllSearchResults: '(Select All Search Results)', searchOoo: 'Search...', blanks: '(Blanks)', noMatches: 'No matches', // Number Filter & Text Filter filterOoo: 'Filter...', equals: 'Equals', notEqual: 'Not equal', blank: 'Blank', notBlank: 'Not blank', empty: 'Choose One', // Number Filter lessThan: 'Less than', greaterThan: 'Greater than', lessThanOrEqual: 'Less than or equal', greaterThanOrEqual: 'Greater than or equal', inRange: 'In range', inRangeStart: 'from', inRangeEnd: 'to', // Text Filter contains: 'Contains', notContains: 'Not contains', startsWith: 'Starts with', endsWith: 'Ends with', // Date Filter dateFormatOoo: 'yyyy-mm-dd', // Filter Conditions andCondition: 'AND', orCondition: 'OR', // Filter Buttons applyFilter: 'Apply', resetFilter: 'Reset', clearFilter: 'Clear', cancelFilter: 'Cancel', // Filter Titles textFilter: 'Text Filter', numberFilter: 'Number Filter', dateFilter: 'Date Filter', setFilter: 'Set Filter', // Side Bar columns: 'Columns', filters: 'Filters', // columns tool panel pivotMode: 'Pivot Mode', groups: 'Row Groups', rowGroupColumnsEmptyMessage: 'Drag here to set row groups', values: 'Values', valueColumnsEmptyMessage: 'Drag here to aggregate', pivots: 'Column Labels', pivotColumnsEmptyMessage: 'Drag here to set column labels', // Header of the Default Group Column group: 'Group', // Row Drag rowDragRows: 'rows', // Other loadingOoo: 'Loading...', noRowsToShow: 'No Rows To Show', enabled: 'Enabled' }; const localeTextFI = { // custom specific make: 'Valmistaja', model: 'Malli', price: 'Hinta', // Set Filter selectAll: '(Valitse kaikki)', selectAllSearchResults: '(Valitse kaikki haun tulokset)', searchOoo: 'Hae...', blanks: '(Tyhjää)', noMatches: 'Ei osumia', // Number Filter & Text Filter filterOoo: 'Suodata...', equals: 'Yhtäsuuri kuin', notEqual: 'Erisuuri kuin', blank: 'Tyhjä', notBlank: 'Ei tyhjä', empty: 'Valitse yksi', // Number Filter lessThan: 'Vähemmän kuin', greaterThan: 'Suurempi kuin', lessThanOrEqual: 'Vähemmän tai yhtäsuuri kuin', greaterThanOrEqual: 'Suurempi tai yhtäsuuri kuin', inRange: 'Välillä', inRangeStart: 'alku', inRangeEnd: 'loppu', // Text Filter contains: 'Sisältää', notContains: 'Ei sisällä', startsWith: 'Alkaa', endsWith: 'Loppuu', // Date Filter dateFormatOoo: 'dd-mm-yyyy', // Filter Conditions andCondition: 'JA', orCondition: 'TAI', // Filter Buttons applyFilter: 'Käytä', resetFilter: 'Nollaa', clearFilter: 'Tyhjennä', cancelFilter: 'Peruuta', // Filter Titles textFilter: 'Teksti suodatin', numberFilter: 'Numero suodatin', dateFilter: 'Päivämäärä suodatin', setFilter: 'Aseta suodatin', // Side Bar columns: 'Kolumnit', filters: 'Suodattimet', // Header of the Default Group Column group: 'Ryhmä', // Row Drag rowDragRows: 'rivit', // Other loadingOoo: 'Lataa...', noRowsToShow: 'Ei näytetäviä rivejä', enabled: 'Käytössä' }; function createMockData(rows) { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000) }); }); return data; } const rowData = createMockData(50); function getLocaleText() { return locale === 'en' ? localeTextEN : localeTextFI; } const gridOptions = { localeText: getLocaleText(), columnDefs: [ { headerName: getLocaleText().make, field: 'make', sortable: true, filter: true }, { headerName: getLocaleText().model, field: 'model', sortable: true }, { headerName: getLocaleText().price, field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; select.addEventListener('mo-change', event => { locale = event.target.value; grid.options = { localeText: getLocaleText(), columnDefs: [ { headerName: getLocaleText().make, field: 'make', sortable: true, filter: true }, { headerName: getLocaleText().model, field: 'model', sortable: true }, { headerName: getLocaleText().price, field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; // re-draw grid to update locale grid.refreshGrid(); }); grid.options = gridOptions; </script>
import { MODatagrid } from '@metsooutotec/modes-web-components/dist/react'; var locale = 'fin'; const localeTextEN = { // custom specific make: 'Make', model: 'Model', price: 'Price', // Set Filter selectAll: '(Select All)', selectAllSearchResults: '(Select All Search Results)', searchOoo: 'Search...', blanks: '(Blanks)', noMatches: 'No matches', // Number Filter & Text Filter filterOoo: 'Filter...', equals: 'Equals', notEqual: 'Not equal', blank: 'Blank', notBlank: 'Not blank', empty: 'Choose One', // Number Filter lessThan: 'Less than', greaterThan: 'Greater than', lessThanOrEqual: 'Less than or equal', greaterThanOrEqual: 'Greater than or equal', inRange: 'In range', inRangeStart: 'from', inRangeEnd: 'to', // Text Filter contains: 'Contains', notContains: 'Not contains', startsWith: 'Starts with', endsWith: 'Ends with', // Date Filter dateFormatOoo: 'yyyy-mm-dd', // Filter Conditions andCondition: 'AND', orCondition: 'OR', // Filter Buttons applyFilter: 'Apply', resetFilter: 'Reset', clearFilter: 'Clear', cancelFilter: 'Cancel', // Filter Titles textFilter: 'Text Filter', numberFilter: 'Number Filter', dateFilter: 'Date Filter', setFilter: 'Set Filter', // Side Bar columns: 'Columns', filters: 'Filters', // columns tool panel pivotMode: 'Pivot Mode', groups: 'Row Groups', rowGroupColumnsEmptyMessage: 'Drag here to set row groups', values: 'Values', valueColumnsEmptyMessage: 'Drag here to aggregate', pivots: 'Column Labels', pivotColumnsEmptyMessage: 'Drag here to set column labels', // Header of the Default Group Column group: 'Group', // Row Drag rowDragRows: 'rows', // Other loadingOoo: 'Loading...', noRowsToShow: 'No Rows To Show', enabled: 'Enabled' }; const localeTextFI = { // custom specific make: 'Valmistaja', model: 'Malli', price: 'Hinta', // Set Filter selectAll: '(Valitse kaikki)', selectAllSearchResults: '(Valitse kaikki haun tulokset)', searchOoo: 'Hae...', blanks: '(Tyhjää)', noMatches: 'Ei osumia', // Number Filter & Text Filter filterOoo: 'Suodata...', equals: 'Yhtäsuuri kuin', notEqual: 'Erisuuri kuin', blank: 'Tyhjä', notBlank: 'Ei tyhjä', empty: 'Valitse yksi', // Number Filter lessThan: 'Vähemmän kuin', greaterThan: 'Suurempi kuin', lessThanOrEqual: 'Vähemmän tai yhtäsuuri kuin', greaterThanOrEqual: 'Suurempi tai yhtäsuuri kuin', inRange: 'Välillä', inRangeStart: 'alku', inRangeEnd: 'loppu', // Text Filter contains: 'Sisältää', notContains: 'Ei sisällä', startsWith: 'Alkaa', endsWith: 'Loppuu', // Date Filter dateFormatOoo: 'dd-mm-yyyy', // Filter Conditions andCondition: 'JA', orCondition: 'TAI', // Filter Buttons applyFilter: 'Käytä', resetFilter: 'Nollaa', clearFilter: 'Tyhjennä', cancelFilter: 'Peruuta', // Filter Titles textFilter: 'Teksti suodatin', numberFilter: 'Numero suodatin', dateFilter: 'Päivämäärä suodatin', setFilter: 'Aseta suodatin', // Side Bar columns: 'Kolumnit', filters: 'Suodattimet', // Header of the Default Group Column group: 'Ryhmä', // Row Drag rowDragRows: 'rivit', // Other loadingOoo: 'Lataa...', noRowsToShow: 'Ei näytetäviä rivejä', enabled: 'Käytössä' }; const createMockData = rows => { const data = []; const makes = ['Toyota', 'Honda', 'Skoda', 'Audi']; const models = ['Superb', 'Celica', 'A4', 'Civic']; Array.from(Array(rows)).forEach((x, i) => { data.push({ make: makes[Math.ceil(Math.random() * makes.length) - 1], model: models[Math.ceil(Math.random() * models.length) - 1], price: Math.ceil(5000 + Math.random() * 100000) }); }); return data; }; const rowData = createMockData(50); const getLocaleText = () => { return locale === 'en' ? localeTextEN : localeTextFI; }; const gridOptions = { localeText: getLocaleText(), columnDefs: [ { headerName: getLocaleText().make, field: 'make', sortable: true, filter: true }, { headerName: getLocaleText().model, field: 'model', sortable: true }, { headerName: getLocaleText().price, field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; const updateLocale = event => { locale = event.target.value; grid.options = { localeText: getLocaleText(), columnDefs: [ { headerName: getLocaleText().make, field: 'make', sortable: true, filter: true }, { headerName: getLocaleText().model, field: 'model', sortable: true }, { headerName: getLocaleText().price, field: 'price', sortable: true, type: 'numberColumn' } ], rowData: rowData }; // re-draw grid to update locale grid.refreshGrid(); }; const App = () => ( <> <div style={{ display: 'flex', justifyContent: 'flex-end' }}> <MOSelect onMoSelect={event => updateLocale(event)} style={{ width: '125px' }} label="Choose locale" value="fin"> <MOOption value="en">English</MOOption> <MOOption value="fin">Suomi</MOOption> </MOSelect> </div> <MODatagrid options={gridOptions}></MODatagrid> </> );
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.
To import this component using a bundler:
import '@metsooutotec/modes-web-components/dist/components/datagrid/datagrid.js';
To import this component as a React component:
import MODatagrid from '@metsooutotec/modes-web-components/dist/react/datagrid/';
To import this component using a script tag:
<script type="module" src="https://modes-web.metso.com/dist/components/cdn/components/datagrid/datagrid.js"></script>
Properties
Name | Description | Reflects | Type | Default |
---|---|---|---|---|
grid
|
Reference to the grid itself. It would make more sense to call this api after ag-grid v31 but to avoid breaking changes it is still called grid |
GridApi
|
- | |
options
|
Options to supply to the Grid. |
GridOptions
|
- | |
height
|
Static height of the grid. |
string
|
'350px'
|
|
compact
|
Makes the grid more compact by changing row height to 32px. |
|
boolean
|
false
|
loose
|
Makes the grid looser by changing row height to 48px. |
|
boolean
|
false
|
loading
|
Set this to true to showcase a loading message while fetching data. Toggle off to remove message. |
|
boolean
|
false
|
theme
|
Custom theme for the grid |
CustomizableThemeParams | undefined
|
- | |
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Dependencies
This component automatically imports the following dependencies.