<ReactDataGrid />
supports. Besides this list, the component also supports all standard DOM attributes - those are not explicitly mentioned here, with a few exceptions.Bool
default: true
true
, will make the first row of the <ReactDataGrid />
active when the <ReactDataGrid />
receives focus - see activeIndex
.<ReactDataGrid />
receives focus and you hit the ArrowDown
key, the first row is becomes active, even if activateRowOnFocus
is false
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import TextInput from '../components/TextInput'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
];
const App = () => {
const [activateRowOnFocus, setActivateRowOnFocus] = useState(true);
return (
<div>
<p>Navigate with Tab key</p>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={activateRowOnFocus}
onChange={setActivateRowOnFocus}
>
Activate row on focus
</CheckBox>
</div>
<TextInput style={{ marginBottom: 20, padding: 5, width: 250 }} type="text" autoFocus defaultValue="Hit tab to navigate to grid" />
<ReactDataGrid
idProperty="id"
style={gridStyle}
activateRowOnFocus={activateRowOnFocus}
columns={columns}
dataSource={people}
/>
<TextInput style={{ marginTop: 20, padding: 5, width: 250 }} type="text" defaultValue="Hit shift+tab to navigate to grid" />
</div>
);
}
export default () => <App />
Number[2]
default: undefined
<ReactDataGrid />
(as opposed to row keyboard navigation). For row navigation, see activeIndex
or defaultActiveIndex
.defaultActiveCell
.<ReactDataGrid />
cell, make sure you update the value of the controlled activeCell
prop when onActiveCellChange
is triggered.activeCell
should be an array of length 2
, the first value being the row index, while the second value is the column index of the activeCell
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', minWidth: 100, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
const App = () => {
const [enableKeyboardNavigation, setEnableKeyboardNavigation] = useState(true);
const [activeCell, setActiveCell] = useState([4, 1]);
return (
<div>
<div>
<CheckBox checked={enableKeyboardNavigation} onChange={setEnableKeyboardNavigation}>
Enable keyboard navigation
</CheckBox>
</div>
<p>Currently active cell: {JSON.stringify(activeCell)}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
activeCell={activeCell}
onActiveCellChange={setActiveCell}
enableKeyboardNavigation={enableKeyboardNavigation}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 100
arrow up/down/left/right
) to change the activeCell
, the keyboard events can fire very quickly, which would be a bottleneck to update the <ReactDataGrid />
active cell so often. Therefore, the updates are throttled, at 100
milliseconds by default in order to keep the <ReactDataGrid />
snappy & responsive.activeIndexThrottle
prop.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 300 }
const defaultActiveCell = [4, 1]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', minWidth: 120, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', hedaer: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
activeCellThrottle={300}
defaultActiveCell={defaultActiveCell}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
defaultActiveIndex
.onActiveIndexChange(activeIndex)
is called, so you need to update the value of activeIndex
manually, since this is a controlled prop.<ReactDataGrid />
with keyboard navigation, as the active index is updated, the <ReactDataGrid />
is automatically scrolled to show the currently active index in the viewport.activeIndex
prop and onActiveIndexChange
callback prop to update the activeIndex
, if you're doing other compute intensive stuff on the render function, you might notice some performance degradation in the scenario when the user keeps arrow up/down
key pressed to quickly navigate to other records. If this is the case, it's better to use the uncontrolled defaultActiveIndex
prop instead to obtain better performance.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', minWidth: 100, defaultFlex: 1, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
const App = () => {
const [enableKeyboardNavigation, setEnableKeyboardNavigation] = useState(true);
const [activeIndex, setActiveIndex] = useState(2);
return (
<div>
<div>
<CheckBox checked={enableKeyboardNavigation} onChange={setEnableKeyboardNavigation}>
Enable keyboard navigation
</CheckBox>
</div>
<p>Current active index: {activeIndex}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
activeIndex={activeIndex}
onActiveIndexChange={setActiveIndex}
enableKeyboardNavigation={enableKeyboardNavigation}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 0
arrow up/down
) to change the active row index (see activeIndex
), the keyboard events can fire very quickly, which would be a bottleneck to update the <ReactDataGrid />
active cell so often. Therefore, the updates are throttled, at 100
milliseconds by default in order to keep the <ReactDataGrid />
snappy & responsive.activeCellThrottle
prop.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
const [activeIndex, setActiveIndex] = useState(1);
return (
<div>
<p>Active index: {activeIndex}</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
activeIndexThrottle={300}
activeIndex={activeIndex}
onActiveIndexChange={setActiveIndex}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
bool
default: true
false
, so groups can be split by default. Specify false
if you don't want to allow groups to be split.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, hedaer: 'Id', defaultVisible: false },
{ name: 'firstName', group: 'personalInfo', defaultFlex: 1, header: 'First Name' },
{ name: 'age', group: 'personalInfo', type: 'number', header: 'Age' },
{ name: 'email', group: 'contactInfo', defaultFlex: 1, header: 'Email' },
{ name: 'phone', group: 'contactInfo', header: 'Phone' },
{ name: 'city', group: 'location', header: 'City' },
{ name: 'streetName', group: 'street', defaultFlex: 1, header: 'Street name' },
{ name: 'streetNo', group: 'street', type: 'number', header: 'Street no' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Personal info' },
{ name: 'contactInfo', header: 'Contact info' },
{ name: 'location', header: 'Location' }
]
const dataSource = [
{ id: 0, firstName: 'Bob', age: 25, email: 'bobby@whocares.com', phone: '+7403 456 768', city: 'Paris', streetName: 'Champs Elysee', streetNo: 34 },
{ id: 1, firstName: 'Lynda', age: 38, email: 'lynda@idont.com', phone: '+7103 66 98 768', city: 'London', streetName: 'St Mary', streetNo: 14 },
{ id: 2, firstName: 'Richard', age: 18, email: 'richy@rich.com', phone: '+173 668 08 83', city: 'Manchester', streetName: 'St Robert', streetNo: 53 },
{ id: 3, firstName: 'Michael', age: 45, email: 'mike@mikey.com', phone: '+075 0628 156 74', city: 'Los Angeles', streetName: 'Greenfield', streetNo: 24 },
{ id: 4, firstName: 'Martin', age: 12, email: 'martin@bobson.com', phone: '+173 5624 675 462', city: 'San Jose', streetName: 'Patrick Ball', streetNo: 67 }
]
const gridStyle = { minHeight: 500 }
const App = () => {
const [allowGroupSplitOnReorder, setAllowGroupSplitOnReorder] = useState(false)
return (
<div>
<div style={{marginBottom: 20}}>
<p>Try dragging columns to break up some groups.</p>
<CheckBox checked={allowGroupSplitOnReorder} onChange={setAllowGroupSplitOnReorder}>
Allow group split on reorder
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
allowGroupSplitOnReorder={allowGroupSplitOnReorder}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool
default: false
false
.import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
import people from './people';
const gridStyle = {
minHeight: 750,
};
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
type: 'number',
defaultWidth: 80,
groupBy: false,
},
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultWidth: 150 },
{ name: 'city', header: 'City', defaultWidth: 150 },
{ name: 'age', header: 'Age', defaultWidth: 100, type: 'number' },
{ name: 'email', header: 'Email', defaultWidth: 150, defaultFlex: 1 },
];
const renderRowReorderProxy = ({data}) => {
return <div style={{ paddingLeft: 30 }}>ID: {data.id} - Name: {data.name}</div>
}
const App = () => {
const [defaultGroupBy, setDefaultGroupBy] = useState(['country']);
const [
allowRowReorderBetweenGroups,
setallowRowReorderBetweenGroups,
] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
theme="default-dark"
checked={allowRowReorderBetweenGroups}
onChange={setallowRowReorderBetweenGroups}
>
allowRowReorderBetweenGroups
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={defaultGroupBy}
columns={columns}
dataSource={people}
rowReorderColumn
allowRowReorderBetweenGroups={allowRowReorderBetweenGroups}
renderRowReorderProxy={renderRowReorderProxy}
/>
</div>
);
};
export default () => <App />;
Bool
default: false
Tab
key.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import TextInput from '../components/TextInput'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 400 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
];
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: '' },
{ name: 'age', operator: 'gte', type: 'number', value: null }
]
const App = () => {
const [allowRowTabNavigation, setAllowRowTabNavigation] = useState(true);
return (
<div>
<p>Navigate with Tab key</p>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={allowRowTabNavigation}
onChange={setAllowRowTabNavigation}
>
Row Tab Navigation
</CheckBox>
</div>
<TextInput style={{ marginBottom: 20, padding: 5, width: 250 }} type="text" autoFocus placeholder="Hit tab to navigate to grid" />
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
defaultFilterValue={filterValue}
allowRowTabNavigation={allowRowTabNavigation}
/>
<TextInput style={{ marginTop: 20, padding: 5, width: 250 }} type="text" defaultValue="Hit shift+tab to navigate to grid" />
</div>
);
}
export default () => <App />
Bool
default: true
<ReactDataGrid />
, when toggling the sort.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [sortable, setSortable] = useState(true)
const [allowUnsort, setAllowUnsort] = useState(true)
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={sortable}
onChange={setSortable}
>
Sortable grid
</CheckBox>
</div>
<div style={{marginBottom: 20}}>
<CheckBox
disabled={!sortable}
checked={allowUnsort}
onChange={setAllowUnsort}
>
Allow unsorted state
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
sortable={sortable}
allowUnsort={allowUnsort}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
true
, after an edit is complete, the grid will automatically receive focus.false
, the grid will not request focus after an edit is complete.onEditComplete
related prop.Bool
default: true
true
, after an edit is canceled, the grid will automatically receive focus.false
, the grid will not request focus after an edit is canceled.onEditCancel
related prop.Object
default: undefined
defaultCellSelection
.idProperty
for that row, followed by a comma and by the name/id of corresponding column: <idProperty value>,<column id or name>
: eg "id1,firstName"
.multiSelect=false
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, resizable: false },
{ name: 'name', header: 'Name', defaultFlex: 1, sortable: false },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultWidth: 100, type: 'number' }
]
const App = () => {
const [cellSelection, setCellSelection] = useState({"2,name": true, "2,city": true})
return (
<div>
<p>
Selected cells: {cellSelection.length == 0 ? 'none' : JSON.stringify(cellSelection)}.
</p>
<ReactDataGrid
idProperty="id"
cellSelection={cellSelection}
onCellSelectionChange={setCellSelection}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool|Object
default: undefined
<ReactDataGrid />
. When checkboxColumn=true
, the checkbox column with the default configuration will be displayed. However, you can use an object as the value for this prop, so you can configure any column properties just like for a normal <ReactDataGrid />
column.selected
(or the uncontrolled defaultSelected
) , unselected
(or the uncontrolled defaultUnselected
) and onSelectionChange
.unselected
(or the uncontrolled defaultUnselected
) only needs to be used when the <ReactDataGrid />
is configured with a remote dataSource
.checkboxOnlyRowSelect=true
to only update row selection when the user interacts with the checkboxes (so, it won't update when the row is clicked anywhere else).checkboxColumn.checkboxTabIndex
in order to assign a tabIndex
to the checkboxes in the column in order for the checkboxes to be reachable with tab-navigation.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 400, marginTop: 10 }
const defaultSelected = { 1: true, 3: true }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultFlex: 1, header: 'Email' }
]
const loadData = ({ skip, limit, sortInfo }) => {
return fetch(DATASET_URL+ '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo): '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const [checkboxOnlyRowSelect, setCheckboxOnlyRowSelect] = useState(true);
const [checkboxColumn, setCheckboxColumn] = useState(true);
const dataSource = useCallback(loadData, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={checkboxColumn} onChange={setCheckboxColumn}>
Checkbox column
</CheckBox>
</div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={checkboxOnlyRowSelect}
onChange={setCheckboxOnlyRowSelect}
>
Update row select using checkbox clicks only
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
key={'grid-' + checkboxOnlyRowSelect}
style={gridStyle}
checkboxColumn={checkboxColumn}
columns={columns}
checkboxOnlyRowSelect={checkboxOnlyRowSelect}
pagination
defaultSelected={defaultSelected}
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Number
default: null
checkboxColumn.checkboxTabIndex
in order to assign a tabIndex
to the checkboxes in the column in order for the checkboxes to be reachable with tab-navigation. The default value is null
, so column checkboxes do not participate in tab-navigation.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 400, marginTop: 10 }
const defaultSelected = {}
const columns = [
{ name: 'id', type: 'number', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultFlex: 1, header: 'Email' }
]
const loadData = ({ skip, limit, sortInfo }) => {
return fetch(DATASET_URL+ '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo): '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const [checkboxTabIndex, setCheckboxTabIndex] = useState(false);
const dataSource = useCallback(loadData, [])
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={checkboxTabIndex}
onChange={setCheckboxTabIndex}
>
Use tabIndex for checkboxes - so they can be reached with tab-navigation
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn={{
checkboxTabIndex: checkboxTabIndex ? 0 : null
}}
columns={columns}
pagination
defaultSelected={defaultSelected}
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
true
, row selection is only performed/updated when the user interacts with the selection checkboxes (see checkboxColumn
).checkboxColumn=true
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 400, marginTop: 10 }
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' }
]
const App = () => {
const [checkboxOnlyRowSelect, setCheckboxOnlyRowSelect] = useState(false);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={checkboxOnlyRowSelect}
onChange={setCheckboxOnlyRowSelect}
>
Update row select using checkbox clicks only
</CheckBox>
</div>
<ReactDataGrid
key={'grid-' + checkboxOnlyRowSelect}
idProperty="id"
style={gridStyle}
checkboxColumn
checkboxOnlyRowSelect={checkboxOnlyRowSelect}
columns={columns}
defaultSelected={true}
sortable={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
bool
default: true
dataSource
prop is updated, if this property is true
, any cached values set via setItemAt
or setItemPropertyAt
are cleared.String
default: "\t"
"\t"
.import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css';
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
minWidth: 80,
type: 'number',
},
{
name: 'name',
header: 'Name',
defaultFlex: 1,
minWidth: 150,
},
{
name: 'country',
header: 'Country',
defaultFlex: 1,
minWidth: 100,
defaultVisible: false,
},
{ name: 'city', header: 'City', defaultFlex: 1, minWidth: 150 },
{ name: 'age', header: 'Age', minWidth: 100, type: 'number' },
{ name: 'email', header: 'Email', defaultFlex: 1, minWidth: 150 },
{
name: 'student',
header: 'Student',
defaultFlex: 1,
render: ({ value }) => (value === true ? 'Yes' : 'No'),
},
];
const App = () => {
const [enableClipboard, setEnableClipboard] = useState(true);
const [
copySpreadsheetCompatibleString,
setCopySpreadsheetCompatibleString,
] = useState(true);
return (
<div>
<h3>Grid with clipboard separator</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableClipboard}
onChange={setEnableClipboard}
>Enable clipboard</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={copySpreadsheetCompatibleString}
onChange={setCopySpreadsheetCompatibleString}
>
Copy spreadsheet compatible string
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard={enableClipboard}
defaultCellSelection={{}}
style={gridStyle}
columns={columns}
dataSource={people}
clipboardSeparator=","
copySpreadsheetCompatibleString={copySpreadsheetCompatibleString}
/>
</div>
);
};
export default () => <App />;
Bool
default: true
true
, when collapsing an async node, it also collapses all its children, at any level of nesting, since when you re-expand the node, you want to display fresh data.loadNode
is specified - not available when loadNodeOnce
is used.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
const gridStyle = { minHeight: 550 }
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{
id: 1,
name: 'App store (async node)',
size: '4.5Mb',
nodes: null
},
{
id: 2,
name: 'iMovie (async node)',
size: '106Mb',
nodes: null
},
{
id: 3,
name: 'IRecall (async node)',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
nodes: [
{
id: 1,
name: 'Todo.md',
size: '2Kb'
},
{
id: 2,
name: 'Calendar.md',
size: '15.2Kb'
},
{ id: 3, name: 'Shopping list.csv',size: '20Kb' }
]
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{
id: 1,
name: 'Personal.xls',
size: '100Gb'
},
{ id: 2, name: 'Work.xls' }
]
},
{ id: 2, name: 'MacRestore.gzip' }
]
}
]
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const loadNode = ({ node, nodeProps }) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (nodeProps.depth >=4 ) {
resolve([
{ id: 1, name: 'First child of ' + node.name },
{ id: 2, name: 'Second child of ' + node.name }
])
}
resolve([
{ id: 1, name: 'First child of ' + node.name, nodes: null },
{ id: 2, name: 'Second child of ' + node.name, nodes: null }
])
}, 200)
})
}
const defaultExpandedNodes = { 1: true, '1/1': true }
const App = () => {
const [expandedNodes, setExpandedNodes] = useState(defaultExpandedNodes);
const [collapseChildrenOnAsyncNodeCollapse, setCollapseChildrenOnAsyncNodeCollapse] = useState(true);
const onExpandedNodesChange = useCallback(({ expandedNodes }) => {
setExpandedNodes(expandedNodes)
}, [])
return (
<div>
<h3>TreeGrid with async nodes</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={collapseChildrenOnAsyncNodeCollapse}
onChange={setCollapseChildrenOnAsyncNodeCollapse}
>
Collapse children on async node collapse
</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
loadNode={loadNode}
collapseChildrenOnAsyncNodeCollapse={collapseChildrenOnAsyncNodeCollapse}
onExpandedNodesChange={onExpandedNodesChange}
expandedNodes={expandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
<p>
Expanded nodes: {JSON.stringify(expandedNodes, null, 2)}
</p>
</div>
);
}
export default () => <App />
Object | true
default: undefined
defaultCollapsedGroups
.expandedGroups
/defaultExpandedGroups
"uk"
is a country shared by many records, and then grouped by city, with "London"
being the city value for many items, then "uk/London"
(a concatenation of the two, separated by groupPathSeparator
) is the key to be used in the collapsedGroups
object in order to render "London"
people as collapsed.groupPathSeparator
.expandedGroups
onGroupCollapseChange
is triggered (whether controlled collapsedGroups
or uncontrolled defaultCollapsedGroups
is used).collapsedGroups
, make sure you update the collapsedGroups
value when onGroupCollapseChange
is triggered, but also expandedGroups
collapsedGroups
and expandedGroups
should be both either controlled or uncontrolled.collapsedGroups=true
means all groups are collapsed (except those explicitly specified by expandedGroups
).expandedGroups=true
means all groups are expanded, except those explicitly specified in collapsedGroups
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultWidth: 140, header: 'Country' },
{ name: 'city', defaultWidth: 140, header: 'City' },
{ name: 'email', defaultWidth: 140, defaultFlex: 1, header: 'Email' }
]
const App = () => {
const [groupBy, setGroupBy] = useState(['country','city'])
const [collapsedGroups, setCollapsedGroups] = useState({ 'uk/London': true, 'usa': true })
const [expandedGroups, setExpandedGroups] = useState(true)
const onGroupCollapseChange = useCallback((collapsedGroups, expandedGroups) => {
setCollapsedGroups(collapsedGroups)
setExpandedGroups(expandedGroups)
}, [])
return (
<div>
<p>
Collapsed groups: {JSON.stringify(Object.keys(collapsedGroups))}.
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
collapsedGroups={collapsedGroups}
expandedGroups={expandedGroups}
onGroupCollapseChange={onGroupCollapseChange}
defaultGroupBy={groupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
expandedRows=true
!<ReactDataGrid />
should be rendered collapsed, when all other rows are expanded (expandedRows=true
). This is a controlled prop. For the uncontrolled version, see defaultCollapsedRows
renderRowDetails
in order to render the row details on expand.true
.onExpandedRowsChange
to be notified when the expanded/collapsed rows change.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const App = () => {
const [expandedRows, setExpandedRows] = useState(true);
const [collapsedRows, setCollapsedRows] = useState({ 1: true, 2: true });
const onExpandedRowsChange = useCallback(({ expandedRows, collapsedRows }) => {
setExpandedRows(expandedRows);
setCollapsedRows(collapsedRows);
}, [])
return (
<div>
<div>
<Button onClick={() => setExpandedRows(true)} style={{ marginRight: 10 }}>
Expand all
</Button>
<Button onClick={() => setExpandedRows({})}>
Collapse all
</Button>
</div>
<p>
Expanded rows: {expandedRows == null ? 'none' : JSON.stringify(expandedRows, null, 2)}.
</p>
{expandedRows === true ?<p>
Collapsed rows: {collapsedRows == null ? 'none' : JSON.stringify(collapsedRows, null, 2)}.
</p> : null}
<ReactDataGrid
idProperty="id"
expandedRows={expandedRows}
collapsedRows={collapsedRows}
onExpandedRowsChange={onExpandedRowsChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String|HTMLElement|Boolean|Fn
default: undefined
<ReactDataGrid />
constrains the column context menu to the <ReactDataGrid />
node.true
(in which case, it's constrained to document.documentElement
), the result of a call to getBoundingClientRect
or a function returning any of the mentioned types.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
];
const App = () => {
return (
<div>
<p>Column menu constrained to document.documentElement</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnContextMenuConstrainTo={true}
columnContextMenuPosition={"fixed"}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
position: absolute
.columnContextMenuConstrainTo
to make the menu constrained to a different element - in which case, you should use "fixed"
positioning.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
];
const App = () => {
return (
<div>
<p>Column menu constrained to document.documentElement</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnContextMenuConstrainTo={true}
columnContextMenuPosition={"fixed"}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
<ReactDataGrid />
columns. If a column specifies a defaultWidth
, that value overrides columnDefaultWidth
.columns.width
and columns.defaultWidth
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ name: 'name', header: 'Name' },
{ name: 'email', header: 'Email' },
{ name: 'country', header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City' },
{ name: 'age', header: 'Age', type: 'number' }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
All columns have a default width of 250px
</div>
<ReactDataGrid
idProperty="id"
columnDefaultWidth={250}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
<ReactDataGrid />
column headers. Since this prop defaults to false
, browser text selection is disabled in headers. Set this to true
to enable text selection in the <ReactDataGrid />
headers.columns.headerUserSelect
, at column-level.<ReactDataGrid />
cells, use columnUserSelect
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name - double click to test selection', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1 },
]
const App = () => {
const [columnHeaderUserSelect, setColumnHeaderUserSelect] = useState(true);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={columnHeaderUserSelect}
onChange={setColumnHeaderUserSelect}
>
Enable browser text selection in column headers
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnHeaderUserSelect={columnHeaderUserSelect}
columns={columns}
dataSource={people}
sortable={false}
/>
</div>
);
}
export default () => <App />
Number
default: 50
<ReactDataGrid />
columns. If a column specifies a maxWidth
, that value overrides columnMaxWidth
.resizable
columns cannot be user-resized to have a bigger size, neither can flexible columns stretch more that the specified maximum width.columnMinWidth
.columns.maxWidth
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 80 },
{ name: 'firstName', header: 'Name maxWidth 200', defaultFlex: 2 },
{
name: 'country',
header: 'Country maxWidth 250',
maxWidth: 250,
defaultFlex: 3,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultFlex: 1 }
];
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMaxWidth={200}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 50
<ReactDataGrid />
columns. If a column specifies a minWidth
, that value overrides columnMinWidth
.resizable
columns cannot be user-resized to be smaller than the specified minimum size, neither can flexible columns shrink to be smaller than the specified min-width.columnMaxWidth
.columns.minWidth
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', minWidth: 40, maxWidth: 40 },
{ name: 'firstName', header: 'Name default minWidth', minWidth: 200, defaultFlex: 1 },
{
name: 'country',
header: 'Country default minWidth',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', header: 'Age default minWidth' }
];
const App = () => {
return (
<div>
<p>Default column minWidth=150</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
columnMinWidth={150}
/>
</div>
);
}
export default () => <App />
String[]
default: undefined
column.name
or column.id
).<ReactDataGrid />
is configured with reorderable columns, column order should be updated when dropping a column to a new position. Make sure you update the columnOrder
value by using onColumnOrderChange(columnOrder)
prop, which gives you the new column order.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 140, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', minWidth: 80, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' },
{ name: 'email', minWidth: 80, defaultFlex: 1, draggable: false, header: 'Email - not draggable' }
]
const App = () => {
const [columnOrder, setColumnOrder] = useState(['id', 'name', 'age', 'city', 'email']);
const [reorderColumns, setReorderColumns] = useState(true);
return (
<div>
<div>
<CheckBox checked={reorderColumns} onChange={setReorderColumns}>
Enable column reordering
</CheckBox>
</div>
<p>Current column order: {JSON.stringify(columnOrder)}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
reorderColumns={reorderColumns}
columnOrder={columnOrder}
onColumnOrderChange={setColumnOrder}
columns={columns}
dataSource={people}
sortable={false}
/>
</div>
);
}
export default () => <App />
Number
default: 20
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultFlex: 1 },
{ name: 'firstName', header: 'Name', defaultWidth: 280 },
{ name: 'email', header: 'Email', defaultWidth: 280 },
{ name: 'country', header: 'Country', defaultWidth: 280,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultWidth: 280 },
{ name: 'age', header: 'Age', defaultWidth: 280 }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Try to reorder columns when there is a horizontal scrollbars - the grid will scroll horizontally very slow, since columnReorderScrollByAmount is configured to be 5 in this example.
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
columnReorderScrollByAmount={5}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object[]
default: undefined
<ReactDataGrid />
.name
- a column name. Will match a property from the items in the dataSource
.id
- if the column doesn't have a name
it needs to have a unique id.header
- will be displayed in the column header. Can be any valid React.Node
or a function. If not present, column.name
will be used (after it's upper-cased and humanized) as the column header.render
- a render function in order to perform custom rendering.textAlign
- a value for aligning column cell contents. If column.headerAlign
is undefined, the column.textAlign
will also be used for header alignment.headerAlign
- a value for aligning column header
contents.<ReactDataGrid />
, we treat props as immutable and only update the <ReactDataGrid />
when you pass different props.columns
array when rendering the <ReactDataGrid />
, instead of building the columns array in the render function of your app and passing it new each time to the <ReactDataGrid />
.columns
at each render will slow down the rendering performance of the <ReactDataGrid />
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultWidth: 100,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
defaultFlex: 2,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object|Fn(cellProps): Object
default: undefined
className
, style
or onClick
.cellDOMProps
and return an object with DOM props that will get applied on the rendered <div />
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const countryStyle = {
color: '#7986cb'
}
const redColor = {
color: '#ef9a9a'
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ name: 'name', defaultFlex: 1, minWidth: 100, header: 'Name', cellDOMProps: { style : redColor } },
{ name: 'country', cellDOMProps: (cellProps) => ({ style: countryStyle }), defaultFlex: 1, minWidth: 100, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 100, header: 'City' },
{ name: 'age', minWidth: 150, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ data, value, rowIndex, column, dataSourceArray })
default: undefined
column.colspan
and column.rowspan
functions you have access to the data you need to make those truly dynamic.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
defaultWidth: 50,
type: 'number',
},
{
name: 'name',
defaultFlex: 1,
header: 'Name',
colspan: ({ data, column, columns }) => {
// make every other row cell expand for 2 columns if the next column is the age column
if (data.id % 2 && columns[column.computedVisibleIndex + 1] && columns[column.computedVisibleIndex + 2].name === 'age') {
return 2
}
return 1
}
},
{
name: 'country',
header: 'Country',
defaultFlex: 1
},
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<h3>Colspan example</h3>
<ReactDataGrid
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
column.flex
.column.minWidth
and column.maxWidth
can be configured for both fixed and flexible columns in order to ensure some minimum or maximum dimensions are always respected.reservedViewportWidth
.column.flex
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 70 },
{ name: 'firstName', header: 'First Name', defaultFlex: 3 },
{
name: 'country',
header: 'Country',
defaultFlex: 2,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<p>
Columns with defaultFlex values of 3, 2, and 1.
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
bool
default: false
<ReactDataGrid />
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'name', header: 'Name - defaultLocked', defaultLocked: true, defaultWidth: 200},
{ name: 'email', header: 'Email', defaultWidth: 250 },
{ name: 'city', header: 'City', defaultWidth: 250 },
{ name: 'country', header: 'Country', defaultWidth: 250,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultWidth: 250 },
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Make sure the columns do not fit the window, to force the horizontal scroll
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
'asc' | 'desc'
default: undefined
defaultSortingDirection
is set to 'asc'
, the default sorting behaviour is to sort in ascending order, i.e. at the first click on the header cell, the column will be sorted in ascending order. When defaultSortingDirection
is set to 'desc'
, the default behavior is to sort in descending order.import React from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 };
const columns = [
{ name: 'id', header: 'Id', defaultWidth: 80, defaultVisible: false },
{
name: 'name',
sortable: false,
header: 'Name (column not sortable)',
defaultFlex: 1,
},
{
name: 'age',
header: 'Age',
type: 'number',
defaultFlex: 1,
defaultSortingDirection: 'desc'
},
];
const dataSource = [
{ name: 'Little Johny', age: 8, id: 0 },
{ name: 'John Grayner', age: 35, id: 1 },
{ name: 'Mary Stones', age: 35, id: 2 },
{ name: 'Robert Fil', age: 17, id: 3 },
{ name: 'Bob Margin', age: 17, id: 4 },
{ name: 'Hillary Wilson', age: 53, id: 5 },
{ name: 'Franklin Richardson', age: 37, id: 6 },
];
const App = () => {
return (
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={dataSource}
defaultSortingDirection="asc"
/>
);
};
export default () => <App />;
Bool
default: undefined
false
if you want to hide a column. If not specified (so column.defaultVisible
is undefined), the column will be visible.visible
.visible
prop value when onColumnVisibleChange({ column, visible })
is triggered.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', type: 'number', defaultWidth: 80, defaultVisible: false },
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultVisible: false, minWidth: 150 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Id column and email column is not visible by default. You can enable it from the header menu.
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
column.width
.column.minWidth
and column.maxWidth
.columnDefaultWidth
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', heder: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', defaultWidth: 210, header: 'Name, defaultWidth=210' },
{ name: 'city', defaultFlex: 1, header: 'City', minWidth: 110 },
{ name: 'email', header: 'Email, defaultWidth=210', defaultWidth: 210 },
{ name: 'country', header: 'Country', defaultFlex: 1, minWidth: 100,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', minWidth: 70, defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = (state) => {
return [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultFlex: 1, draggable: state.draggable, header: 'First Name' },
{ name: 'country', defaultFlex: 1, draggable: state.draggable, header: 'Country' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age', draggable: state.draggable, header: 'Age' }
]
}
const App = () => {
const [draggable, setDraggable] = useState(true)
const [columns, setColumns] = useState(getColumns({ draggable }))
const onDraggableChange = useCallback((value) => {
setDraggable(value)
setColumns(getColumns({ draggable: value }))
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={draggable} onChange={onDraggableChange}>
Draggable
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool|Function(editValue, cellProps)
default: undefined
editable
is a function) should have inline edit enabled or not.Promise
. In case a Promise
is returned, if it is rejected or resolved with false
, the cell is not editable. If the returned Promise
is resolved with true
, the cell is editable.editable
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = (state) => {
return [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, editable: state.editable, header: 'Name' },
{ name: 'country', defaultFlex: 1, minWidth: 80, header: 'Country' },
{ name: 'city', defaultFlex: 1, editable: state.editable, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
}
const App = () => {
const [editable, setEditable] = useState(true)
const [dataSource, setDataSource] = useState(people)
const [columns, setColumns] = useState(getColumns({ editable }))
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
const onEditableChange = useCallback((editable) => {
setEditable(editable)
setColumns(getColumns({ editable }))
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={editable} onChange={onEditableChange}>
Make Name and City columns editable
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
React.Node
default: undefined
<ReactDataGrid />
supports this feature, so you can specify your own column.editor
, which should be a React Component.column.editor
, nor column.renderEditor
are specified, a default text editor is used for editing.column.editor
or column.renderEditor(editorProps)
it is important that you call editorProps.onChange
and editorProps.onComplete
accordingly, when the user changes the value in the editor and when it completes/cancels the edit. It's also important that you call editorProps.onTabNavigation(complete: bool, direction)
so that the user can navigate from the editor to other editors in the row (either backwards or forwards - direction should be -1
for backwards and 1
for forwards).import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumericEditor from '@inovua/reactdatagrid-community/NumericEditor'
import BoolEditor from '@inovua/reactdatagrid-community/BoolEditor'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', type: 'number', defaultFlex: 1, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'age', defaultFlex: 1, editor: NumericEditor, header: 'Age' },
{
name: 'student',
header: 'Student',
defaultFlex: 1,
render: ({ value }) => value? 'Yes':'No',
editor: BoolEditor,
editorProps: {
style: { background: '#444d65' }
}
},
{ name: 'country', defaultFlex: 1, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' }
]
const initialData = people.map(p=>Object.assign({}, p))
const App = () => {
const [dataSource, setDataSource] = useState(initialData)
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
return (
<div style={{marginBottom: 20}}>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
editable={true}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
supports this feature, so you can specify your own column.editor
, which should be a React Component. If you simply want to override the props of the default column editor, you can use editorProps
to do so.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumericEditor from '@inovua/reactdatagrid-community/NumericEditor'
import BoolEditor from '@inovua/reactdatagrid-community/BoolEditor'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ name: 'name', defaultFlex: 1, minWidth: 200, maxWidth: 300, header: 'Name' },
{ name: 'age', defaultFlex: 1, type: 'number', editor: NumericEditor, header: 'Age' },
{ name: 'student',
header: 'Student',
width: 100,
editor: BoolEditor,
render: ({ value }) => value? 'Yes':'No',
editorProps: {
style: { background: 'rgba(121, 134, 203, 0.25)' }
}
},
{ name: 'country', defaultFlex: 1, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' }
]
const App = () => {
const [dataSource, setDataSource] = useState(people);
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data);
}, [dataSource])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
editable={true}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
import React, { useState }from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumberFilter from '@inovua/reactdatagrid-community/NumberFilter'
import SelectFilter from '@inovua/reactdatagrid-community/SelectFilter'
import DateFilter from '@inovua/reactdatagrid-community/DateFilter'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 600 }
const COUNTRIES = {
ca: 'Canada',
uk: 'United Kingdom',
usa: 'United States of America'
}
const countries = people.reduce((countries, p) => {
if (countries.filter(c => c.id == p.country).length) {
return countries
}
countries.push({
id: p.country,
label: COUNTRIES[p.country] || p.country
})
return countries
}, []);
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: '' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 },
{ name: 'city', operator: 'startsWith', type: 'string', value: '' },
{
name: 'birthDate',
operator: 'before',
type: 'date',
value: ''
},
{ name: 'country', operator: 'eq', type: 'select', value: 'ca' }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, enableColumnFilterContextMenu: true },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number', filterEditor: NumberFilter },
{
name: 'country',
header: 'Country',
defaultFlex: 1,
filterEditor: SelectFilter,
filterEditorProps: {
placeholder: 'All',
dataSource: countries
},
render: ({ value })=> flags[value]? flags[value]: value
},
{
name: 'birthDate',
header: 'Bith date',
defualtFlex: 1,
minWidth: 200,
enableColumnFilterContextMenu: false,
filterEditor: DateFilter,
filterEditorProps: (props, { index }) => {
// for range and notinrange operators, the index is 1 for the after field
return {
dateFormat: 'MM-DD-YYYY',
cancelButton: false,
highlightWeekends: false,
placeholder: index == 1 ? 'Created date is before...': 'Created date is after...'
}
},
render: ({ value, cellProps }) => {
return moment(value).format('MM-DD-YYYY')
}
},
{ name: 'city', header: 'City', defaultFlex: 1 },
];
const App = () => {
const [enableColumnFilterContextMenu, setEnableColumnFilterContextMenu] = useState(true);
return (
<div>
<h3>Grid with filter context menu control</h3>
<p>
The 'name' column has "enableColumnFilterContextMenu" setted to 'true'
and 'birthDate' has "enableColumnFilterContextMenu" setted to 'false'
at the column level.
</p>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableColumnFilterContextMenu}
onChange={setEnableColumnFilterContextMenu}
>Enable column filter context menu</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
enableColumnFilterContextMenu={enableColumnFilterContextMenu}
/>
</div>
)
}
export default () => <App />
Bool
default: undefined
import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css';
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people';
import flags from './flags';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultWidth: 60,
type: 'number',
},
{ name: 'name', header: 'Name', defaultWidth: 100 },
{
name: 'country',
header: 'Country',
defaultWidth: 100,
render: ({ value }: { value: string }) =>
flags[value] ? flags[value] : value,
},
{
name: 'city',
header: 'City',
defaultWidth: 120,
enableColumnHover: false
},
{
name: 'age',
header: 'Age',
defaultWidth: 100,
type: 'number',
enableColumnHover: true
},
];
const App = () => {
const [enableColumnHover, setEnableColumnHover] = useState(true)
return (
<div>
<h3>Grid with hover disabled on 'city' column and 'age' column enabled</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableColumnHover}
onChange={setEnableColumnHover}
>Enable column hover</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
style={gridStyle}
columns={columns}
dataSource={people}
enableColumnHover={enableColumnHover}
/>
</div>
);
};
export default () => <App />;
Bool|Number
default: 250
false
or 0
, no delay is used.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ name: 'name', defaultFlex: 1, filterDelay: 500, hedaer: 'Name' },
{ name: 'country', defaultFlex: 1,
hedaer: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
React.Component
default: undefined
<ReactDataGrid />
, but have to be explicitly imported. Here is the list of available imports:@inovua/reactdatagrid-enterprise/StringFilter
@inovua/reactdatagrid-community/NumberFilter
@inovua/reactdatagrid-community/BoolFilter
@inovua/reactdatagrid-community/SelectFilter
@inovua/reactdatagrid-community/DateFilter
React.Component
should have a setValue(value)
public method to allow setting the filter value imperatively.render
prop (which is a function), that accepts any React.Node
as a parameter. So the filter editor should return the result of the this.props.render(any jsx)
call on its render
method.StringFilter
editor.import React from 'react';
import debounce from 'lodash.debounce';
class StringFilter extends React.Component {
constructor(props) {
super(props);
const { filterValue } = props;
this.state = {
value: filterValue ? filterValue.value : ''
};
this.onChange = this.onChange.bind(this);
this.onValueChange = this.onValueChange.bind(this);
if (props.filterDelay && props.filterDelay >= 1) {
this.onValueChange = debounce(this.onValueChange, props.filterDelay, {
leading: false,
trailing: true
});
}
}
onChange(event) {
const value = event.target.value;
this.onValueChange(value);
this.setValue(value);
}
setValue(value) {
this.setState({
value
});
}
onValueChange(value) {
this.props.onChange(Object.assign({}, this.props.filterValue, { value }));
}
render() {
let { filterValue, readOnly, style } = this.props;
const inputProps = {
readOnly,
style: Object.assign({}, { minWidth: 0 }, style)
};
if (filterValue) {
inputProps.value = this.state.value;
}
return this.props.render(
<input
type="text"
onChange={this.onChange}
className="inovua-react-datagrid__column-header__filter inovua-react-datagrid__column-header__filter--string"
{...inputProps}
/>
);
}
}
setValue
method, to be called when people use the column header menu to clear the filter value, or when clearColumnFilter
is called by the user.render
function:render(){
// ... other code here
return this.props.render(
<input
type="text"
onChange={this.onChange}
className="..."
{...inputProps}
/>
);
}
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumberFilter from '@inovua/reactdatagrid-community/NumberFilter'
import BoolFilter from '@inovua/reactdatagrid-community/BoolFilter'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterTypes = Object.assign({}, ReactDataGrid.defaultProps.filterTypes, {
country: {
name: 'country',
operators: [
{
name: 'europe',
fn: ({ value, filterValue, data }) => {
if (filterValue == null) {
return true
}
const isInEurope = value != 'usa' && value != 'ca'
return filterValue ?
isInEurope :
!isInEurope
}
}
]
}
})
const filterValue = [
{ name: 'country', operator: 'europe', type: 'country', value: true },
{ name: 'age', operator: 'gte', type: 'number', minWidth: 200, value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, maxWidth: 100, type: 'number' },
{ name: 'name', defaultFlex: 1, maxWidth: 200, header: 'Name' },
{ name: 'country',
header: 'Country - with Europe checkbox filter',
defaultFlex: 1,
filterEditor: BoolFilter,
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, minWidth: 200, header: 'City' },
{ name: 'age', minWidth: 150, type: 'number', filterEditor: NumberFilter, header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
filterTypes={filterTypes}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object|Function
default: undefined
filterEditor
.inrange/notinrange
editors.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumberFilter from '@inovua/reactdatagrid-community/NumberFilter'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, maxWidth: 100, type: 'number' },
{
name: 'name',
header: 'Name',
defaultFlex: 1,
minWidth: 200, maxWidth: 300,
filterEditorProps: { style: { background: 'rgba(121, 134, 203, 0.25)' } }
},
{ name: 'age', defaultFlex: 1, type: 'number', filterEditor: NumberFilter, header: 'Age' },
{ name: 'country', defaultFlex: 1, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
<p>Delete the filters if you want to show all data. You can click the configure icon and then "Clear All"</p>
</div>
);
}
export default () => <App />
Fn({ className: String, filterValue: String })
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumberFilter from '@inovua/reactdatagrid-community/NumberFilter'
import SelectFilter from '@inovua/reactdatagrid-community/SelectFilter'
import DateFilter from '@inovua/reactdatagrid-community/DateFilter'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 600 }
const filterIcon = className => {
return (
<svg
className={className}
enable-background="new 0 0 24 24"
height="24px"
viewBox="0 0 24 24"
width="24px"
>
<g>
<path d="M0,0h24 M24,24H0" fill="none" />
<path d="M7,6h10l-5.01,6.3L7,6z M4.25,5.61C6.27,8.2,10,13,10,13v6c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1v-6 c0,0,3.72-4.8,5.74-7.39C20.25,4.95,19.78,4,18.95,4H5.04C4.21,4,3.74,4.95,4.25,5.61z" />
<path d="M0,0h24v24H0V0z" fill="none" />
</g>
</svg>
);
};
const COUNTRIES = {
ca: 'Canada',
uk: 'United Kingdom',
usa: 'United States of America'
}
const countries = people.reduce((countries, p) => {
if (countries.filter(c => c.id == p.country).length) {
return countries
}
countries.push({
id: p.country,
label: COUNTRIES[p.country] || p.country
})
return countries
}, []);
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: '' },
{ name: 'age', operator: 'gte', type: 'number', value: null },
{ name: 'city', operator: 'startsWith', type: 'string', value: '' },
{
name: 'birthDate',
operator: 'before',
type: 'date',
value: ''
},
{ name: 'country', operator: 'eq', type: 'select', value: null }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{
name: 'name',
header: 'Name',
defaultFlex: 1,
filterEditorProps: {
placeholder: 'Name',
renderSettings: ({ className }) => filterIcon(className)
},
},
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number', filterEditor: NumberFilter },
{
name: 'country',
header: 'Country',
defaultFlex: 1,
filterEditor: SelectFilter,
filterEditorProps: {
placeholder: 'All',
dataSource: countries,
renderSettings: ({ className }) => filterIcon(className)
},
render: ({ value })=> flags[value]? flags[value]: value
},
{
name: 'birthDate',
header: 'Bith date',
defualtFlex: 1,
minWidth: 200,
filterEditor: DateFilter,
filterEditorProps: (props, { index }) => {
// for range and notinrange operators, the index is 1 for the after field
return {
dateFormat: 'MM-DD-YYYY',
cancelButton: false,
highlightWeekends: false,
renderSettings: ({ className }) => filterIcon(className),
placeholder: index == 1 ? 'Created date is before...': 'Created date is after...'
}
},
render: ({ value, cellProps }) => {
return moment(value).format('MM-DD-YYYY')
}
},
{ name: 'city', header: 'City', defaultFlex: 1 },
];
const App = () => {
console.log('people', people)
return (
<div>
<h3>Grid with custom filter icon on Name and Country columns</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
<p>Delete the filters if you want to show all data. You can click the configure icon and then "Clear All"</p>
</div>
)
}
export default () => <App />
String
default: undefined
filterValue.type
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumberFilter from '@inovua/reactdatagrid-community/NumberFilter'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, maxWidth: 100, type: 'number' },
{ name: 'name', defaultFlex: 1, minWidth: 200, maxWidth: 300, filterType: 'string', header: 'Name' },
{ name: 'age', defaultFlex: 1, type: 'number', filterEditor: NumberFilter, header: 'Age' },
{ name: 'country', defaultFlex: 1, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
<p>Delete the filters if you want to show all data. You can click the configure icon and then "Clear All"</p>
</div>
);
}
export default () => <App />
Number
default: undefined
column.defaultFlex
.column.minWidth
and column.maxWidth
can be configured for both fixed and flexible columns in order to ensure some minimum or maximum dimensions are always respected.reservedViewportWidth
.column.defaultFlex
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const defaultColumns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', flex: 3 },
{
name: 'country',
header: 'Country',
flex: 2,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', flex: 1 }
]
const App = () => {
const [columns, setColumns] = useState(defaultColumns)
const onBatchColumnResize = useCallback((batchColumnInfo) => {
const colsMap = batchColumnInfo.reduce((acc, colInfo) => {
const { column, flex} = colInfo
acc[column.name] = { flex }
return acc
}, {})
const cols = columns.map(c => {
return Object.assign({}, c, colsMap[c.name])
})
setColumns(cols)
}, [columns])
return (
<div>
<p>
Columns with flex values of 3, 2, and 1.
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
onBatchColumnResize={onBatchColumnResize}
/>
</div>
);
}
export default () => <App />
Function(editValue, cellProps)
default: undefined
Promise
. The resolve value of the returned Promise
will be the actual value used when starting the edit.editValue
passed to the function is the current value in the cell.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = (state) => {
return [
{ name: 'id', type: 'number', defaultWidth: 80, editable: false, header: 'Id', defaultVisible: false },
{ name: 'name', header: 'Name', defaultFlex: 1, getEditStartValue: (value) => Promise.resolve(value + '!!!') },
{ name: 'country', defaultFlex: 1, minWidth: 80, header: 'Country' },
{ name: 'city', header: 'City', defaultFlex: 1, getEditStartValue: (value) => value + '!!!' },
{ name: 'age', header: 'Age', minWidth: 80, type: 'number', getEditStartValue: (value) => Promise.resolve(value + '!!!') }
]
}
const App = () => {
const [editable, setEditable] = useState(true)
const [dataSource, setDataSource] = useState(people)
const [columns, setColumns] = useState(getColumns({ editable }))
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
return (
<div>
<p>NAME, CITY and AGE columns start the edit by adding a "!!!" at the end of the actual value</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
editable
onEditComplete={onEditComplete}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
String
default: undefined
column.group
if you want a specific column to belong to a group.allowGroupSplitOnReorder
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, hedaer: 'Id', defaultVisible: false },
{ name: 'firstName', group: 'personalInfo', defaultFlex: 1, header: 'First Name' },
{ name: 'age', group: 'personalInfo', type: 'number', header: 'Age' },
{ name: 'email', group: 'contactInfo', defaultFlex: 1, header: 'Email' },
{ name: 'phone', group: 'contactInfo', header: 'Phone' },
{ name: 'city', group: 'location', header: 'City' },
{ name: 'streetName', group: 'street', defaultFlex: 1, header: 'Street name' },
{ name: 'streetNo', group: 'street', type: 'number', header: 'Street no' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Personal info' },
{ name: 'contactInfo', header: 'Contact info' },
{ name: 'location', header: 'Location' }
]
const dataSource = [
{ id: 0, firstName: 'Bob', age: 25, email: 'bobby@whocares.com', phone: '+7403 456 768', city: 'Paris', streetName: 'Champs Elysee', streetNo: 34 },
{ id: 1, firstName: 'Lynda', age: 38, email: 'lynda@idont.com', phone: '+7103 66 98 768', city: 'London', streetName: 'St Mary', streetNo: 14 },
{ id: 2, firstName: 'Richard', age: 18, email: 'richy@rich.com', phone: '+173 668 08 83', city: 'Manchester', streetName: 'St Robert', streetNo: 53 },
{ id: 3, firstName: 'Michael', age: 45, email: 'mike@mikey.com', phone: '+075 0628 156 74', city: 'Los Angeles', streetName: 'Greenfield', streetNo: 24 },
{ id: 4, firstName: 'Martin', age: 12, email: 'martin@bobson.com', phone: '+173 5624 675 462', city: 'San Jose', streetName: 'Patrick Ball', streetNo: 67 }
]
const gridStyle = { minHeight: 500 }
export default () => <div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
/>
</div>
Bool
default: undefined
column.groupBy=false
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 50 },
{ name: 'firstName', header: 'First Name', defaultWidth: 150 },
{ name: 'lastName', header: 'Last Name', defaultWidth: 150 },
{ name: 'email', header: 'Email', groupBy: false, defaultWidth: 150 },
{
name: 'permissionToCall',
header: 'Permission to call',
defaultWidth: 200,
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value ? 'Can be called' : 'Cannot be called'
}
];
const loadData = ({ skip, limit, sortInfo, groupBy }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo) : '') + (groupBy && groupBy.length ? '&groupBy=' + groupBy : '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const [stickyGroupRows, setStickyGroupRows] = useState(false);
const [groupBy, setGroupBy] = useState([]);
const dataSource = useCallback(loadData, [])
return (
<div>
<p><Button onClick={() => setGroupBy(['permissionToCall', 'lastName'])}>Group by permissionToCall and lastName</Button></p>
<p><Button onClick={() => setGroupBy([])}>Remove grouping</Button></p>
<p>In this example, you cannot group by id or email.</p>
<div style={{marginBottom: 20}}>
<CheckBox
checked={stickyGroupRows}
onChange={setStickyGroupRows}
>
Use sticky group rows
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
stickyGroupRows={stickyGroupRows}
groupBy={groupBy}
onGroupByChange={setGroupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
{ initialValue: any, reducer: (acc, current) => any, complete: (value, arr) => any}
default: undefined
groupSummaryReducer
object has the following shape:initialValue
- the initial value to be used for the summary computation - generally a number/string/etcreducer(accumulator, currentValue)
- the reducer function - basically computes the summary from the accumulated value (at first call, this will equal the initialValue
) and the current value for the item at which we are doing the computationcomplete(accumulatedValue, array)
- can be used for doing one last computation at the end of the iteration - for example useful for computing the average of a value. The first argument is the accumulated value, while the second is the array on which the summary was computed againstgroupSummaryReducer
.render
functions defined for columns, when the group row is being rendered, you have access to the group summaries via the data.groupColumnSummary
object, which has a key for each of the columns that define a column.groupSummaryReducer
.data.groupSummary
is available in the render function in case you have definedgroupSummaryReducer
at grid-level.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
const gridStyle = { minHeight: 600, marginTop: 10 }
let cities;
const sum = (a,b) => a + b;
const columns = [
{ name: 'name', defaultFlex: 1, header: 'City' },
{ name: 'country', defaultFlex: 1, header: 'Country' },
{
name: 'population',
type: 'number',
defaultFlex: 1,
header: 'Population',
render: ({ value, data, cellProps: {summaryProps} }) => {
// if you want to custom-render the summary value for this column
// you can do so
return summaryProps ? (
<React.Fragment>
<b>Total: </b>
{value}{' '}
</React.Fragment>
) : (
value
);
},
groupSummaryReducer: {
initialValue: 0,
reducer: sum,
},
},
];
const App = () => {
const [showGroupSummaryRow, setShowGroupSummaryRow] = useState(true);
const renderGroupTitle = useCallback((value, { data }) => {
let summary = null;
if (data.groupColumnSummary) {
summary = (
<b> Total Population: {data.groupColumnSummary.population}</b>
);
}
return (
<div>
{value}
{summary}
</div>
);
}, [])
return (
<div>
<h3>Group summary row position demo</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showGroupSummaryRow}
onChange={setShowGroupSummaryRow}
>
Show group summary row
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showGroupSummaryRow={showGroupSummaryRow}
columns={columns}
dataSource={cities}
defaultGroupBy={['country']}
renderGroupTitle={renderGroupTitle}
/>
</div>
);
}
cities = [
{
id: 'ny',
country: 'USA',
name: 'New York City',
population: 1000
},
{
id: 'la',
country: 'USA',
name: 'Los Angeles',
population: 150
},
{
id: 'paris',
country: 'France',
name: 'Paris',
population: 2000
},
{
id: 'london',
name: 'London',
country: 'UK',
population: 3000
},
{
id: 'SF',
name: 'San Francisco',
country: 'USA',
population: 3900
},
{
id: 'ly',
name: 'Lyon',
country: 'France',
population: 980
},
{
id: 'ma',
name: 'Manchester',
country: 'UK',
population: 2000
}
]
export default () => <App />;
Fn(value)
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 600 }
const europeCities = {
Paris: true,
London: true,
Manchester: true
}
const cityToString = (city) => {
if (!city) {
return 'unknown'
}
if (city.name in europeCities) {
return 'europe'
}
return 'us'
}
const dataSource = [
{ id: 0, firstName: 'Bob', age: 25, email: 'bobby@whocares.com', phone: '+7403 456 768', city: {name: 'Paris'}, streetName: 'Champs Elysee', streetNo: 34 },
{ id: 1, firstName: 'Lynda', age: 38, email: 'lynda@idont.com', phone: '+7103 66 98 768', city: {name: 'London'}, streetName: 'St Mary', streetNo: 14 },
{ id: 2, firstName: 'Richard', age: 18, email: 'richy@rich.com', phone: '+173 668 08 83', city: {name: 'Manchester'}, streetName: 'St Robert', streetNo: 53 },
{ id: 3, firstName: 'Michael', age: 45, email: 'mike@mikey.com', phone: '+075 0628 156 74', city: {name: 'Los Angeles'}, streetName: 'Greenfield', streetNo: 24 },
{ id: 4, firstName: 'Martin', age: 12, email: 'martin@bobson.com', phone: '+173 5624 675 462', city: {name: 'San Jose'}, streetName: 'Patrick Ball', streetNo: 67 }
]
const columns = [
{ name: 'id', type: 'number', minWidth: 50, header: 'Id', defaultVisible: false },
{ name: 'city',
header: 'City',
minWidth: 100,
flex: 1,
groupToString: cityToString,
render: ({ value: city }) => city ? city.name : null,
renderGroupTitle: (city) => {
if (!city) {
return 'unknown'
}
if (city.name in europeCities) {
return 'Cities in Europe'
}
return 'Cities in US'
}
},
{ name: 'firstName', defaultFlex: 1, minWidth: 120, header: 'First Name' },
{ name: 'age', type: 'number', defaultFlex: 1, minWidth: 70, header: 'Age' },
{ name: 'email', defaultFlex: 1, header: 'Email', minWidth: 170 },
{ name: 'phone', defaultFlex: 1, header: 'Phone', minWidth: 150 },
{ name: 'streetName', defaultFlex: 1, header: 'Street name', minWidth: 120 },
{ name: 'streetNo', type: 'number', minWidth: 120, defaultFlex: 1, header: 'Street no' }
]
const App = () => {
return (
<div>
<p>The "city" column has a custom grouping function.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={["city"]}
hideGroupByColumns={false}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
React.Node|Fn(columnProps, info)
default: undefined
columns.header
prop (any valid React.Node or even a function) you can have full control over what gets rendered as the column header - even for different states of the column (sorted, filtered, etc).column.header
function provides additional info about the column header. For example, you can use info.contextMenu
to know if the header function is currently called for rendering the column name/header in the <ReactDataGrid />
column context menu.column.header
function is called when rendering the column header in three different scenarios:column.header(cellProps, { cellProps, column, headerProps })
cellProps
is an object that contains all the column properties, but in addition also contains useful information about the header cell.column.header
is called for the normal column header, the headerProps
property is present on the second parameter to the function call.column.header(cellProps, { column, contextMenu })
.column.header
is called for the show/hide columns menu, the contextMenu
property is present on the second parameter to the function call.<ReactDataGrid />
is grouped by the current column - called like column.header(column, { column, group: true })
column.header
is called for the grouping toolbar item when grouping by the current column, neither headerProps
nor contextMenu
properties are present on the second parameter to the function call. Instead, a boolean group
prop is present.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: <h3 style={{margin: 0, color: 'tomato', fontWeight: 'bold'}}>First Name</h3> },
{ name: 'city', defaultFlex: 1,
header: ({ sortInfo }, { contextMenu }) => {
const sorted = sortInfo && sortInfo.name === 'city' ? ' sorted' : '';
const sortOrder = sorted ? (sortInfo.dir === 1 ? ' ASC' : ' DESC') : ''
return 'City'+sorted+sortOrder + (contextMenu ? ' (context menu)': '')
}
},
{ name: 'age', header: 'Current age', maxWidth: 400, defaultWidth: 150, type: 'number' }
]
export default () => <ReactDataGrid
style={gridStyle}
idProperty="uniqueId"
columns={columns}
dataSource={people}
/>
String
default: undefined
column.headerAlign
is not specified, column.textAlign
will be used for aligning content in the column header."start"
, "center"
and "end"
. By default, column header contents are naturally aligned by the browser, so they get "start"
-aligned.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, headerAlign: 'start' },
{ name: 'city', header: 'City', defaultFlex: 1, headerAlign: 'center' },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1, headerAlign: 'end' }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Columns with headerAlign none, start, center and end
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
className
, style
or onClick
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const countryStyle = {
color: '#7986cb'
}
const redColor = {
color: '#ef9a9a'
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ name: 'name', defaultFlex: 1, minWidth: 100, header: 'Name', headerDOMProps: { style : redColor } },
{ name: 'country', headerDOMProps: { style: countryStyle }, defaultFlex: 1, minWidth: 100, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 100, header: 'City' },
{ name: 'age', minWidth: 150, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
column.header
), ellipsis will no longer work since you are changing the nesting & layout of the column header. In this case, you have to take care of showing the text ellipsis yourself by adding the correct styles to the correct elements to make it work as desired.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = ({ textEllipsis }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{
id: 'description',
defaultFlex: 1,
maxWidth: 150,
textEllipsis,
headerEllipsis: textEllipsis,
header: 'Description column to test ellipsis',
render: ({ data }) => data.name + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
}
const App = () => {
const [textEllipsis, setTextEllipsis] = useState(true)
const [columns, setColumns] = useState(getColumns({ textEllipsis }))
const onTextEllipsisChange = useCallback((textEllipsis) => {
setTextEllipsis(textEllipsis)
setColumns(getColumns({ textEllipsis }))
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={textEllipsis}
onChange={onTextEllipsisChange}
>
Show text ellipsis on description header and column.
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
columnHeaderUserSelect
.columns.userSelect
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = ({ headerUserSelect }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name - double-click to test selection', defaultFlex: 1, minWidth: 250, headerUserSelect },
{ name: 'age', minWidth: 250, defaultFlex: 1, header: 'Double-click to select', headerUserSelect: true }
]
}
const App = () => {
const [headerUserSelect, setHeaderUserSelect] = useState(true);
const [columns, setColumns] = useState(getColumns({ headerUserSelect }))
const headerUserSelectHandle = useCallback((value) => {
setHeaderUserSelect(value);
setColumns(getColumns({ headerUserSelect: value }));
}, [])
return (
<div>
<div>
<CheckBox checked={headerUserSelect} onChange={headerUserSelectHandle}>
Enable browser text selection in headers
</CheckBox>
</div>
<p>The last column header is always selectable, since it's configured with headerUserSelect: true</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
sortable={false}
/>
</div>
);
}
export default () => <App />
String
default: undefined
column.headerVerticalAlign
is not specified, column.textVerticalAlign
will be used for vertically aligning content in the column header."top"
, "center"
(or "middle"
) and "bottom"
. By default, column header contents are vertically "middle"
-aligned.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, headerVerticalAlign: 'top' },
{ name: 'city', header: 'City', defaultFlex: 1, headerVerticalAlign: 'middle' },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number', headerVerticalAlign: 'bottom' }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Header columns with headerVerticalAlign none, top, middle and bottom
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={70}
headerHeight={100}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
false
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = ({ nameHideable }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, hideable: nameHideable, header: 'Name' },
{ name: 'country', defaultFlex: 1, minWidth: 80, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
}
const App = () => {
const [nameHideable, setNameHideable] = useState(false);
const [columns, setColumns] = useState(getColumns({ nameHideable }))
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={nameHideable}
onChange={(nameHideable) => {
setNameHideable(nameHideable);
setColumns(getColumns({ nameHideable }));
}}
>
Can hide Name column
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
id
or a name
, which should both be unique.column.id
is used, you need to use the column.render({data})
function in order to render content for the column cells.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultWidth: 100,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
defaultFlex: 2,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
false
. For the most part, this prop is an alias to columns.showColumnMenuLockOptions
.columns.showColumnMenuLockOptions
for details.lockable
Bool
default: false
<ReactDataGrid />
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = (lockStart, lockEnd) => {
const lockedStartProps = lockStart ? { locked: 'start' } : { locked: false };
const lockedEndProps = lockEnd ? { locked: 'end' } : { locked: false };
return [
{ name: 'Id', header: 'Id', defaultVisible: false },
Object.assign({ name: 'name', header: 'Name', defaultWidth: 250 }, lockedStartProps),
{ name: 'email', header: 'Email', defaultWidth: 250 },
Object.assign({ name: 'city', header: 'City', defaultWidth: 250}, lockedEndProps),
{ name: 'country', header: 'Country', defaultWidth: 250,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultWidth: 250 }
]
}
const App = () => {
const [lockStart, setLockStart] = useState(true)
const [lockEnd, setLockEnd] = useState(false)
const [columns, setColumns] = useState(getColumns('start'))
return (
<div>
<div style={{ marginBottom: 20 }}>
Make sure the columns do not fit the window, to force the horizontal scroll
</div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={lockStart}
onChange={value => {
setLockStart(value)
setColumns(getColumns(value, lockEnd))
}}
>
Lock at start
</CheckBox>
<CheckBox
style={{ marginLeft: 16 }}
checked={lockEnd}
onChange={value => {
setLockEnd(value)
setColumns(getColumns(lockStart, value))
}}
>
Lock at end
</CheckBox>
</div>
<ReactDataGrid
key={'grid-' + lockStart + lockEnd}
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
resizable
columns cannot be user-resized to have a bigger size, neither can flexible columns stretch more that the specified maximum width.column.minWidth
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 80 },
{ name: 'firstName', header: 'Name maxWidth 200', defaultFlex: 2 },
{
name: 'country',
header: 'Country maxWidth 250',
maxWidth: 250,
defaultFlex: 3,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultFlex: 1 }
];
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMaxWidth={200}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
resizable
columns cannot be user-resized to be smaller than the specified minimum size, neither can flexible columns shrink to be smaller than the specified min-width.column.maxWidth
.columnMinWidth
(which defaults to 50
).import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', minWidth: 40, maxWidth: 40 },
{ name: 'firstName', header: 'Name default minWidth', minWidth: 200, defaultFlex: 1 },
{
name: 'country',
header: 'Country default minWidth',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', header: 'Age default minWidth' }
];
const App = () => {
return (
<div>
<p>Default column minWidth=150</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
columnMinWidth={150}
/>
</div>
);
}
export default () => <App />
String
default: undefined
dataSource
. id
is not specified, the name
will be used as an identifier. As a consequence, the column.name
or column.id
should be unique.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ id: 'uid', header: '#', render: ({data}) => data.id, defaultWidth: 80 },
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Each column must have a name or an id. First column has no name, but a required id and a custom render function.
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(cellProps)
default: undefined
className
, style
).column.cellDOMProps
, which is the last render hook before the cell contents get into the DOM.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const onCountryRender = (cellProps) => {
cellProps.style.color = '#7986cb'
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ name: 'name', defaultFlex: 1, minWidth: 100, header: 'Name' },
{ name: 'country', onRender: onCountryRender, defaultFlex: 1, minWidth: 100, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 100, header: 'City' },
{ name: 'age', minWidth: 150, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
(fieldValue, { data: object, field: string }) => string
default: undefined
'string'
or 'number'
or 'boolean'
, it simply stringifies them with toString
, otherwise it will use JSON.stringify
)bucketing
because we decide in which bucket/group a data item in the grid dataSource
should be put - this determines which items go into a certain pivot group.pivot
prop.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import sales from './sales';
const currency = (v) => {
const str = ("" + v).split("").reverse().map((c,i) => {
if (i && i%3 === 0) {
return c + ","
}
return c
}).reverse().join('')
return "$ " + str + ".00"
}
const gridStyle = { minHeight: 500, marginTop: 10 }
const sumReducer = {
initialValue: 0,
reducer: (a: number, b: number) => a + b,
};
const groupSummaryReducer = {
initialValue: {
count: 0,
grandTotal: 0,
},
reducer: (v: { count: number; grandTotal: number }, item) => {
return {
count: v.count + 1,
grandTotal: v.grandTotal + item.amount,
};
},
};
const quarterSumReducer = (monthFn: (m: number) => boolean) => {
return {
initialValue: 0,
reducer: (acc: number, value: number, item: any) => {
const month = parseInt(item.date.split('-')[1], 10);
if (monthFn(month)) {
return acc + item.amount;
}
return acc;
},
};
};
const columns = [
{ name: 'region', header: 'Region' },
{ name: 'country', header: 'Country' },
{ name: 'city', header: 'City' },
{
name: 'id',
header: 'Id',
defaultVisible: false,
type: 'number',
maxWidth: 100,
},
{
id: 'year',
name: 'date',
header: 'Year',
pivotToString: (_, { data }) => {
return data.date.split('-')[0];
},
},
{
id: 'q1',
defaultWidth: 150,
header: 'Q1',
name: 'amount',
pivotName: 'q1',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month <= 3),
render: ({ value }) => currency(value),
textAlign: 'end'
},
{
id: 'q2',
defaultWidth: 150,
header: 'Q2',
name: 'amount',
pivotName: 'q2',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 3 && month <= 6),
render: ({ value }) => currency(value),
textAlign: 'end'
},
{
id: 'q3',
defaultWidth: 150,
header: 'Q3',
pivotName: 'q3',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 6 && month <= 9),
render: ({ value }) => currency(value),
textAlign: 'end'
},
{
id: 'q4',
defaultWidth: 150,
header: 'Q4',
pivotName: 'q4',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 9 && month <= 12),
render: ({ value }) => currency(value),
textAlign: 'end'
},
];
const summaryReducer = {
initialValue: {
total: 0
},
reducer: (acc, item, computedProps) => {
const dateSplit = item.date.split('-');
const year = parseInt(dateSplit[0], 10);
const month = parseInt(dateSplit[1], 10);
const quarter =
year +
'-' +
(month <= 3 ? 'q1' : month <= 6 ? 'q2' : month <= 9 ? 'q3' : 'q4');
if (!acc[year]) {
acc[year] = 0;
}
if (!acc[quarter]) {
acc[quarter] = 0;
}
acc[year] += item.amount;
acc[quarter] += item.amount;
acc.total += item.amount;
return acc;
},
};
const footerCellStyle = {
textOverflow: 'ellipsis',
width: '100%',
whiteSpace: 'nowrap',
overflow: 'hidden',
};
const pivot = [
{
name: 'year',
summaryReducer: {
initialValue: 0,
reducer: (acc, value, item) => {
const year = item.date.split('-')[0];
if (year == value) {
return acc + item.amount;
}
return acc;
},
complete: (value) => <b>{currency(value)}</b>
},
summaryColumn: ({ pivotSummaryPath }) => {
return {
header: 'Summary ' + pivotSummaryPath[0].value,
textAlign: 'end',
style: {
color: '#7986cb'
}
};
},
summaryGroup: {
headerAlign: 'center'
}
}
]
const App = () => {
const [enablePivot, setEnablePivot] = useState(true)
const [groupBy, setGroupBy] = useState(['region', 'city'])
const [showPivotSummaryColumns, setShowPivotSummaryColumns] = useState(true)
const updateArray = useCallback((arr, fn, keys, sortOrder) => {
let sortOrderIndexes = (sortOrder || []).reduce((acc, value, index) =>{
acc[value] = index
return acc
}, {})
Object.keys(keys).forEach(columnName => {
const checked = keys[columnName]
if (checked) {
if (arr.indexOf(columnName) === -1) {
arr = [...arr, columnName]
}
} else {
if (arr.indexOf(columnName) !== -1) {
arr = arr.filter(x=>x!=columnName)
}
}
})
if (sortOrder) {
arr.sort((a,b) => sortOrderIndexes[a] - sortOrderIndexes[b])
}
fn(arr)
}, [])
const updateGroupBy = useCallback((keys) => {
updateArray(groupBy, setGroupBy, keys,['region', 'country', 'city']);
}, [groupBy])
return (
<div>
<h3>Grid pivoted by year, with the column having pivotToString defined</h3>
<div style={{ marginTop: 20}}>
<CheckBox
checked={showPivotSummaryColumns}
onChange={setShowPivotSummaryColumns}
>
Show pivot summary columns
</CheckBox>
</div>
<div style={{ marginTop: 20 }}>
<CheckBox
checked={groupBy.indexOf('region') !== -1}
onChange={checked => updateGroupBy({ region: checked })}
>
Group by region
</CheckBox>
</div>
<div style={{ marginTop: 20 }}>
<CheckBox
checked={groupBy.indexOf('country') !== -1}
onChange={checked => updateGroupBy({ country: checked })}
>
Group by country
</CheckBox>
</div>
<div style={{ marginTop: 20 }}>
<CheckBox
checked={groupBy.indexOf('city') !== -1}
onChange={checked => updateGroupBy({ city: checked })}
>
Group by city
</CheckBox>
</div>
<ReactDataGrid
style={gridStyle}
columns={columns}
dataSource={sales}
columnMinWidth={150}
pivot={enablePivot ? pivot : null}
groupBy={groupBy}
showPivotSummaryColumns={showPivotSummaryColumns}
pivotGrandSummaryColumn={{
header: 'TOTAL',
style: {
color: '#ef9a9a',
textAlign: 'right'
},
render: ({ data }) => <b>{currency(data.groupSummary.grandTotal)}</b>
}}
onGroupByChange={setGroupBy}
groupSummaryReducer={groupSummaryReducer}
groupColumn={{
defaultFlex: 1,
minWidth: 250,
renderGroupValue: ({ value, groupSummary }) => (
<React.Fragment>
{value} ({groupSummary.count} records)
</React.Fragment>
),
}}
summaryReducer={summaryReducer}
footerRows={[
{
render: ({ column, summary }) => {
const { pivotColumnPath, pivotSummaryPath, pivotGrandSummaryColumn, groupColumn } = column;
let style = Object.assign({},footerCellStyle)
if (groupColumn) {
return <div style={style}>
<b>Total sales</b>
</div>
}
style.textAlign = 'end'
let result;
if (pivotSummaryPath && pivotSummaryPath.length) {
const pivotInfo = [...pivotSummaryPath].pop();
const pivotValue = pivotInfo.value;
result = summary[pivotValue];
style.color = '#7986cb'
} else if (pivotColumnPath) {
result = summary[(pivotColumnPath || []).join('-')] || 0;
} else if (pivotGrandSummaryColumn) {
result = summary.total;
style.color = '#ef9a9a'
}
return (
<div style={style}>
<b>{currency(result || 0)}</b>
</div>
);
},
},
]}
/>
</div>
);
}
export default () => <App />
Fn()
default: undefined
name
prop by default render the value in the corresponding property in the dataSource
items.name
or an id
) is supported via the columns.render
function prop. The columns.render
is passed an object with the following properties:value
- if the column has a name, the value would be the value rendered if no columns.render
property were configured.data
- the data object in the dataSource
corresponding to the current row being rendered.cellProps: Object
- the props being passed to the cell corresponding to the current row and column.cellProps: Object
has a lot of properties you can use, here are some of them:cellProps.data: Object
- the data object backing the rowcellProps.value
- the value to render for the cellcellProps.rowIndex: Number
cellProps.columnIndex: Number
cellProps.inEdit: Bool
- whether the cell is currently in edit modecellProps.editProps: Object
- available when the cell is in edit moderowIndex: Number
- the index of the current row being rendered.rowSelected: Boolean
- a boolean value indicating if the current row is selected or not.rowActive: Boolean
- a boolean value indicating if the current row is keyboard active or not.cellSelected: Boolean
- a boolean value indicating if the current cell is selected or not.empty: Boolean
- a boolean value indicating if the current row is an empty row or not.totalDataCount: Number
- the total count of rows that will be rendered.rowExpanded: Boolean
- a boolean value indicating if the current row is expanded or not.toggleRowExpand: Function
- if the <ReactDataGrid />
has row expand enabled - see expandedRows
, this function will be present, and can be used to toggle the current row.setRowExpanded: Function(Boolean)
- if the <ReactDataGrid />
has row expand enabled - see expandedRows
, this function will be present, and can be used to set the toggle state of the current row.loadNodeAsync: Function()
- calling it allows you to reload the current tree node (available when treeColumn
is used) - loadNode or loadNodeOnce will be called for the current node.toggleNodeExpand: Function()
- calling it allows you to toggle the current tree node (available when treeColumn
is used)rendersInlineEditor
- boolean flag indicating if the cell should have the inline editor renderedcolumns.render
function is reused - so you should not keep a reference to it. Instead, use ES6 destructuring to take the values you are interested in from this object.<ReactDataGrid />
column cells are optimized to only render when there is a change in the underlying dataSource
, therefore, the column.render
function should be pure. If not pure, and if the column.render
uses variables defined outside of the function, make sure you specify columns.shouldComponentUpdate
to return true
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import flags from './flags'
const gridStyle = { maxHeight: 207 }
const columns = [
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, header: 'Last Name' },
{
name: 'country',
header: 'Country',
defaultWidth: 100,
textAlign: 'center',
render: ({ value }) => flags[value] ? flags[value] : 'unknown'
},
{ id: 'fullName', header: 'Full Name', minWidth: 100, defaultFlex: 1, render: ({ data }) => data.firstName + ' ' + data.lastName },
{
name: 'age',
header: 'Age',
defaultWidth: 80,
render: ({ value }) => <span style={{ color: value < 30 ? '#7986cb' : 'inherit'}}>{value}</span>
}
]
const dataSource = [
{ firstName: 'John', lastName: 'Grayner', country: 'usa', age: 35, id: 0 },
{ firstName: 'Mary', lastName: 'Stones', country: 'ca', age: 25, id: 1 },
{ firstName: 'Robert', lastName: 'Fil', country: 'uk', age: 27, id: 2 },
{ firstName: 'Mark', lastName: 'Twain', country: 'usa', age: 74, id: 3 }
]
export default () => <ReactDataGrid
idProperty="id"
columns={columns}
dataSource={dataSource}
style={gridStyle}
/>
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import TextInput from '../components/TextInput'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 400 }
const App = () => {
const [gridRef, setGridRef] = useState(null);
const [dataSource, setDataSource] = useState(people);
const [searchText, setSearchText] = useState('');
const render = useCallback(({ value }) => {
const lowerSearchText = searchText && searchText.toLowerCase();
if (!lowerSearchText) {
return value
}
const str = value + '' // get string value
const v = str.toLowerCase() // our search is case insensitive
const index = v.indexOf(lowerSearchText)
if (index === -1) {
return value
}
return [
<span key="before">{str.slice(0, index)}</span>,
<span key="match" style={{ background: 'yellow', fontWeight: 'bold'}}>{str.slice(index, index + lowerSearchText.length)}</span>,
<span key="after">{str.slice(index + lowerSearchText.length)}</span>
]
}, [searchText])
const shouldComponentUpdate = () => true
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, minWidth: 50, type: 'number', render, shouldComponentUpdate },
{ name: 'name', defaultFlex: 1, render, shouldComponentUpdate, header: 'Name' },
{ name: 'country', defaultFlex: 1, minWidth: 100, render: ({ value })=> flags[value] ? flags[value] : value, shouldComponentUpdate, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 100, render, shouldComponentUpdate, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number',render, shouldComponentUpdate, header: 'Age' }
]
const onSearchChange = useCallback(({ target: { value }}) => {
const visibleColumns = gridRef.current.visibleColumns
const lowerSearchText = value.toLowerCase();
const newData = people.filter(p => {
return visibleColumns.reduce((acc, col) => {
const v = (p[col.id] + '').toLowerCase() // get string value
return acc || v.indexOf(lowerSearchText) != -1 // make the search case insensitive
}, false)
})
setSearchText(value);
setDataSource(newData);
}, [gridRef])
return (
<div>
<p>
We have to use <code>shouldComponentUpdate: () => true</code> for the columns rendering the search highlight, because they rely on external data (the render function is not pure), and yet we want them to be updated when the search text is updated.
</p>
<p>
If not specifying the <code>shouldComponentUpdate: () => true</code>, the grid will not update the highlight when there is no change in the filtered rows, but yet the searchText changes - eg: going from "Manche" to "Manchester")
</p>
<div style={{ marginBottom: 20 }}>
<label>Search text: <TextInput style={{ padding: 5 }} value={searchText} onChange={onSearchChange}/> </label>
</div>
<p>
We demo a search-box outside the grid. Use the search-box to filter out rows that do not contain the specified text.
</p>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(editorProps)
default: undefined
<ReactDataGrid />
supports this feature, so you can specify your own column.editor
, which should be a React Component.column.renderEditor(editorProps)
function and return a React.Node
that describes your editor.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumericEditor from '@inovua/reactdatagrid-community/NumericEditor'
import BoolEditor from '@inovua/reactdatagrid-community/BoolEditor'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, minWidth: 200, maxWidth: 300, header: 'Name' },
{ name: 'age', defaultFlex: 1, type: 'number', editor: NumericEditor, header: 'Age' },
{ name: 'student',
header: 'Student',
width: 100,
render: ({ value }) => value? 'Yes':'No',
renderEditor: (editorProps) => {
return <div
tabIndex={0}
autoFocus
onClick={() => {
editorProps.onChange(!editorProps.value)
}}
onBlur={editorProps.onComplete}
onKeyDown={e => {
if (e.key == 'Tab') {
editorProps.onTabNavigation(
true /*complete navigation?*/,
e.shiftKey ? -1 : 1 /*backwards of forwards*/
);
}
}}
style={{
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
width: '100%',
height: '100%',
background: '#434d64',
color: '#9ba7b4',
left: 0,
top: 0
}}
>
{editorProps.value ? 'X' : 'O'}
</div>
}
},
{ name: 'country', defaultFlex: 1, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' }
]
const App = () => {
const [dataSource, setDataSource] = useState(people);
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data);
}, [dataSource])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
editable={true}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn({ value, name, fieldPath, ... }, rowProps)
default: undefined
groupBy
.renderGroupTitle
column.groupToString
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', groupBy: false, type: 'number', defaultWidth: 70, header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultWidth: 200, header: 'First Name' },
{ name: 'lastName', defaultWidth: 200, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultWidth: 200, header: 'Email' },
{
name: 'permissionToCall', defaultWidth: 200,
header: 'Permission to call',
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value ? 'Can be called' : 'Cannot be called'
}
]
const loadData = ({ skip, limit, sortInfo, groupBy }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo) : '') + (groupBy && groupBy.length ? '&groupBy=' + groupBy : '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const [groupBy, setGroupBy] = useState([]);
const dataSource = useCallback(loadData, [])
return (
<div>
<p><Button onClick={() => setGroupBy(['permissionToCall', 'lastName'])}>Group by permissionToCall and lastName</Button></p>
<p><Button onClick={() => setGroupBy([])}>Remove grouping</Button></p>
<p>In this example, you cannot group by id or email.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
groupBy={groupBy}
onGroupByChange={setGroupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(cellProps)
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Arrow from './Arrow'
import flags from './flags'
const arrowStyle = {
display: 'block',
marginBottom: 2
};
const defaultStyle = {
display: 'inline-block',
marginRight: 5,
width: 8,
verticalAlign: 'middle'
};
const SortIndicator = ({ direction }) => {
return <div style={defaultStyle}>
{direction === -1 ? <Arrow type="activeUp" style={arrowStyle} /> : <Arrow type="up" style={arrowStyle} />}
{direction === 1 ? <Arrow type="activeDown" style={arrowStyle} /> : <Arrow type="down" style={arrowStyle} />}
</div>
};
const renderHeader = ({children}) => {
return children.reverse() // reverse the order
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 120 },
{ name: 'firstName', header: 'Fist Name, unsortable', sortable: false, minWidth: 200, defaultFlex: 1, renderHeader },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1, renderHeader },
{
name: 'country',
header: 'Country',
defaultWidth: 100,
renderHeader,
render: ({ value }) => flags[value] ? flags[value] : 'unknown'
},
{ id: 'fullName', header: 'Full Name', renderHeader, minWidth: 50, defaultFlex: 1, render: ({ data }) => data.firstName + ' ' + data.lastName },
{
name: 'age',
header: 'Age',
type: 'number',
renderHeader,
defaultWidth: 80,
render: ({ value }) => <span style={{ color: value < 30 ? 'green' : 'inherit'}}>{value}</span>
}
]
const renderSortTool = (direction) => {
return <SortIndicator direction={direction} />
}
const dataSource = [
{ firstName: 'John', lastName: 'Grayner', country: 'usa', age: 35, id: 0 },
{ firstName: 'Mary', lastName: 'Stones', country: 'ca', age: 25, id: 1 },
{ firstName: 'Robert', lastName: 'Fil', country: 'uk', age: 27, id: 2 },
{ firstName: 'Bob', lastName: 'Fisher', country: 'usa', age: 72, id: 3 },
{ firstName: 'Michael', lastName: 'Rogers', country: 'usa', age: 45, id: 4 },
{ firstName: 'Hilly', lastName: 'Bobson', country: 'uk', age: 5, id: 5 },
{ firstName: 'Mike', lastName: 'Brind', country: 'ca', age: 15, id: 6 },
{ firstName: 'Carl', lastName: 'Phancer', country: 'ca', age: 56, id: 7 },
{ firstName: 'Victory', lastName: 'Hope', country: 'uk', age: 52, id: 8 }
]
const gridStyle = { minHeight: 550 }
const defaultSortInfo = { name: 'age', dir: 1 }
export default () => <ReactDataGrid
idProperty="id"
columns={columns}
style={gridStyle}
defaultSortInfo={defaultSortInfo}
renderSortTool={renderSortTool}
dataSource={dataSource}
/>
bool|Fn(props)
default: undefined
rendersInlineEditor=true
, it should use its render
function to render an editor - which, when focused, starts the edit (so it saves the user a double click on the cell in order to start editing). The editor also participates in the edit keyboard navigation flow.column.render
function.rendersInlineEditor
is a function, the result of the function will be available in the column.render
function, as a property to the first argument.import React, { useState, useEffect, useRef, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import TextInput from '../components/TextInput'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const Input = (props) => {
const inputRef = useRef(null)
useEffect(() => {
if (inputRef && inputRef.current) {
if (props.autoFocus) {
inputRef.current.focus()
}
}
}, [])
return (
<TextInput {...props} inputRef={inputRef} />
);
}
const nameColumn = {
name: 'name',
header: 'Name',
defaultFlex: 1, minWidth: 200,
rendersInlineEditor: true,
render: ({ value }, { cellProps }) => {
let v = cellProps.editProps.inEdit
? cellProps.editProps.value
: value;
return (
<Input
type="text"
autoFocus={cellProps.inEdit}
value={v}
onBlur={e => {
cellProps.editProps.onComplete();
}}
onChange={cellProps.editProps.onChange}
onFocus={() => cellProps.editProps.startEdit()}
onKeyDown={e => {
if (e.key === 'Escape') {
cellProps.editProps.onCancel(e);
}
if (e.key === 'Enter') {
cellProps.editProps.onComplete(e);
}
if (e.key == 'Tab') {
e.preventDefault();
cellProps.editProps.onTabNavigation(
true,
e.shiftKey ? -1 : 1
);
}
}}
/>
);
}
}
const initialData = people.map(p=> Object.assign({}, p))
const columns = [
{ name: 'id', minWidth: 70, type: 'number', header: 'Id', defaultVisible: false },
nameColumn,
{ name: 'country', defaultFlex: 1, minWidth: 100, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 200, header: 'City' },
{ name: 'age', minWidth: 150, type: 'number', header: 'Age' }
]
const App = () => {
const [dataSource, setDataSource] = useState(initialData)
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId] = Object.assign({}, data[rowId], {[columnId]: value});
setDataSource(data)
}, [dataSource])
return (
<div>
<h3>NAME column already renders an editor</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
editable={true}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(direction, extraProps)
default: undefined
renderSortTool
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Arrow from './Arrow'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const arrowStyle = {
display: 'block',
marginBottom: 2
};
const defaultStyle = {
display: 'inline-block',
marginLeft: 5,
width: 8,
verticalAlign: 'middle'
};
const SortIndicator = ({ direction }) => {
return <div style={defaultStyle}>
{direction === -1 ? <Arrow type="activeUp" style={arrowStyle} /> : <Arrow type="up" style={arrowStyle} />}
{direction === 1 ? <Arrow type="activeDown" style={arrowStyle} /> : <Arrow type="down" style={arrowStyle} />}
</div>
};
const renderSortTool = (direction, extraProps) => {
return <SortIndicator direction={direction} />
}
const defaultSortInfo = { name: 'age', dir: 1 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80, renderSortTool },
{ name: 'firstName', header: 'First Name', defaultFlex: 1, renderSortTool },
{ name: 'country', header: 'Country', defaultFlex: 1, renderSortTool,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1, renderSortTool }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
defaultSortInfo={defaultSortInfo}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ resizable }) => {
return [
{ name: 'firstName', defaultFlex: 1, resizable, header: 'First Name' },
{ name: 'country', defaultFlex: 1, resizable, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{
id: 'desc',
header: 'Description',
defaultFlex: 2,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
}
const App = () => {
const [resizable, setResizable] = useState(true)
const [columns, setColumns] = useState(getColumns({ resizable }))
const onResizableChange = useCallback((resizable) => {
setResizable(resizable)
setColumns(getColumns({ resizable }))
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={resizable}
onChange={onResizableChange}
>
Toggle resizable for the first two columns.
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ data, value, rowIndex, column, dataSourceArray })
default: undefined
column.rowspan
and column.colspan
functions you have access to the data you need to make those truly dynamic.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
defaultWidth: 50,
type: 'number'
},
{ name: 'name', defaultFlex: 1, header: 'Name' },
{
name: 'country',
header: 'Country',
defaultFlex: 1,
rowspan: ({ value, dataSourceArray, rowIndex, column }) => {
let rowspan = 1;
const prevData = dataSourceArray[rowIndex - 1];
if (prevData && prevData[column.name] === value) {
return rowspan;
}
let currentRowIndex = rowIndex + 1;
while (
dataSourceArray[currentRowIndex] &&
dataSourceArray[currentRowIndex][column.name] === value
) {
rowspan++;
currentRowIndex++;
if (rowspan > 9) {
break;
}
}
return rowspan;
}
},
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<h3>Rowspan example</h3>
<p>
Try and sort the <b>COUNTRY</b> column to see the cells with same country
spanning together.
</p>
<ReactDataGrid
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
default: undefined
column.render
function which is not pure, but uses variables from the outer context. Otherwise, if not using shouldComponentUpdate: () => true
in these cases, you end up with the cells not being updated/re-rendered properly.<ReactDataGrid />
column cells are optimized to only render when there is a change in the underlying dataSource
, therefore, the column.render
function should be pure. If not pure, and if the column.render
uses variables defined outside of the function, make sure you specify columns.shouldComponentUpdate
to return true
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import TextInput from '../components/TextInput'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 400 }
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [dataSource, setDataSource] = useState(people);
const [searchText, setSearchText] = useState('');
const render = useCallback(({ value }) => {
const lowerSearchText = searchText && searchText.toLowerCase();
if (!lowerSearchText) {
return value
}
const str = value + '' // get string value
const v = str.toLowerCase() // our search is case insensitive
const index = v.indexOf(lowerSearchText)
if (index === -1) {
return value
}
return [
<span key="before">{str.slice(0, index)}</span>,
<span key="match" style={{ background: 'yellow', fontWeight: 'bold'}}>{str.slice(index, index + lowerSearchText.length)}</span>,
<span key="after">{str.slice(index + lowerSearchText.length)}</span>
]
}, [searchText])
const shouldComponentUpdate = () => true
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, minWidth: 50, type: 'number', render, shouldComponentUpdate },
{ name: 'name', defaultFlex: 1, render, shouldComponentUpdate, header: 'Name' },
{ name: 'country', defaultFlex: 1, minWidth: 100, render: ({ value })=> flags[value] ? flags[value] : value, shouldComponentUpdate, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 100, render, shouldComponentUpdate, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number',render, shouldComponentUpdate, header: 'Age' }
]
const onSearchChange = useCallback(({ target: { value }}) => {
const visibleColumns = gridRef.current.visibleColumns
const lowerSearchText = value.toLowerCase();
const newData = people.filter(p => {
return visibleColumns.reduce((acc, col) => {
const v = (p[col.id] + '').toLowerCase() // get string value
return acc || v.indexOf(lowerSearchText) != -1 // make the search case insensitive
}, false)
})
setSearchText(value);
setDataSource(newData);
}, [gridRef])
return (
<div>
<p>
We have to use <code>shouldComponentUpdate: () => true</code> for the columns rendering the search highlight, because they rely on external data (the render function is not pure), and yet we want them to be updated when the search text is updated.
</p>
<p>
If not specifying the <code>shouldComponentUpdate: () => true</code>, the grid will not update the highlight when there is no change in the filtered rows, but yet the searchText changes - eg: going from "Manche" to "Manchester")
</p>
<div style={{ marginBottom: 20 }}>
<label>Search text: <TextInput style={{ padding: 5 }} value={searchText} onChange={onSearchChange}/> </label>
</div>
<p>
We demo a search-box outside the grid. Use the search-box to filter out rows that do not contain the specified text.
</p>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
showColumnMenuFilterOptions
, at column-level.renderColumnContextMenu
in order to have full control over what gets rendered in the menu.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
];
const getColumns = ({ showColumnMenuFilterOptions }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, showColumnMenuFilterOptions, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, hedaer: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
}
const App = () => {
const [showColumnMenuFilterOptions, setShowColumnMenuFilterOptions] = useState(true);
const [columns, setColumns] = useState(getColumns({ showColumnMenuFilterOptions }));
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuFilterOptions}
onChange={(showColumnMenuFilterOptions) => {
setShowColumnMenuFilterOptions(showColumnMenuFilterOptions);
setColumns(getColumns({ showColumnMenuFilterOptions }))
}}
>
Display show/hide filtering row option for NAME column in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
showColumnMenuGroupOptions
, at column-level.renderColumnContextMenu
in order to have full control over what gets rendered in the menu.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ showColumnMenuGroupOptions }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, showColumnMenuGroupOptions, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
}
const App = () => {
const [showColumnMenuGroupOptions, setShowColumnMenuGroupOptions] = useState(true);
const [columns, setColumns] = useState(getColumns({ showColumnMenuGroupOptions }));
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuGroupOptions}
onChange={(showColumnMenuGroupOptions) => {
setShowColumnMenuGroupOptions(showColumnMenuGroupOptions);
setColumns(getColumns({ showColumnMenuGroupOptions }));
}}
>
Show group/ungroup loption for NAME column in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
showColumnMenuLockOptions
, at column-level.renderColumnContextMenu
in order to have full control over what gets rendered in the menu.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ showColumnMenuLockOptions }) => [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, showColumnMenuLockOptions, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
const [showColumnMenuLockOptions, setShowColumnMenuLockOptions] = useState(true);
const [columns, setColumns] = useState(getColumns({ showColumnMenuLockOptions }));
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuLockOptions}
onChange={(showColumnMenuLockOptions) => {
setShowColumnMenuLockOptions(showColumnMenuLockOptions);
setColumns(getColumns({ showColumnMenuLockOptions }))
}}
>
Show lock/unlock option for NAME column in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
showColumnMenuSortOptions
, at column-level.renderColumnContextMenu
in order to have full control over what gets rendered in the menu.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ showColumnMenuSortOptions }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, showColumnMenuSortOptions, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
];
}
const App = () => {
const [showColumnMenuSortOptions, setShowColumnMenuSortOptions] = useState(true);
const [columns, setColumns] = useState(getColumns({ showColumnMenuSortOptions }));
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuSortOptions}
onChange={(showColumnMenuSortOptions) => {
setShowColumnMenuSortOptions(showColumnMenuSortOptions);
setColumns(getColumns({ showColumnMenuSortOptions }))
}}
>
Show sort/unsort loption for NAME column in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
showColumnMenuTool
, at column-level.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ showColumnMenuTool }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, showColumnMenuTool, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
}
const App = () => {
const [showColumnMenuTool, setShowColumnMenuTool] = useState(true);
const [columns, setColumns] = useState(getColumns({ showColumnMenuTool }));
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuTool}
onChange={(showColumnMenuTool) => {
setShowColumnMenuTool(showColumnMenuTool);
setColumns(getColumns({ showColumnMenuTool }))
}}
>
Show NAME column header tool
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
showColumnMenuTool
is displayed on mouse over, or all the time. Defaults to true
if not a mobile device, and false
if the component is rendered on a mobile device, where we want the menu tool to always be rendered.showColumnMenuToolOnHover
, at column-level.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ showColumnMenuToolOnHover }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, showColumnMenuToolOnHover, header: 'Name' },
{ name: 'country', defaultFlex: 1,
header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
];
}
const App = () => {
const [showColumnMenuToolOnHover, setShowColumnMenuToolOnHover] = useState(true);
const [columns, setColumns] = useState(getColumns({ showColumnMenuToolOnHover }));
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuToolOnHover}
onChange={(showColumnMenuToolOnHover) => {
setShowColumnMenuToolOnHover(showColumnMenuToolOnHover);
setColumns(getColumns({ showColumnMenuToolOnHover }))
}}
>
Show NAME column header tool on hover
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(one, two, column)
default: undefined
columns.sort
function, make sure it always sorts in ascending order! For sorting in descending order, the <ReactDataGrid />
will take care to inverse the result of this function so as to obtain the correct sort order.columns.sort
function respects the contract specified by Array.prototype.sort - so you need to make sure it can be passed to [].sort
.columns.sort
function will be called with the first two arguments being the corresponding values for the column from the dataSource
(eg: for the age
column, it would be called with two numbers, the age
values from the currently compared records). The third argument is a reference to the column config, since you may need it sometimes (eg: when having a date column, specify a column.dateFormat
which you can access in the sort function).columns.sort
function does not have a columns.name
property, columns.sort
will be called with two arguments which are two items from the dataSource
(as opposed to being called with the corresponding properties for the column extracted from those dataSource
items).import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const dataSource = [
{ person: { name: 'Amanda Soaresz', age: 35 }, id: 0 },
{ person: { name: 'Mary Adamson', age: 25 }, id: 1 },
{ person: { name: 'Robert Fil', age: 27 }, id: 2 },
{ person: { name: 'Roger Bob', age: 81 }, id: 3 },
{ person: { name: 'Billary Konwik', age: 18 }, id: 4 },
{ person: { name: 'Bob Marc', age: 18 }, id: 5 },
{ person: { name: 'Matthew Richardson', age: 54 }, id: 6 },
{ person: { name: 'Richy Peterson', age: 54 }, id: 7 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{
name: 'person',
header: 'Person',
defaultFlex: 1,
sortable: true,
sort: (p1, p2) => p1.name.split(' ')[1].localeCompare(p2.name.split(' ')[1]),
render: ({ data }) => { return <span>{data.person.name}</span> }
},
{
name: 'age',
header: 'Age',
maxWidth: 400,
defaultWidth: 200,
type: 'number',
render: ({ data }) => <span>{data.person.age}</span>
}
]
const App = () => {
return (
<div>
<p>
In this example, you can sort the person column by the last name.
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
dataSource={dataSource}
columns={columns}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
columns.renderSortTool
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ sortable }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'Name', defaultFlex: 1, sortable },
{ name: 'country', header: 'Country', defaultWidth: 100, sortable,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'Age', header: 'Age - unsortable', defaultFlex: 1, sortable: false }
]
}
const App = () => {
const [sortable, setSortable] = useState(true)
const [columns, setColumns] = useState(getColumns({ sortable }))
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={sortable} onChange={value => {
setSortable(value)
setColumns(getColumns({ sortable: value }))
}}>
Sortable columns
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
column.headerAlign
is not specified, column.textAlign
will also be used for aligning content in the column header."start"
, "center"
and "end"
. By default, cell contents are naturally aligned by the browser, so they get "start"
-aligned.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultFlex: 1 },
{ name: 'name', header: 'Name', defaultFlex: 1, textAlign: 'start' },
{ name: 'city', header: 'City', defaultFlex: 1, textAlign: 'center' },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number', textAlign: 'end' }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Columns with textAlign none, start, center and end
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
column.render
), ellipsis will no longer work since you are changing the nesting & layout of the <ReactDataGrid />
cell. In this case, you have to take care of showing the text ellipsis yourself by adding the correct styles to the correct elements to make it work as desired.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = ({ textEllipsis }) => {
return [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{
id: 'description',
defaultFlex: 1,
maxWidth: 150,
textEllipsis,
header: 'Description',
render: ({ data }) => data.name + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
}
const App = () => {
const [textEllipsis, setTextEllipsis] = useState(true)
const [columns, setColumns] = useState(getColumns({ textEllipsis }))
const onTextEllipsisChange = useCallback((value) => {
setTextEllipsis(value)
setColumns(getColumns({ textEllipsis: value }))
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={textEllipsis}
onChange={onTextEllipsisChange}
>
Show text ellipsis on description column.
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
<ReactDataGrid />
cells."top"
, "center"
(or "middle"
) and "bottom"
. By default, cell contents are "middle"
-aligned.column.headerVerticalAlign
is not specified, column.textVerticalAlign
will also be used for vertically aligning content in the column header.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1, textVerticalAlign: 'top' },
{ name: 'city', header: 'City', defaultFlex: 1, textVerticalAlign: 'middle' },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1, textVerticalAlign: 'bottom' }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Column headers with none, top, middle and bottom vertical alignment
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
rowHeight={100}
headerHeight={100}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
columns.type="number"
for sorting in numeric order, instead of using string sort order. If not specified, the<ReactDataGrid />
will assume string content and will use String.prototype.localeCompare to compare values, which is not what you want for numbers.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
const gridStyle = {
maxHeight: 400
}
export default () => <ReactDataGrid
idProperty="id"
columns={columns}
dataSource={people}
style={gridStyle}
/>
Bool
default: undefined
columnUserSelect
.columns.headerUserSelect
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name - test cell selection on this column', defaultFlex: 1, minWidth: 250, },
{ name: 'age', minWidth: 250, defaultFlex: 1, header: 'Content can always be selected' }
]
const App = () => {
const [columnUserSelect, setColumnUserSelect] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={columnUserSelect} onChange={setColumnUserSelect}>
Enable browser text selection in cells
</CheckBox>
</div>
<p>The contents inside the 'name' column are always selectable, since it's configured with userSelect: true</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnUserSelect={columnUserSelect}
columns={columns}
dataSource={people}
sortable={false}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
false
if you want to hide a column. If not specified (so column.visible
is undefined), the column will be visible.defaultVisible
.visible
prop value when onColumnVisibleChange({ column, visible })
is triggered.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const getColumns = ({ visible }) => {
return [
{ name: 'id', header: 'Id', type: 'number', defaultWidth: 70, visible },
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
}
const App = () => {
const [visible, setVisible] = useState(false)
const [columns, setColumns] = useState(getColumns({ visible }))
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={visible}
onChange={visible => {
setVisible(visible)
setColumns(getColumns({ visible }))
}}
>
Show Id column
</CheckBox>
</div>
<ReactDataGrid
key={visible}
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
onColumnResize
and update the column width accordingly.defaultWidth
to specify the column size for a fixed column, so it updates the column width on resize without any other configuration.column.flex
.column.minWidth
and column.maxWidth
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const defaultColumns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultFlex: 1 },
{ name: 'firstName', header: 'Name', width: 120 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', width: 80 }
]
const App = () => {
const [columns, setColumns] = useState(defaultColumns)
const onColumnResize = useCallback(({ column, flex, width }) => {
const newColumns = columns.map(c => {
if (c.name === column.name) {
c = Object.assign({}, c, { width, flex })
}
return c
})
}, [columns])
return (
<div>
<div style={{marginBottom: 20}}>
First and last columns with fixed width
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
onColumnResize={onColumnResize}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
false
, browser text selection is disabled. Set this to true
to enable text selection in the <ReactDataGrid />
.columns.userSelect
, at column-level.<ReactDataGrid />
header, use columnHeaderUserSelect
.preventDefaultTextSelectionOnShiftMouseDown
related propimport React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name - try selecting text in cells', defaultFlex: 1, minWidth: 250, },
{ name: 'age', defaultFlex: 1, minWidth: 250, header: 'Cells in this col are always selectable - userSelect: true', userSelect: true }
]
const App = () => {
const [columnUserSelect, setColumnUserSelect] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={columnUserSelect} onChange={setColumnUserSelect}>
Enable browser text selection in cells
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnUserSelect={columnUserSelect}
columns={columns}
dataSource={people}
sortable={false}
/>
</div>
);
}
export default () => <App />
Bool
default: false
true
, it copies to clipboard a string compatible with spreadsheet editors. The default separator is '\t'
, see clipboardSeparator
.import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css';
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
minWidth: 80,
type: 'number',
},
{
name: 'name',
header: 'Name',
defaultFlex: 1,
minWidth: 150,
},
{
name: 'country',
header: 'Country',
defaultFlex: 1,
minWidth: 100,
defaultVisible: false,
},
{ name: 'city', header: 'City', defaultFlex: 1, minWidth: 150 },
{ name: 'age', header: 'Age', minWidth: 100, type: 'number' },
{ name: 'email', header: 'Email', defaultFlex: 1, minWidth: 150 },
{
name: 'student',
header: 'Student',
defaultFlex: 1,
render: ({ value }) => (value === true ? 'Yes' : 'No'),
},
];
const App = () => {
const [enableClipboard, setEnableClipboard] = useState(true);
const [
copySpreadsheetCompatibleString,
setCopySpreadsheetCompatibleString,
] = useState(true);
return (
<div>
<h3>Grid with copy spreadsheet compatible string</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableClipboard}
onChange={setEnableClipboard}
>Enable clipboard</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={copySpreadsheetCompatibleString}
onChange={setCopySpreadsheetCompatibleString}
>
Copy spreadsheet compatible string
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard={enableClipboard}
defaultCellSelection={{}}
style={gridStyle}
columns={columns}
dataSource={people}
copySpreadsheetCompatibleString={copySpreadsheetCompatibleString}
/>
</div>
);
};
export default () => <App />;
Array|Promise|Fn()=>Promise
default: undefined
<ReactDataGrid />
contents. The <ReactDataGrid />
supports both sync & async dataSource
.dataSource
, in the form of an array. The dataSource
items (the objects in the array) are not constrained to a specific scheme, but they need to have a property which can be used as a unique identifier (most often, this is called "id"
). When configuring the <ReactDataGrid />
, this property should be specified in the idProperty
. The properties in the dataSource
items, although not constrained to a scheme, will generally match the configured columns
.<ReactDataGrid />
supports async dataSource
which can be specified as a Promise
or a function returning a Promise
. Again, the rules of immutability apply, so make sure you pass a reference to the same promise/function when you want to render the same-exact dataSource
.dataSource
or as returned by the dataSource
function) should be resolved with two possible value types:data: Array
and count: Number
properties - this is generally useful when using remote data with pagination and the count represents the total number of records on the server (only a part of those are sent to the client via pagination).Promise
, dataSource
as a function can also return an array, for synchronous dataSource
that you want to have full control over (this function is passed info about sortInfo
, skip
and limit
).import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 500, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 40 },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, hedaer: 'Last Name' },
{ name: 'email', groupBy: false, defaultFlex: 1, header: 'Email' }
]
const loadData = ({ skip, limit, sortInfo }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo) : '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const dataSource = useCallback(loadData, [])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
pagination
defaultLimit={15}
defaultSkip={15}
pageSizes={[10, 15, 30]}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Number[2]
default: undefined
<ReactDataGrid />
(as opposed to row keyboard navigation). For row navigation, see defaultActiveIndex
or activeIndex
.activeCell
.<ReactDataGrid />
cell onActiveCellChange
is triggered.defaultActiveCell
should be an array of length 2
, the first value being the row index, while the second value is the column index of the activeCell
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 300 }
const defaultActiveCell = [4,1]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
const App = () => {
const [enableKeyboardNavigation, setEnableKeyboardNavigation] = useState(true);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={enableKeyboardNavigation} onChange={setEnableKeyboardNavigation}>
Enable keyboard navigation
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultActiveCell={defaultActiveCell}
enableKeyboardNavigation={enableKeyboardNavigation}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
<ReactDataGrid />
. This is an uncontrolled prop. For the controlled version, see activeIndex
.arrow up/down
, page up/down
and home/end
.<ReactDataGrid />
with keyboard navigation, as the active index is updated, the <ReactDataGrid />
is automatically scrolled to show the currently active row in the viewport.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 500 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', minWidth: 100, defaultFlex: 1, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultActiveIndex={1}
enableKeyboardNavigation={true}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
cellSelection
.idProperty
for that row, followed by a comma and by the name/id of corresponding column: <idProperty value>,<column id or name>
: eg "id1,firstName"
.multiSelect=false
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const defaultCellSelection = {"2,name": true, "2,city": true}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, resizable: false },
{ name: 'name', header: 'Name', defaultFlex: 1, sortable: false },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultWidth: 100, type: 'number' }
]
const App = () => {
const [cellSelection, setCellSelection] = useState(defaultCellSelection)
return (
<div>
<p>
Selected cells: {cellSelection.length == 0 ? 'none' : JSON.stringify(cellSelection)}.
</p>
<ReactDataGrid
idProperty="id"
defaultCellSelection={defaultCellSelection}
onCellSelectionChange={setCellSelection}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
collapsedGroups
"uk"
is a country shared by many records, and then grouped by city, with "London"
being the city value for many items, then "uk/London"
(a concatenation of the two, separated by groupPathSeparator
) is the key to be used in the collapsedGroups
object in order to render "London"
people as collapsed.groupPathSeparator
.onGroupCollapseChange
is triggered (whether controlled collapsedGroups
or uncontrolled defaultCollapsedGroups
is used).defaultCollapsedGroups=true
means all groups are collapsed.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 600 }
const defaultCollapsedGroups = { 'uk/London': true, 'usa': true }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultWidth: 140, header: 'Country' },
{ name: 'city', defaultWidth: 140, header: 'City' },
{ name: 'email', defaultWidth: 140, defaultFlex: 1, header: 'Email' }
]
const App = () => {
const [groupBy, setGroupBy] = useState(['country','city'])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultCollapsedGroups={defaultCollapsedGroups}
defaultGroupBy={groupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
defaultExpandedRows=true
!<ReactDataGrid />
should be rendered collapsed by default, when all other rows are expanded (defaultExpandedRows=true
). This is an uncontrolled prop. For the controlled version, see collapsedRows
renderRowDetails
in order to render the row details on expand.true
.onExpandedRowsChange
to be notified when the expanded/collapsed rows change.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const defaultCollapsedRows = { 1: true, 2: true }
const App = () => {
const [expandedRows, setExpandedRows] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => setExpandedRows(true)} style={{ marginRight: 10 }}>
Expand all
</Button>
<Button onClick={() => setExpandedRows({})}>
Collapse all
</Button>
</div>
<ReactDataGrid
idProperty="id"
expandedRows={expandedRows}
defaultCollapsedRows={defaultCollapsedRows}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
expandedGroups
"uk"
is a country shared by many records, and then grouped by city, with "London"
being the city value for many items, then "uk/London"
(a concatenation of the two, separated by groupPathSeparator
) is the key to be used in the expandedGroups
object in order to render "London"
people as expanded.groupPathSeparator
.onGroupCollapseChange
is triggered (whether controlled expandedGroups
or uncontrolled defaultExpandedGroups
is used).defaultExpandedGroups=true
means all groups are expanded.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 600 }
const defaultExpandedGroups = { 'uk/London': true, 'usa': true }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultWidth: 140, header: 'Country' },
{ name: 'city', defaultWidth: 140, header: 'City' },
{ name: 'email', defaultWidth: 140, defaultFlex: 1, header: 'Email' }
]
const App = () => {
const [groupBy, setGroupBy] = useState(['country','city'])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultExpandedGroups={defaultExpandedGroups}
defaultCollapsedGroups={true}
defaultGroupBy={groupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
should be rendered expanded by default. This is an uncontrolled prop. For the controlled version, see expandedNodes
true
.onExpandedNodesChange
to be notified when the expanded/collapsed nodes change.'3/1'
is specified as expanded, but its parent is not.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{
id: 1,
name: 'App store',
size: '4.5Mb'
},
{
id: 2,
name: 'iMovie',
size: '106Mb'
},
{
id: 3,
name: 'IRecall',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
nodes: [
{
id: 1,
name: 'Todo.md',
size: '2Kb'
},
{
id: 2,
name: 'Calendar.md',
size: '15.2Kb'
},
{ id: 3, name: 'Shopping list.csv',size: '20Kb' }
]
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{
id: 1,
name: 'Personal.xls',
size: '100Gb'
},
{ id: 2, name: 'Work.xls' }
]
},
{ id: 2, name: 'MacRestore.gzip' }
]
}
]
const defaultExpandedNodes = { 1: true, 2: true, '3/1': true }
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const App = () => {
return (
<div>
<p>
Specifying a node as expanded does not render its parent as expended.
</p>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Object|Boolean
default: undefined
<ReactDataGrid />
should be rendered expanded by default. This is an uncontrolled prop. For the controlled version, see expandedRows
renderRowDetails
in order to render the row details on expand.true
.multiRowExpand=false
.true
renders all rows as expanded. In this case, you can use defaultCollapsedRows
to indicate which rows (if any) should be rendered as collapsed by default.onExpandedRowsChange
to be notified when the expanded/collapsed rows change.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const expandedRows = { 2: true, 1: true }
const App = () => {
return (
<div>
<p>
The second and third row is expanded by default.
</p>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={expandedRows}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Array[Object]
default: undefined
<ReactDataGrid />
. When this is specified, unless enableFiltering
is false
, the <ReactDataGrid />
becomes filterable.filterValue
.onFilterValueChange
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, maxWidth: 100, type: 'number' },
{ name: 'name', defaultFlex: 1, minWidth: 200, maxWidth: 300, header: 'Name' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' },
{ name: 'country', defaultFlex: 1, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
<p>Delete the filters if you want to show all data. You can click the configure icon and then "Clear All"</p>
</div>
);
}
export default () => <App />
String[]
default: undefined
groupBy
since you don't have to hook onGroupByChange
callback prop and update the <ReactDataGrid />
when there are grouping changes. You can also use drag-and-drop to reorder group by columns. Or you can click the remove icon to ungroup by a specific column.<ReactDataGrid />
. See hideGroupByColumns
if you want to change that.age
column header to the grouping toolbar in the <ReactDataGrid />
and see grouping being updated.column.groupToString
function prop.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'country', defaultFlex: 1, header: 'Country' },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={['country']}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 50
<ReactDataGrid />
, when pagination
is enabled.limit
.onLimitChange
to get notified when the user changes the current page size from the pagination toolbar ComboBox.import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 500, marginTop: 10 }
const loadData = ({ skip, limit }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 40 },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultFlex: 1, header: 'Email' }
]
const App = () => {
const dataSource = useCallback(loadData, [])
return (
<div>
<ReactDataGrid
sortable={false}
idProperty="id"
style={gridStyle}
columns={columns}
pagination
dataSource={dataSource}
defaultLimit={100}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
loading
.dataSource
is used, the uncontrolled defaultLoading
is used by the <ReactDataGrid />
. If you are using the controlled loading
, you need to make sure the loading mask is displayed while fetching remote data.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'age', header: 'Age' }
]
const App = () => {
const [loading, setLoading] = useState(true)
const [dataSource, setDataSource] = useState([])
// Let's make this intentionally slow, in order to see the loading better
const mockTimeConsumingLoad = useCallback(() => {
const data = new Promise((resolve) => {
setTimeout(() => {
resolve([
{ name: 'John Grayner', age: 35, id: 0 },
{ name: 'Mary Stones', age: 25, id: 1 },
{ name: 'Robert Fil', age: 27, id: 2 },
{ name: 'Bob Margin', age: 17, id: 3 },
{ name: 'Hillary Wilson', age: 53, id: 4 },
{ name: 'Franklin Richardson', age: 37, id: 5 }
])
}, 2000)
})
setDataSource(data)
}, [])
return (
<div>
<p>
<Button onClick={mockTimeConsumingLoad}>
Start long loading...
</Button>
</p>
<div style={{marginBottom: 20}}>
<CheckBox
checked={loading}
onChange={setLoading}
>
Default loading
</CheckBox>
</div>
<ReactDataGrid
style={{ marginTop: 10, minHeight: 300 }}
idProperty="id"
columns={columns}
dataSource={dataSource}
defaultLoading={loading}
/>
</div>
);
}
export default () => <App />
String|Number|Object
default: undefined
<ReactDataGrid />
. This is an uncontrolled prop. For the controlled version, see selected
.string
or a number
as the value of this prop. The value of the prop should be the id of the row you want to show as selected (see idProperty
).idProperty
), while the values should be any truthy values.<ReactDataGrid />
and changes the selection, onSelectionChange
is called so you get a chance to update the value for the selected
accordingly.checkboxColumn
and a checkbox column will be displayed as the first column of the <ReactDataGrid />
and will be used for multiple selection.checkboxColumn
is used, checkboxOnlyRowSelect
might also be very handy in order to only update row selection when the selection checkboxes are toggled.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const defaultSelected = { 1: true, 2: true }
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' }
]
const App = () => {
const [selected, setSelected] = useState(null);
const onSelectionChange = useCallback(({ selected: selectedMap }) => {
setSelected(selectedMap)
}, [])
return (
<div>
<p>
Selected rows: {selected === null ? JSON.stringify(Object.keys(defaultSelected)) : JSON.stringify(Object.keys(selected))}.
</p>
<ReactDataGrid
idProperty="id"
defaultSelected={defaultSelected}
onSelectionChange={onSelectionChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 0
<ReactDataGrid />
, when pagination
is enabled.skip
.onSkipChange
is triggered, so the dataSource
(most often, a function when the <ReactDataGrid />
has remote pagination) can be reloaded with the correct skip
value.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 500, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 40 },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultFlex: 1, header: 'Email' }
]
const loadData = ({ skip, limit, sortInfo }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo) : '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then((data) => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const dataSource = useCallback(loadData, [])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
pagination
defaultLimit={15}
defaultSkip={45}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Object|Object[]
default: undefined
<ReactDataGrid />
. This is an uncontrolled prop. For the controlled version, see sortInfo
.<ReactDataGrid />
will sort the dataSource
internally, so no need to pass a sorted dataSource
.sortInfo
, see Controlled and uncontrolled sorting.dataSource
yourself, be it local or remote data source.defaultSortInfo
is easier to use as you don't have to worry about sorting yourself. In case of remote dataSource
(generally a function returning a Promise
), you need to make sure you send the correct sorting params to the server so as to sort the data server-side.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const defaultSortInfo = { name: 'age', dir: -1, type: 'number' }
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, sortable: false },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
const dataSource = [
{ name: 'Little Johnny', age: 8, id: 1 },
{ name: 'John Brown', age: 35, id: 2 },
{ name: 'Mary Stones', age: 35, id: 3 },
{ name: 'Robert Fil', age: 17, id: 4 },
{ name: 'Bob Margin', age: 17, id: 5 },
{ name: 'Hillary Wilson', age: 53, id: 6 },
{ name: 'Franklin Richardson', age: 37, id: 7 }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
defaultSortInfo={defaultSortInfo}
columns={columns}
dataSource={dataSource}
style={gridStyle}
/>
</div>
);
}
export default () => <App />
'asc' | 'desc'
default: undefined
defaultSortingDirection
is set to 'asc'
, the default sorting behaviour is to sort in ascending order, i.e. at the first click on the header cell, the column will be sorted in ascending order. When defaultSortingDirection
is set to 'desc'
, the default behavior is to sort in descending order.import React from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 };
const columns = [
{ name: 'id', header: 'Id', defaultWidth: 80, defaultVisible: false },
{
name: 'name',
sortable: false,
header: 'Name (column not sortable)',
defaultFlex: 1,
},
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 },
];
const dataSource = [
{ name: 'Little Johny', age: 8, id: 0 },
{ name: 'John Grayner', age: 35, id: 1 },
{ name: 'Mary Stones', age: 35, id: 2 },
{ name: 'Robert Fil', age: 17, id: 3 },
{ name: 'Bob Margin', age: 17, id: 4 },
{ name: 'Hillary Wilson', age: 53, id: 5 },
{ name: 'Franklin Richardson', age: 37, id: 6 },
];
const App = () => {
return (
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={dataSource}
defaultSortingDirection="desc"
/>
);
};
export default () => <App />;
Object
default: undefined
dataSource
and defaultSelected
.<ReactDataGrid />
rows should be rendered as unselected. When selected=true
(or defaultSelected=true
) , all items but those specified by this prop should be selected.defaultUnselected
object should be keyed using item ids, as specified by their idProperty
.unselected
.onSelectionChange({ selected, unselected })
to listen to changes in the selection.checkboxColumn=true
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 400, marginTop: 10 }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 70, header: 'Id', defualtVisible: false },
{ name: 'firstName', defaultWidth: 135, header: 'First Name' },
{ name: 'lastName', defaultWidth: 135, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultWidth: 135, header: 'Email' }
]
const loadData = ({ skip, limit }) => {
return fetch(DATASET_URL).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const [checkboxOnlyRowSelect, setCheckboxOnlyRowSelect] = useState(true);
const [selected, setSelected] = useState(true);
const [unselected, setUnselected] = useState({ 1: true, 3: true });
const dataSource = useCallback(loadData, [])
const onSelectionChange = useCallback(({ selected, unselected }) => {
setSelected(selected);
setUnselected(unselected)
}, [])
return (
<div>
<p>
Unselected rows: {unselected && Object.keys(unselected).length ? JSON.stringify(Object.keys(unselected)) : (selected === true ? 'none' : 'too many')}.
</p>
<div>
<CheckBox
checked={checkboxOnlyRowSelect}
onChange={setCheckboxOnlyRowSelect}
>
Update row select using checkbox clicks only
</CheckBox>
</div>
<ReactDataGrid
key={'grid-' + checkboxOnlyRowSelect}
idProperty="id"
style={gridStyle}
checkboxColumn
columns={columns}
checkboxOnlyRowSelect={checkboxOnlyRowSelect}
pagination
selected={selected}
defaultUnselected={unselected}
onSelectionChange={onSelectionChange}
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
.import React from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css';
import people from './people';
const gridStyle = { minHeight: 550 };
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, resizable: false },
{ name: 'name', header: 'Name', defaultFlex: 1, sortable: false },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultWidth: 100, type: 'number' },
];
const disabledRows = {
3: true,
4: true,
7: true,
}
const App = () => {
return (
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
disabledRows={disabledRows}
editable
checkboxColumn
/>
)
}
export default () => <App />;
Bool
default: false
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' }
]
const App = () => {
const [disableGroupByToolbar, toggle] = useState(false);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={!disableGroupByToolbar}
onChange={checked=>toggle(!checked)}
>
Show groupBy toolbar
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
columns={columns}
dataSource={people}
defaultGroupBy={['country']}
disableGroupByToolbar={disableGroupByToolbar}
/>
</div>
);
}
export default () => <App />
Bool|Function(editValue, cellProps)
default: false
<ReactDataGrid />
should have inline edit enabled or not.Promise
. In case a Promise
is returned, if it is rejected or resolved with false
, the cell is not editable. If the returned Promise
is resolved with true
, the cell is editable.columns.editable
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, editable: () => false, header: 'Name' },
{ name: 'country', header: 'Country', defaultFlex: 1,
editable: (editValue) => {
return Promise.resolve(editValue !== 'uk')
},
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
const [dataSource, setDataSource] = useState(people)
const [editable, setEditable] = useState(true)
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={editable}
onChange={setEditable}
>
Enable inline edit
</CheckBox>
</div>
<p>Name column not editable.</p>
<p>!!! Cells with "uk" are not editable !!!
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
editable={editable}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
String
default: "dblclick"
"dblclick"
. Possible values are "click"
and "dblclick"
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, editable: () => false, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
const [dataSource, setDataSource] = useState(people)
const [editOnSingleClick, setEditOnSingleClick] = useState(true)
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={editOnSingleClick}
onChange={setEditOnSingleClick}
>
Edit on click (not double click)
</CheckBox>
</div>
<p>editStartEvent can have one of those two values: "click" or "dblclick"
</p>
<p>Currently starting the edit on {editOnSingleClick? 'click':'dblclick'}
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
editStartEvent={editOnSingleClick ? "click" : "dblclick"}
onEditComplete={onEditComplete}
editable={true}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
React.Node|Fn()
default: "No records available"
<ReactDataGrid />
has no records,emptyText
), will be displayed centered inside the <ReactDataGrid />
viewport to provide feedback to the user.React.Node
(so any valid jsx) or a function returning anything renderable (React.Node
).import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const emptyText = <b style={{
padding: 8,
border: '1px solid #7986cb',
color: '#ef9a9a',
borderRadius: 4
}}>No contents here !!!</b>
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, minWidth: 80, header: 'Name' },
{ name: 'country', defaultFlex: 1, minWidth: 80, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 80, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
emptyText={emptyText}
columns={columns}
dataSource={[]}
/>
</div>
);
}
export default () => <App />
Bool
default: false
import React, { useCallback, useState } from 'react';
import DataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css';
import people from './people';
const gridStyle = { minHeight: 350 };
const minWidth: number = 160;
const columns = [
{
name: 'id',
header: 'ID',
type: 'number',
defaultWidth: 80,
defaultVisible: false,
},
{ name: 'firstName', header: 'First Name', flex: 1, minWidth },
{ name: 'city', header: 'City', flex: 1, minWidth },
{ name: 'email', header: 'Email', flex: 1, minWidth },
{ name: 'country', header: 'Country', flex: 1, minWidth },
{ name: 'age', header: 'Age', type: 'number', flex: 1, minWidth },
{
name: 'student',
header: 'Student',
render: ({ value }) => {
if (typeof value === 'boolean') {
return value ? 'Yes' : 'No';
}
return value;
},
minWidth,
},
{ name: 'birthDate', header: 'Birth Date', flex: 1, minWidth },
];
const App = () => {
const [dataSource, setDataSource] = useState(people);
const onEditComplete = useCallback(
({
value,
columnId,
rowIndex,
}) => {
const data = [...dataSource];
data[rowIndex][columnId] = value;
setDataSource(data);
},
[]
);
return (
<div>
<DataGrid
columns={columns}
idProperty="id"
style={gridStyle}
dataSource={dataSource}
defaultCellSelection={{}}
multiSelect
enableCellBulkUpdate
editable
onEditComplete={onEditComplete}
/>
</div>
);
};
export default () => <App />;
Bool
default: false
true
, enables copy-paste active row or selected cells to/from clipboard.import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css';
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
minWidth: 300,
type: 'number',
},
{
name: 'name',
header: 'Name',
defaultFlex: 1,
minWidth: 250,
},
{
name: 'country',
header: 'Country',
defaultFlex: 1,
minWidth: 100,
defaultVisible: false,
},
{ name: 'city', header: 'City', defaultFlex: 1, minWidth: 300 },
{ name: 'age', header: 'Age', minWidth: 150, type: 'number' },
{ name: 'email', header: 'Email', defaultFlex: 1, minWidth: 150 },
{
name: 'student',
header: 'Student',
defaultFlex: 1,
render: ({ value }) => (value === true ? 'Yes' : 'No'),
},
];
const App = () => {
const [enableClipboard, setEnableClipboard] = useState(true)
return (
<div>
<h3>Grid with copy/paste the active row</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableClipboard}
onChange={setEnableClipboard}
>Enable clipboard</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard={enableClipboard}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Bool
default: undefined
import React, { useState, useCallback } from 'react';
import '@inovua/reactdatagrid-enterprise/index.css';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import people from './people';
import flags from './flags';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
minWidth: 300,
type: 'number',
},
{ name: 'name', header: 'Name', defaultFlex: 1, minWidth: 250 },
{
name: 'city',
header: 'City',
defaultFlex: 1,
minWidth: 300,
editable: false,
},
{
name: 'age',
header: 'Age',
minWidth: 150,
type: 'number',
editable: true,
},
{
name: 'country',
header: 'Country',
defaultFlex: 1,
minWidth: 100,
render: ({ value }) => flags[value] ? flags[value] : value,
},
];
const App = () => {
const [dataSource, setDataSource] = useState(people);
const [cellSelection, setCellSelection] = useState({});
const onEditComplete = useCallback(
({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data);
},
[dataSource]
);
const onCopySelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
const onPasteSelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
return (
<div>
<h3>Grid with inline edit</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
editable={true}
columns={columns}
dataSource={dataSource}
cellSelection={cellSelection}
onCellSelectionChange={setCellSelection}
enableClipboard
onCopySelectedCellsChange={onCopySelectedCellsChange}
onPasteSelectedCellsChange={onPasteSelectedCellsChange}
enableClipboardForEditableCellsOnly
/>
</div>
);
};
export default () => <App />;
Bool
default: true
import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people';
import flags from './flags';
import Button from '@inovua/reactdatagrid-community/packages/Button';
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultWidth: 60,
type: 'number',
resizable: false,
},
{ name: 'name', header: 'Name', defaultWidth: 100 },
{
name: 'country',
header: 'Country',
defaultWidth: 100,
resizable: false,
render: ({ value }) =>
flags[value] ? flags[value] : value,
},
{ name: 'city', header: 'City', defaultWidth: 120 },
{ name: 'age', header: 'Age', defaultWidth: 100, type: 'number' },
];
const App = () => {
const [gridRef, setGridRef] = useState(null);
const [enableColumnAutosize, setEnableColumnAutosize] = useState(true);
return (
<div>
<h3>Grid with colums autosize</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={enableColumnAutosize} onChange={setEnableColumnAutosize}>Enable column autosize</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<Button
onClick={() => {
if (gridRef && gridRef.current.setColumnSizesToFit) {
gridRef.current.setColumnSizesToFit();
}
}}
>
Set column sizes to fit
</Button>
</div>
<ReactDataGrid
idProperty="id"
handle={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
enableColumnAutosize={enableColumnAutosize}
/>
</div>
);
};
export default () => <App />;
Bool
default: true
true
.import React, { useState }from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumberFilter from '@inovua/reactdatagrid-community/NumberFilter'
import SelectFilter from '@inovua/reactdatagrid-community/SelectFilter'
import DateFilter from '@inovua/reactdatagrid-community/DateFilter'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 600 }
const COUNTRIES = {
ca: 'Canada',
uk: 'United Kingdom',
usa: 'United States of America'
}
const countries = people.reduce((countries, p) => {
if (countries.filter(c => c.id == p.country).length) {
return countries
}
countries.push({
id: p.country,
label: COUNTRIES[p.country] || p.country
})
return countries
}, []);
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: '' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 },
{ name: 'city', operator: 'startsWith', type: 'string', value: '' },
{
name: 'birthDate',
operator: 'before',
type: 'date',
value: ''
},
{ name: 'country', operator: 'eq', type: 'select', value: 'ca' }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, enableColumnFilterContextMenu: true },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number', filterEditor: NumberFilter },
{
name: 'country',
header: 'Country',
defaultFlex: 1,
filterEditor: SelectFilter,
filterEditorProps: {
placeholder: 'All',
dataSource: countries
},
render: ({ value })=> flags[value]? flags[value]: value
},
{
name: 'birthDate',
header: 'Bith date',
defualtFlex: 1,
minWidth: 200,
enableColumnFilterContextMenu: false,
filterEditor: DateFilter,
filterEditorProps: (props, { index }) => {
// for range and notinrange operators, the index is 1 for the after field
return {
dateFormat: 'MM-DD-YYYY',
cancelButton: false,
highlightWeekends: false,
placeholder: index == 1 ? 'Created date is before...': 'Created date is after...'
}
},
render: ({ value, cellProps }) => {
return moment(value).format('MM-DD-YYYY')
}
},
{ name: 'city', header: 'City', defaultFlex: 1 },
];
const App = () => {
const [enableColumnFilterContextMenu, setEnableColumnFilterContextMenu] = useState(true);
return (
<div>
<h3>Grid with filter context menu control</h3>
<p>
The 'name' column has "enableColumnFilterContextMenu" setted to 'true'
and 'birthDate' has "enableColumnFilterContextMenu" setted to 'false'
at the column level.
</p>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableColumnFilterContextMenu}
onChange={setEnableColumnFilterContextMenu}
>Enable column filter context menu</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
enableColumnFilterContextMenu={enableColumnFilterContextMenu}
/>
</div>
)
}
export default () => <App />
Bool
default: undefined
import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise';
import '@inovua/reactdatagrid-enterprise/index.css';
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people';
import flags from './flags';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultWidth: 60,
type: 'number',
},
{ name: 'name', header: 'Name', defaultWidth: 100 },
{
name: 'country',
header: 'Country',
defaultWidth: 100,
render: ({ value }: { value: string }) =>
flags[value] ? flags[value] : value,
},
{
name: 'city',
header: 'City',
defaultWidth: 120,
},
{
name: 'age',
header: 'Age',
defaultWidth: 100,
type: 'number',
},
];
const App = () => {
const [enableColumnHover, setEnableColumnHover] = useState(true)
return (
<div>
<h3>Grid with column hover enabled</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableColumnHover}
onChange={setEnableColumnHover}
>Enable column hover</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
style={gridStyle}
columns={columns}
dataSource={people}
enableColumnHover={enableColumnHover}
/>
</div>
);
};
export default () => <App />;
Bool
default: undefined
true
, makes the <ReactDataGrid />
filterable if defaultFilterValue
or filterValue
is specified.false
, it will make the <ReactDataGrid />
unfilterable (even if defaultFilterValue
or filterValue
have been specified).<ReactDataGrid />
.onEnableFilteringChange
to allow the<ReactDataGrid />
to respond to the change.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1,
hedaer: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', hedear: 'Age' }
]
const App = () => {
const [enableFiltering, setEnableFiltering] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableFiltering}
onChange={setEnableFiltering}
>
Enable filtering
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
enableFiltering={enableFiltering}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
<ReactDataGrid />
is focused and there is an active row, arrow up/down
, page up/down
and home/end
can be used to change the current activeIndex
.defaultActiveIndex
or activeIndex
.activeCell
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'city', minWidth: 100, defaultFlex: 1, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
const App = () => {
const [enableKeyboardNavigation, setEnableKeyboardNavigation] = useState(true)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={enableKeyboardNavigation} onChange={setEnableKeyboardNavigation}>
Enable keyboard navigation
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultActiveIndex={2}
enableKeyboardNavigation={enableKeyboardNavigation}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
<ReactDataGrid />
.<ReactDataGrid />
is expandable if one of the following is specified:expandedRows
, defaultExpandedRows
, renderRowDetails
).import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const defaultExpandedRows = { 1: true }
const renderRowDetails = ({ data, toggleRowExpand }) => {
return <div style={{ padding: 20}}>
<h3><Button onClick={toggleRowExpand}>Collapse row</Button></h3>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const App = () => {
const [enableRowExpand, setEnableRowExpand] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableRowExpand}
onChange={setEnableRowExpand}
>
Enable row expand
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
renderRowDetails={renderRowDetails}
enableRowExpand={enableRowExpand}
style={gridStyle}
rowExpandHeight={400}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
enableSelection=true
or use the controlled selected
prop or the uncontrolled defaultSelected
prop.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const App = () => {
const [selected, setSelected] = useState(null);
const [enableSelection, setEnableSelection] = useState(true);
const onSelectionChange = useCallback(({ selected }) => {
setSelected(selected)
})
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableSelection}
onChange={setEnableSelection}
>
Enable selection
</CheckBox>
</div>
<p>
Selected row id: {selected === null ? 'none' : JSON.stringify(selected)}.
</p>
<ReactDataGrid
idProperty="id"
enableSelection={enableSelection}
onSelectionChange={onSelectionChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
true
.import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
const gridStyle = { minHeight: 750 };
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{ id: 1, name: 'App store', size: '4.5Mb' },
{ id: 2, name: 'iMovie', size: '106Mb' },
{ id: 3, name: 'IRecall', size: '200Mb' },
],
},
{
id: 2,
name: 'Documents',
nodes: [
{ id: 1, name: 'Todo.md', size: '2Kb' },
{ id: 2, name: 'Calendar.md', size: '15.2Kb' },
{ id: 3, name: 'Shopping list.csv', size: '20Kb' },
],
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{ id: 1, name: 'Personal.xls', size: '100Gb' },
{ id: 2, name: 'Work.xls' },
],
},
{ id: 2, name: 'MacRestore.gzip' },
],
},
{ id: 4, name: 'Movies' },
];
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 160 },
];
const App = () => {
const [rowReorderColumn, setRowReorderColumn] = useState(true);
const [enableTreeRowReorder, setEnableTreeRowReorder] = useState(true);
return (
<div>
<h3>TreeGrid with row reorder</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={rowReorderColumn} onChange={setRowReorderColumn}>
rowReorderColumn
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={enableTreeRowReorder} onChange={setEnableTreeRowReorder}>
enableTreeRowReorder
</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
theme="default-dark"
style={gridStyle}
columns={columns}
dataSource={treeData}
defaultExpandedNodes={{ 1: true, 2: true, 3: true, '3/1': true }}
rowReorderColumn={rowReorderColumn}
enableTreeRowReorder={enableTreeRowReorder}
/>
</div>
);
};
export default () => <App />;
Bool
default: true
true
.import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
const gridStyle = { minHeight: 750 };
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{ id: 1, name: 'App store', size: '4.5Mb' },
{ id: 2, name: 'iMovie', size: '106Mb' },
{ id: 3, name: 'IRecall', size: '200Mb' },
],
},
{
id: 2,
name: 'Documents',
nodes: [
{ id: 1, name: 'Todo.md', size: '2Kb' },
{ id: 2, name: 'Calendar.md', size: '15.2Kb' },
{ id: 3, name: 'Shopping list.csv', size: '20Kb' },
],
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{ id: 1, name: 'Personal.xls', size: '100Gb' },
{ id: 2, name: 'Work.xls' },
],
},
{ id: 2, name: 'MacRestore.gzip' },
],
},
{ id: 4, name: 'Movies' },
];
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 160 },
];
const App = () => {
const [rowReorderColumn, setRowReorderColumn] = useState(true);
const [enableTreeRowReorder, setEnableTreeRowReorder] = useState(true);
const [enableTreeRowReorderNestingChange, setEnableTreeRowReorderNestingChange] = useState(true);
return (
<div>
<h3>TreeGrid with row reorder</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={rowReorderColumn} onChange={setRowReorderColumn}>
rowReorderColumn
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={enableTreeRowReorder} onChange={setEnableTreeRowReorder}>
enableTreeRowReorder
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={enableTreeRowReorderNestingChange} onChange={setEnableTreeRowReorderNestingChange}>
enableTreeRowReorderNestingChange
</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
theme="default-dark"
style={gridStyle}
columns={columns}
dataSource={treeData}
defaultExpandedNodes={{ 1: true, 2: true, 3: true, '3/1': true }}
rowReorderColumn={rowReorderColumn}
enableTreeRowReorder={enableTreeRowReorder}
enableTreeRowReorderNestingChange={enableTreeRowReorderNestingChange}
/>
</div>
);
};
export default () => <App />;
Bool
default: true
enableTreeRowReorderParentChange
is true
, allows droppind a row to another parent. By default is true
.import React, { useState } from 'react';
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
const gridStyle = { minHeight: 750 };
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{ id: 1, name: 'App store', size: '4.5Mb' },
{ id: 2, name: 'iMovie', size: '106Mb' },
{ id: 3, name: 'IRecall', size: '200Mb' },
],
},
{
id: 2,
name: 'Documents',
nodes: [
{ id: 1, name: 'Todo.md', size: '2Kb' },
{ id: 2, name: 'Calendar.md', size: '15.2Kb' },
{ id: 3, name: 'Shopping list.csv', size: '20Kb' },
],
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{ id: 1, name: 'Personal.xls', size: '100Gb' },
{ id: 2, name: 'Work.xls' },
],
},
{ id: 2, name: 'MacRestore.gzip' },
],
},
{ id: 4, name: 'Movies' },
];
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 160 },
];
const App = () => {
const [rowReorderColumn, setRowReorderColumn] = useState(true);
const [enableTreeRowReorder, setEnableTreeRowReorder] = useState(true);
const [enableTreeRowReorderParentChange, setEnableTreeRowReorderParentChange] = useState(true);
return (
<div>
<h3>TreeGrid with row reorder</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={rowReorderColumn} onChange={setRowReorderColumn}>
rowReorderColumn
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={enableTreeRowReorder} onChange={setEnableTreeRowReorder}>
enableTreeRowReorder
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={enableTreeRowReorderParentChange} onChange={setEnableTreeRowReorderParentChange}>
enableTreeRowReorderParentChange
</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
theme="default-dark"
style={gridStyle}
columns={columns}
dataSource={treeData}
defaultExpandedNodes={{ 1: true, 2: true, 3: true, '3/1': true }}
rowReorderColumn={rowReorderColumn}
enableTreeRowReorder={enableTreeRowReorder}
enableTreeRowReorderParentChange={enableTreeRowReorderParentChange}
/>
</div>
);
};
export default () => <App />;
Fn({data})
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{
id: 'desc',
header: 'Description',
defaultFlex: 2,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
},
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultWidth: 100 },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 },
]
const expandColumn = ({ data }) => {
if (data.country === 'uk') {
return 'desc'
}
}
const App = () => {
return (
<ReactDataGrid
idProperty="id"
expandColumn={expandColumn}
style={gridStyle}
columns={columns}
dataSource={people}
/>
);
}
export default () => <App />
Object | true
default: undefined
defaultExpandedGroups
.collapsedGroups
/defaultCollapsedGroups
"uk"
is a country shared by many records, and then grouped by city, with "London"
being the city value for many items, then "uk/London"
(a concatenation of the two, separated by groupPathSeparator
) is the key to be used in the expandedGroups
object in order to render "London"
people as expanded.groupPathSeparator
.collapsedGroups
onGroupCollapseChange
is triggered (whether controlled collapsedGroups
or uncontrolled defaultCollapsedGroups
is used).expandedGroups
, make sure you update the expandedGroups
value when onGroupCollapseChange
is triggered, but also collapsedGroups
collapsedGroups
and expandedGroups
should be both either controlled or uncontrolled.expandedGroups=true
means all groups are expanded (except those explicitly specified by collapsedGroups
).collapsedGroups=true
means all groups are collapsed, except those explicitly specified in expandedGroups
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultWidth: 140, header: 'Country' },
{ name: 'city', defaultWidth: 140, header: 'City' },
{ name: 'email', defaultWidth: 140, defaultFlex: 1, header: 'Email' }
]
const App = () => {
const [groupBy, setGroupBy] = useState(['country','city'])
const [expandedGroups, setExpandedGroups] = useState({ 'uk/London': true, 'usa': true })
const [collapsedGroups,setCollapsedGroups ] = useState(true)
const onGroupCollapseChange = useCallback((collapsedGroups, expandedGroups) => {
setCollapsedGroups(collapsedGroups)
setExpandedGroups(expandedGroups)
}, [])
return (
<div>
<p>
Expanded groups: {JSON.stringify(Object.keys(expandedGroups))}.
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
collapsedGroups={collapsedGroups}
expandedGroups={expandedGroups}
onGroupCollapseChange={onGroupCollapseChange}
defaultGroupBy={groupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
(with tree functionality) should be rendered expanded. This is a controlled prop. For the uncontrolled version, see defaultExpandedNodes
true
.<ReactDataGrid />
will assign a unique id
(see idProperty
) to all nodes based on the path from the root node to the respective node. This id value is built by joining all the parent ids using the /
character (as defined by nodePathSeparator
prop). So, for example, expandedNodes
could look like this for a grid: expandedNodes={ 1: true, 3: true, '3/1': true', '3/2/1': true }
.onExpandedNodesChange
to be notified when the expanded/collapsed nodes change. When using this controlled prop, make sure you update it's value when onExpandedNodesChange
is called.'3/1'
is specified as expanded, but its parent is not.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{
id: 1,
name: 'App store',
size: '4.5Mb'
},
{
id: 2,
name: 'iMovie',
size: '106Mb'
},
{
id: 3,
name: 'IRecall',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
nodes: [
{
id: 1,
name: 'Todo.md',
size: '2Kb'
},
{
id: 2,
name: 'Calendar.md',
size: '15.2Kb'
},
{ id: 3, name: 'Shopping list.csv',size: '20Kb' }
]
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{
id: 1,
name: 'Personal.xls',
size: '100Gb'
},
{ id: 2, name: 'Work.xls' }
]
},
{ id: 2, name: 'MacRestore.gzip' }
]
}
]
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 120 }
]
const App = () => {
const [expandedNodes, setExpandedNodes] = useState({ 1: true, 2: true, '3/1': true });
const onExpandedNodesChange = useCallback(({ expandedNodes }) => {
setExpandedNodes(expandedNodes)
}, [])
return (
<div>
<p>
Expanded nodes: {expandedNodes == null ? 'none' : JSON.stringify(expandedNodes, null, 2)}.
</p>
<ReactDataGrid
treeColumn="name"
expandedNodes={expandedNodes}
onExpandedNodesChange={onExpandedNodesChange}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Object|Boolean
default: undefined
<ReactDataGrid />
should be rendered expanded. This is a controlled prop. For the uncontrolled version, see defaultExpandedRows
renderRowDetails
in order to render the row details on expand.true
.multiRowExpand=false
.true
renders all rows as expanded. In this case, you can use collapsedRows
to indicate which rows (if any) should be rendered as collapsed.onExpandedRowsChange
to be notified when the expanded/collapsed rows change. When using this controlled prop, make sure you update it's value when onExpandedRowsChange
is called.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const App = () => {
const [expandedRows, setExpandedRows] = useState({ 1: true, 2: true });
const [collapsedRows, setCollapsedRows] = useState(null);
const onExpandedRowsChange = useCallback(({ expandedRows, collapsedRows }) => {
setExpandedRows(expandedRows);
setCollapsedRows(collapsedRows);
}, [])
return (
<div>
<div>
<Button onClick={() => setExpandedRows(true)} style={{ marginRight: 10 }}>
Expand all
</Button>
<Button onClick={() => setExpandedRows({})}>
Collapse all
</Button>
</div>
<p>
Expanded rows: {expandedRows == null ? 'none' : JSON.stringify(expandedRows, null, 2)}.
</p>
{expandedRows === true ? <p>
Collapsed rows: {collapsedRows == null ? 'none' : JSON.stringify(collapsedRows, null, 2)}.
</p> : null}
<ReactDataGrid
idProperty="id"
expandedRows={expandedRows}
collapsedRows={collapsedRows}
onExpandedRowsChange={onExpandedRowsChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
locked
columns. Defaults to false
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 600 }
const renderGroupTitle = (valueParam, { data }) => {
const { value, name, fieldPath } = data
if (name === 'country') {
return 'This is the current country for the group:' + value +'.'
}
if (name === 'age') {
return 'Aged: ' + value +'.'
}
return value
}
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name', groupBy: false, defaultLocked: true },
{ name: 'country', defaultFlex: 1, defaultLocked: true, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' },
{ name: 'email', defaultFlex: 1, defaultLocked: 'end', header: 'Email' },
]
const App = () => {
const [defaultGroupBy, setDefaultGroupBy] = useState(['country'])
const [expandGroupTitle, setExpandGroupTitle] = useState(false)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={expandGroupTitle}
onChange={setExpandGroupTitle}
>
Expand group title
</CheckBox>
</div>
<ReactDataGrid
key={'grid-' + expandGroupTitle}
idProperty="id"
style={gridStyle}
renderGroupTitle={renderGroupTitle}
expandGroupTitle={expandGroupTitle}
defaultGroupBy={defaultGroupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
const gridStyle = { minHeight: 550 }
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{
id: 1,
name: 'App store',
size: '4.5Mb',
nodes: null
},
{
id: 2,
name: 'iMovie',
size: '106Mb',
nodes: null
},
{
id: 3,
name: 'IRecall',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
nodes: [
{
id: 1,
name: 'Todo.md',
size: '2Kb'
},
{
id: 2,
name: 'Calendar.md',
size: '15.2Kb'
},
{ id: 3, name: 'Shopping list.csv',size: '20Kb' }
]
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{
id: 1,
name: 'Personal.xls',
size: '100Gb'
},
{ id: 2, name: 'Work.xls' }
]
},
{ id: 2, name: 'MacRestore.gzip' }
]
}
]
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const defaultExpandedNodes = { 1: true }
const App = () => {
const [showTools, setShowTools] = useState(true);
const [expandOnMouseDown, setExpandOnMouseDown] = useState(true);
const renderCollapseTool = ({ domProps, size }) => {
const style = Object.assign(domProps.style, { fill: 'red' });
return (
<svg
{...domProps}
height={size}
viewBox="0 0 24 24"
width={size}
style={style}
>
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
</svg>
);
};
const renderExpandTool = ({ domProps, size }) => {
const style = Object.assign(domProps.style, { fill: 'red' });
return (
<svg
{...domProps}
height={size}
viewBox="0 0 24 24"
width={size}
style={style}
>
<path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" />
</svg>
);
};
return (
<div>
<h3>TreeGrid with exand/collapse on mouse down</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={showTools} onChange={setShowTools}>Show tools</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={expandOnMouseDown} onChange={setExpandOnMouseDown}>Enable expand/collapse node on mouse down</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
renderTreeCollapseTool={showTools ? renderCollapseTool : null}
renderTreeExpandTool={showTools ? renderExpandTool : null}
expandOnMouseDown={expandOnMouseDown}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
currently supports for filtering:"string"
- string/text filter. The following operators are supported:"contains"
- contains. Will filter the dataSource
to only include items that for the current column have a value that contains the filter value."notContains"
- not contains. Will filter the dataSource
to only include items that for the current column have a value that does not contain the filter value."eq"
- equals. Will filter the dataSource
to only include items that for the current column have a value equal to the filter value."neq"
- not equals. Will filter the dataSource
to only include items that for the current column have a value not equal to the filter value."empty"
- empty. Will filter the dataSource
to only include items that for the current column have an empty value."notEmpty"
- not empty. Will filter the dataSource
to only include items that for the current column have a non empty value."startsWith"
- starts with. Will filter the dataSource
to only include items that for the current column have a value that starts with the filter value."endsWith"
- ends with. Will filter the dataSource
to only include items that for the current column have a value that ends with the filter value."number"
- numeric filter. The following operators are supported:"eq"
- equals. Will filter the dataSource
to only include items that for the current column have a value equal to the filter value."neq"
- not equals. Will filter the dataSource
to only include items that for the current column have a value not equal to the filter value."gt"
- greater than. Will filter the dataSource
to only include items that for the current column have a value greater than the filter value."gte"
- greater than or equal. Will filter the dataSource
to only include items that for the current column have a value greater than or equal to the filter value."lt"
- less than. Will filter the dataSource
to only include items that for the current column have a value less than the filter value."lte"
- less than or equal. Will filter the dataSource
to only include items that for the current column have a value less than or equal to the filter value."boolean"
- boolean filter. The following operators are supported:"eq"
- equals. Will filter the dataSource
to only include items that for the current column have a value equal to the filter value."neq"
- not equals. Will filter the dataSource
to only include items that for the current column have a value not equal to the filter value.filterValue
array. Make sure you specify an operator supported by the filter type of your choice.filterTypes
is just an object with keys being the name of the filter types and values being object describing the filter type.ReactDataGrid.defaultProps.filterTypes = {
string: {
type: 'string',
emptyValue: '',
operators: [
{
'contains',
fn: ({ value, filterValue, data }) => {
return !filterValue ?
true :
value.indexOf(filterValue) != -1;
}
},
{
name: 'eq', fn: ({ value, filterValue }) => value===filterValue
},
... other operators
]
},
boolean: {
type: 'boolean',
operators: [...]
}
... other filter types
}
filterTypes
default prop value. You can either enhance the <ReactDataGrid />
default props or pass another totally different filterTypes
prop to get the desired filtering behavior.date
would look like the following:ReactDataGrid.defaultProps.filterTypes.date = {
type: 'date',
emptyValue: '',
operators: [
{
name: 'lt',
fn: ({ value, filterValue, data }) => {
return !filterValue ?
true :
value < filterValue
}
},
{
name: 'eq', fn: ({ value, filterValue }) => value === filterValue
},
... other operators
]
}
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterTypes = Object.assign({}, ReactDataGrid.defaultProps.filterTypes, {
country: {
name: 'country',
emptyValue: '',
operators: [
{
name: 'europe',
fn: ({ value, filterValue, data }) => {
const isInEurope = value != 'usa' && value != 'ca'
return filterValue === 'true' ?
isInEurope :
!isInEurope
}
}
]
}
});
const filterValue = [
{ name: 'country', operator: 'europe', type: 'country', value: 'true' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, maxWidth: 100, type: 'number' },
{ name: 'name', defaultFlex: 1, maxWidth: 200, header: 'Name' },
{ name: 'country',
header: 'Country',
defaultFlex: 1,
filterEditor: 'bool',
render: ({ value })=> flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
filterTypes={filterTypes}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ value, filterValue, data })
default: undefined
===
to the emptyValue
for the current filterType, the filtering function is skipped and no longer called (so all items pass the filter)import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterTypes = Object.assign({}, ReactDataGrid.defaultProps.filterTypes, {
country: {
name: 'country',
emptyValue: null,
operators: [
{
name: 'europe',
fn: ({ value, filterValue, data }) => {
const isInEurope = value != 'usa' && value != 'ca'
return filterValue ?
isInEurope :
!isInEurope
}
}
]
}
});
filterValue = [
{ name: 'country', operator: 'europe', type: 'country', value: null },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country',
header: 'Country',
flex: 1,
filterEditor: 'bool',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
];
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
filterTypes={filterTypes}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Array
default: undefined
boolean
filters have the operators array equal to the following:[
{
name: 'eq',
fn: ({ value, filterValue, data }) => {
return filterValue != null ? filterValue === value : true;
}
},
{
name: 'neq',
fn: ({ value, filterValue, data }) => {
return filterValue != null ? filterValue !== value : true;
}
}
]
operators.fn
for details on the filtering function.Fn({ value, filterValue, data })
default: undefined
dataSource
pass the filtering.value
(the cell value for the current column), filterValue
(the value in the filter) and data
(the current row data object) as keys.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterTypes = Object.assign({}, ReactDataGrid.defaultProps.filterTypes, {
country: {
name: 'country',
operators: [
{
name: 'europe',
fn: ({ value, filterValue, data }) => {
if (filterValue == null) {
return true
}
const isInEurope = value != 'usa' && value != 'ca'
return filterValue ?
isInEurope :
!isInEurope
}
}
]
}
});
const defaultFilterValue = [
{ name: 'country', operator: 'europe', type: 'country', value: true },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, maxWidth: 200, header: 'Name' },
{ name: 'country',
header: 'Country',
defaultFlex: 1,
filterEditor: 'bool',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
filterTypes={filterTypes}
defaultFilterValue={defaultFilterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ value, filterValue, data })
default: undefined
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const filterTypes = Object.assign({}, ReactDataGrid.defaultProps.filterTypes, {
country: {
name: 'country',
emptyValue: null,
operators: [
{
name: 'europe',
fn: ({ value, filterValue, data }) => {
const isInEurope = value != 'usa' && value != 'ca'
return filterValue ?
isInEurope :
!isInEurope
}
}
]
}
});
const filterValue = [
{ name: 'country', operator: 'europe', type: 'country', value: null },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country',
header: 'Country',
defaultFlex: 1,
filterEditor: 'bool',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
];
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
filterTypes={filterTypes}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Array[Object]
default: undefined
<ReactDataGrid />
. When this is specified, unless enableFiltering
is false
, the <ReactDataGrid />
becomes filterable.filterValue
is used, it's the user's responsibility to filter out the dataSource
!!!onFilterValueChange
). For the uncontrolled version, see defaultFilterValue
.filterValue
is an array that holds the filter value for each filterable column. The objects in this array should have the following properties:name
- the name (or id) of the column for which the current filter is applied.type
- the type of the filter to apply. Valid types for now are: string
, bool
(or its alias, boolean
) and number
. If you want to add more filter types, see filterTypes
.operator
- the operator to use for filtering. It needs to be one of the operators supported by the specified filter type.value
- the actual value to be used for filtering.emptyValue
(optional) - can specify a value for which the filter will not apply. Overrides filterTypes.emptyValue
.fn({ value, filterValue, data})
(optional) - can specify a custom filtering function. Overrides filterTypes.operators.fn
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import filter from '@inovua/reactdatagrid-community/filter'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const defaultFilterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' },
{ name: 'country', defaultFlex: 1, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' }
]
const App = () => {
const initialData = useCallback(filter(people, defaultFilterValue), []);
const [dataSource, setDataSource] = useState(initialData);
const [filterValue, setFilterValue] = useState(defaultFilterValue);
const onFilterValueChange = useCallback((filterValue) => {
const data = filter(people, filterValue)
setFilterValue(filterValue);
setDataSource(data);
}, [])
return (
<div>
<p>
Current filter value: {JSON.stringify(filterValue, null, 2)}
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onFilterValueChange={onFilterValueChange}
filterValue={filterValue}
columns={columns}
dataSource={dataSource}
/>
<p>Delete the filters if you want to show all data. You can click the configure icon and then "Clear All"</p>
</div>
);
}
export default () => <App />
default: undefined
<ReactDataGrid />
- see footer page for more examples.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600, marginTop: 10 }
let cities;
const footerRows = [
{
render: {
population: ({ summary }) => <div>Total population: <b>{summary}</b>.</div>
}
}
]
const summaryReducer = {
initialValue: 0,
reducer: (accumulator, item) => accumulator + (item.population || 0)
}
const columns = [
{ name: 'name', defaultFlex: 1, header: 'City', },
{ name: 'country', defaultFlex: 1, header: 'Country'},
{
name: 'population',
type: 'number',
defaultFlex: 1,
header: 'Population'
}
];
const App = () => {
return (
<div>
<h3>The population column has a summary - shown in corresponding footer column.</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={cities}
summaryReducer={summaryReducer}
footerRows={footerRows}
/>
</div>
);
}
cities = [
{
id: 'ny',
country: 'USA',
name: 'New York City',
population: 1000
},
{
id: 'la',
country: 'USA',
name: 'Los Angeles',
population: 150
},
{
id: 'paris',
country: 'France',
name: 'Paris',
population: 2000
},
{
id: 'london',
name: 'London',
country: 'UK',
population: 3000
},
{
id: 'SF',
name: 'San Francisco',
country: 'USA',
population: 3900
},
{
id: 'ly',
name: 'Lyon',
country: 'France',
population: 980
},
{
id: 'ma',
name: 'Manchester',
country: 'UK',
population: 2000
}
]
export default () => <App />
Object|number|() => number
default: undefined
colspan
gives you complete flexibility over the functionality.if (typeof colspan === 'function') {
colspan = colspan(
{
column,
columnIndex,
row,
rowIndex,
},
computedProps
);
}
column
being rendered and any other additional props you might needimport React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600, marginTop: 10 }
let cities;
const footerRows = [
{
render: {
population: ({ summary }) => <div>Population min: {summary.min}</div>
},
country: <b>Nothing to render</b>
},
{
render: {
population: ({ summary }) => <div>Population max: {summary.max}</div>
}
},
{
render: {
population: ({ summary }) => <div>Population average: {summary.avg}</div>
}
},
{
render: {
name: (_, computedProps) => {
return <div>Selected rows: <b>{computedProps.computedSelectedCount}</b></div>
}
},
colspan: {
name: (_, computedProps) => computedProps.visibleColumns.length
},
cellStyle: ({ column }, computedProps) => {
if (column.name !== 'name'){
return
}
const style = {
paddingTop: 20,
paddingBottom: 20
}
if (computedProps.computedSelectedCount) {
style.background = '#ff5b5b'
style.color = 'white'
}
return style
}
}
]
const summaryReducer = {
initialValue: {
min: Infinity,
max: 0,
avg: 0
},
reducer: (accumulator, item) => {
if (item.population) {
return {
min: Math.min(accumulator.min, item.population),
max: Math.max(accumulator.max, item.population),
avg: accumulator.avg + item.population
}
}
return accumulator
},
complete: (accumulator, arr) => {
return Object.assign({}, accumulator, {
avg: Math.round(accumulator.avg / arr.length),
})
}
}
const columns = [
{ name: 'name', defaultFlex: 1, header: 'City', hideable: false, draggable: false },
{ name: 'country', defaultFlex: 1, header: 'Country'},
{
name: 'population',
type: 'number',
defaultFlex: 1,
groupBy: false,
header: 'Population'
}
]
const App = () => {
return (
<div>
<h3>Footer with custom render and colspan</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
dataSource={cities}
summaryReducer={summaryReducer}
footerRows={footerRows}
/>
</div>
);
}
cities = [
{
id: 'ny',
country: 'USA',
name: 'New York City',
population: 1000
},
{
id: 'la',
country: 'USA',
name: 'Los Angeles',
population: 150
},
{
id: 'paris',
country: 'France',
name: 'Paris',
population: 2000
},
{
id: 'london',
name: 'London',
country: 'UK',
population: 3000
},
{
id: 'SF',
name: 'San Francisco',
country: 'USA',
population: 3900
},
{
id: 'ly',
name: 'Lyon',
country: 'France',
population: 980
},
{
id: 'ma',
name: 'Manchester',
country: 'UK',
population: 2000
}
]
export default () => <App />
{[columnId]: ReactNode|() => ReactNode}|ReactNode|() => ReactNode
default: undefined
ReactNode
values. Using a function gives you the flexibility to decide what to render at run-time - for example, the first argument will have a summary
property which will hold the value computed via the configured summaryReducer
.render(
{
summary,
row,
rowIndex,
column,
columnIndex,
},
computedProps
);
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600, marginTop: 10 }
let cities;
const footerRows = [
{
render: {
name: <b>Nothing to render here</b>,
population: ({ summary }) => <div>Total population: <b>{summary}</b>.</div>
}
}
]
const summaryReducer = {
initialValue: 0,
reducer: (accumulator, item) => accumulator + (item.population || 0)
}
const columns = [
{ name: 'name', defaultFlex: 1, header: 'City', },
{ name: 'country', defaultFlex: 1, header: 'Country'},
{
name: 'population',
type: 'number',
defaultFlex: 1,
header: 'Population'
}
]
const App = () => {
return (
<div>
<h3>The population column has a summary - shown in corresponding footer column.</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={cities}
summaryReducer={summaryReducer}
footerRows={footerRows}
/>
</div>
);
}
cities = [
{
id: 'ny',
country: 'USA',
name: 'New York City',
population: 1000
},
{
id: 'la',
country: 'USA',
name: 'Los Angeles',
population: 150
},
{
id: 'paris',
country: 'France',
name: 'Paris',
population: 2000
},
{
id: 'london',
name: 'London',
country: 'UK',
population: 3000
},
{
id: 'SF',
name: 'San Francisco',
country: 'USA',
population: 3900
},
{
id: 'ly',
name: 'Lyon',
country: 'France',
population: 980
},
{
id: 'ma',
name: 'Manchester',
country: 'UK',
population: 2000
}
]
export default () => <App />
Bool
default: true
true
, the <ReactDataGrid />
will assign a unique id
(see idProperty
) to all nodes based on the path from the root node to the respective node. This id value is built by joining all the parent ids using the /
character (as defined by nodePathSeparator
prop). In this case, the ids of each node in the dataSource
should only be unique among node siblings.false
, all nodes in the tree should have unique ids (unique in all dataSource, not only unique sibling ids). In this case, the <ReactDataGrid />
does not modify the ids of nodes.String[]
default: undefined
defaultGroupBy
since you don't have to hook onGroupByChange
callback prop and update the <ReactDataGrid />
when there are grouping changes. You can also use drag-and-drop to reorder group by columns. Or you can click the remove icon to ungroup by a specific column.<ReactDataGrid />
. See hideGroupByColumns
if you want to change that.locked
columns, you might want to use expandGroupTitle=true
to make sure the group title expands to occupy the whole available group row.renderGroupTitle
useful in order to customize what gets rendered as the title of a group.column.groupToString
function prop.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 50 },
{ name: 'firstName', header: 'First Name', defaultWidth: 150 },
{ name: 'lastName', header: 'Last Name', defaultWidth: 150 },
{ name: 'email', header: 'Email', groupBy: false, defaultWidth: 150 },
{
name: 'permissionToCall',
header: 'Permission to call',
defaultWidth: 200,
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value ? 'Can be called' : 'Cannot be called'
}
];
const loadData = ({ skip, limit, sortInfo, groupBy }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo) : '') + (groupBy && groupBy.length ? '&groupBy=' + groupBy : '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const [stickyGroupRows, setStickyGroupRows] = useState(false);
const [groupBy, setGroupBy] = useState([]);
const dataSource = useCallback(loadData, [])
return (
<div>
<p><Button onClick={() => setGroupBy(['permissionToCall', 'lastName'])}>Group by permissionToCall and lastName</Button></p>
<p><Button onClick={() => setGroupBy([])}>Remove grouping</Button></p>
<p>In this example, you cannot group by id or email.</p>
<div style={{marginBottom: 20}}>
<CheckBox
checked={stickyGroupRows}
onChange={setStickyGroupRows}
>
Use sticky group rows
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
stickyGroupRows={stickyGroupRows}
groupBy={groupBy}
onGroupByChange={setGroupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool|Object
default: undefined
<ReactDataGrid />
. When groupColumn=true
, the checkbox column with the default configuration will be displayed. However, you can use an object as the value for this prop, so you can configure any column properties just like for a normal <ReactDataGrid />
column.groupColumn.renderGroupValue
if you want to customize how the group value is rendered in the group column.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 400 }
const groupColumn = {
renderGroupValue: ({ value }) => value === 'true'? 'Yes': value === 'false' ? 'No': value
}
const columns = [
{ name: 'id', type: 'number', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultFlex: 1, header: 'Email' },
{
name: 'permissionToCall', minWidth: 80,
header: 'Permission to call',
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value === true || value === 'true' ? 'Calls allowed' : 'No calls allowed'
}
]
const loadData = ({ sortInfo }) => {
return fetch(DATASET_URL + '?skip=0&limit=20&sortInfo='+JSON.stringify(sortInfo))
.then(response => response.json())
}
const App = () => {
const [stickyGroupRows, setStickyGroupRows] = useState(false);
const [showGroupColumn, setShowGroupColumn] = useState(false);
const [groupBy, setGorupBy] = useState(['permissionToCall'])
const dataSource = useCallback(loadData, [])
return (
<div>
<h3>GroupBy example with default grouping</h3>
<div style={{marginBottom: 20}}>
<CheckBox
checked={stickyGroupRows}
onChange={setStickyGroupRows}
>
Use sticky group rows
</CheckBox>
</div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={showGroupColumn}
onChange={setShowGroupColumn}
>
Use dedicated group column
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
groupColumn={showGroupColumn? groupColumn: null}
stickyGroupRows={stickyGroupRows}
defaultGroupBy={groupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn({ value, data, groupSummary })
default: undefined
groupColumn=true
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 400 }
const groupColumn = {
renderGroupValue: ({ value }) => value === 'true'? 'Yes': value === 'false' ? 'No': value
}
const columns = [
{ name: 'id', type: 'number', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'lastName', defaultFlex: 1, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultFlex: 1, header: 'Email' },
{
name: 'permissionToCall', minWidth: 80,
header: 'Permission to call',
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value === true || value === 'true' ? 'Calls allowed' : 'No calls allowed'
}
]
const loadData = ({ sortInfo }) => {
return fetch(DATASET_URL + '?skip=0&limit=20&sortInfo='+JSON.stringify(sortInfo))
.then(response => response.json())
}
const App = () => {
const [stickyGroupRows, setStickyGroupRows] = useState(false);
const [showGroupColumn, setShowGroupColumn] = useState(false);
const [groupBy, setGorupBy] = useState(['permissionToCall'])
const dataSource = useCallback(loadData, [])
return (
<div>
<h3>GroupBy example with default grouping</h3>
<div style={{marginBottom: 20}}>
<CheckBox
checked={stickyGroupRows}
onChange={setStickyGroupRows}
>
Use sticky group rows
</CheckBox>
</div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={showGroupColumn}
onChange={setShowGroupColumn}
>
Use dedicated group column
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
groupColumn={showGroupColumn? groupColumn: null}
stickyGroupRows={stickyGroupRows}
defaultGroupBy={groupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
String
default: undefined
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 600 }
const groups = [{ name: 'permission', header: 'Permission' }]
const columns = [
{ name: 'id', type: 'number', defaultWidth: 50, header: 'Id', defaultVisible: false },
{
name: 'permissionToCall',
header: 'Permission to call',
defaultWidth: 200,
group: 'permission',
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value ? 'Can be called' : 'Cannot be called'
},
{ name: 'firstName', groupBy: false, defaultWidth: 150, header: 'First Name' },
{ name: 'lastName', defaultWidth: 150, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultWidth: 150, header: 'Email' }
]
const loadData = ({ skip, limit, sortInfo, groupBy }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo) : '') + (groupBy && groupBy.length ? '&groupBy=' + groupBy : '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
const App = () => {
const [groupBy, setGroupBy] = useState(['permissionToCall'])
const dataSource = useCallback(loadData, [])
return (
<div>
<p>In this example, you cannot group by first name or email.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
groupBy={groupBy}
groups={groups}
hideGroupByColumns={false}
groupForGroupColumns="permission"
onGroupByChange={setGroupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Number
default: 30
columns
automatically generated for grouping.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import ComboBox from '@inovua/reactdatagrid-community/packages/ComboBox'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', groupBy: false, type: 'number', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'firstName', defaultWidth: 150, header: 'First Name' },
{ name: 'lastName', defaultWidth: 150, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultWidth: 150, header: 'Email' },
{
name: 'permissionToCall', defaultWidth: 200,
header: 'Permission to call',
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value ? 'Can be called' : 'Cannot be called'
}
]
const loadData = ({ skip, limit, sortInfo, groupBy }) => {
return fetch(DATASET_URL + '?skip='+skip + '&limit='+limit+(sortInfo ? '&sortInfo='+JSON.stringify(sortInfo) : '') + (groupBy && groupBy.length ? '&groupBy=' + groupBy : '')).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data=> {
return { data, count: parseInt(totalCount) };
})
})
}
const nestingSizeDataSource = [
{ id: 30, label: 'Size: 30px' },
{ id: 50, label: 'Size: 50px' },
{ id: 70, label: 'Size: 70px' },
{ id: 100, label: 'Size: 100px' },
{ id: 150, label: 'Size: 150px' },
]
const App = () => {
const [groupBy, setGroupBy] = useState(['permissionToCall'])
const [groupNestingSize, setGroupNestingSize] = useState(50)
const dataSource = useCallback(loadData, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
Group nesting size:{' '}
<ComboBox
style={{ width: 150}}
inlineFlex
collapseOnSelect
clearIcon={false}
searchable={false}
changeValueOnNavigation
dataSource={nestingSizeDataSource}
value={groupNestingSize}
onChange={setGroupNestingSize}
/>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
groupNestingSize={groupNestingSize}
defaultGroupBy={groupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
default: undefined
collapsed
groups in a <ReactDataGrid />
.selected
object should be the "paths" to collapsed groups. For example, if records are first grouped by country, and "uk"
is a country shared by many records, and then grouped by city, with "London"
being the city value for many items, then "uk/London"
(a concatenation of the two, separated by groupPathSeparator
) is the key to be used in the collapsed
object in order to render "London"
people as collapsed.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 600 }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultWidth: 140, header: 'Country' },
{ name: 'city', defaultWidth: 140, header: 'City' },
{ name: 'email', defaultWidth: 140, defaultFlex: 1, header: 'Email' }
]
const App = () => {
const [groupBy, setGroupBy] = useState(['country','city'])
const [collapsedGroups, setCollapsedGroups] = useState({ 'uk#London': true, 'uk#Bristol': true })
const [expandedGroups, setExpandedGroups] = useState(true)
const onGroupCollapseChange = useCallback((collapsedGroups, expandedGroups) => {
setCollapsedGroups(collapsedGroups)
setExpandedGroups(expandedGroups)
}, [])
return (
<div>
<p>
Collapsed groups: {JSON.stringify(Object.keys(collapsedGroups))}.
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
collapsedGroups={collapsedGroups}
expandedGroups={expandedGroups}
groupPathSeparator="#"
onGroupCollapseChange={setCollapsedGroups}
defaultGroupBy={groupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Array
default: undefined
<ReactDataGrid />
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, hedaer: 'Id', defaultVisible: false },
{ name: 'firstName', group: 'personalInfo', defaultFlex: 1, header: 'First Name' },
{ name: 'age', group: 'personalInfo', type: 'number', header: 'Age' },
{ name: 'email', group: 'contactInfo', defaultFlex: 1, header: 'Email' },
{ name: 'phone', group: 'contactInfo', header: 'Phone' },
{ name: 'city', group: 'location', header: 'City' },
{ name: 'streetName', group: 'street', defaultFlex: 1, header: 'Street name' },
{ name: 'streetNo', group: 'street', type: 'number', header: 'Street no' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Personal info' },
{ name: 'contactInfo', header: 'Contact info' },
{ name: 'location', header: 'Location' }
]
const dataSource = [
{ id: 0, firstName: 'Bob', age: 25, email: 'bobby@whocares.com', phone: '+7403 456 768', city: 'Paris', streetName: 'Champs Elysee', streetNo: 34 },
{ id: 1, firstName: 'Lynda', age: 38, email: 'lynda@idont.com', phone: '+7103 66 98 768', city: 'London', streetName: 'St Mary', streetNo: 14 },
{ id: 2, firstName: 'Richard', age: 18, email: 'richy@rich.com', phone: '+173 668 08 83', city: 'Manchester', streetName: 'St Robert', streetNo: 53 },
{ id: 3, firstName: 'Michael', age: 45, email: 'mike@mikey.com', phone: '+075 0628 156 74', city: 'Los Angeles', streetName: 'Greenfield', streetNo: 24 },
{ id: 4, firstName: 'Martin', age: 12, email: 'martin@bobson.com', phone: '+173 5624 675 462', city: 'San Jose', streetName: 'Patrick Ball', streetNo: 67 }
]
const gridStyle = { minHeight: 500 }
export default () => <div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
/>
</div>
Bool
default: undefined
false
to make a column group non-draggable. By default column groups are draggable.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', type: 'number', minWidth: 50, header: 'Id', defaultVisible: false },
{ name: 'firstName', group: 'personalInfo', defaultFlex: 1, header: 'First Name' },
{ name: 'age', group: 'personalInfo', type: 'number', minWidth: 50, header: 'Age' },
{ name: 'email', group: 'contactInfo', defaultFlex: 1, header: 'Email' },
{ name: 'phone', group: 'contactInfo', defaultFlex: 1, header: 'Phone' },
{ name: 'city', group: 'location', defaultFlex: 1, header: 'City' },
{ name: 'streetName', group: 'street', defaultFlex: 1, header: 'Street name' },
{ name: 'streetNo', group: 'street', type: 'number', minWidth: 50, header: 'Street no' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', group: 'details', header: 'Personal info' },
{ name: 'contactInfo', group: 'details', header: 'Contact info' },
{ name: 'location', group: 'details', draggable: false, header: 'Location' }
]
const dataSource = [
{ id: 0, firstName: 'Bob', age: 25, email: 'bobby@whocares.com', phone: '+7403 456 768', city: 'Paris', streetName: 'Champs Elysee', streetNo: 34 },
{ id: 1, firstName: 'Lynda', age: 38, email: 'lynda@idont.com', phone: '+7103 66 98 768', city: 'London', streetName: 'St Mary', streetNo: 14 },
{ id: 2, firstName: 'Richard', age: 18, email: 'richy@rich.com', phone: '+173 668 08 83', city: 'Manchester', streetName: 'St Robert', streetNo: 53 },
{ id: 3, firstName: 'Michael', age: 45, email: 'mike@mikey.com', phone: '+075 0628 156 74', city: 'Los Angeles', streetName: 'Greenfield', streetNo: 24 },
{ id: 4, firstName: 'Martin', age: 12, email: 'martin@bobson.com', phone: '+173 5624 675 462', city: 'San Jose', streetName: 'Patrick Ball', streetNo: 67 }
]
const gridStyle = { minHeight: 500 }
export default () => <div>
<p>Location group is not draggable in this example</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
/>
</div>
Array
default: undefined
groups.group
property - eg: say you want to nest a 'street'
group inside a 'location'
group - you have to specify { name: 'street', group: 'location'}
which means the 'street'
group is nested inside the 'location'
group.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', type: 'number', defaultWidth: 40, header: 'Id', defaultVisible: false },
{ name: 'firstName', group: 'personalInfo', defaultFlex: 2, header: 'First Name' },
{ name: 'age', group: 'personalInfo', type: 'number', defaultWidth: 50, header: 'Age' },
{ name: 'email', group: 'contactInfo', defaultFlex: 2, header: 'Email' },
{ name: 'phone', group: 'contactInfo', defaultFlex: 1, header: 'Phone' },
{ name: 'city', group: 'location', defaultFlex: 1, header: 'City' },
{ name: 'streetName', group: 'street', defaultFlex: 1, header: 'Street name' },
{ name: 'streetNo', group: 'street', type: 'number', defaultWidth: 50, header: 'Street no' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Personal info' },
{ name: 'contactInfo', header: 'Contact info' },
{ name: 'location', header: 'Location' }
]
const dataSource = [
{ id: 0, firstName: 'Bob', age: 25, email: 'bobby@whocares.com', phone: '+7403 456 768', city: 'Paris', streetName: 'Champs Elysee', streetNo: 34 },
{ id: 1, firstName: 'Lynda', age: 38, email: 'lynda@idont.com', phone: '+7103 66 98 768', city: 'London', streetName: 'St Mary', streetNo: 14 },
{ id: 2, firstName: 'Richard', age: 18, email: 'richy@rich.com', phone: '+173 668 08 83', city: 'Manchester', streetName: 'St Robert', streetNo: 53 },
{ id: 3, firstName: 'Michael', age: 45, email: 'mike@mikey.com', phone: '+075 0628 156 74', city: 'Los Angeles', streetName: 'Greenfield', streetNo: 24 },
{ id: 4, firstName: 'Martin', age: 12, email: 'martin@bobson.com', phone: '+173 5624 675 462', city: 'San Jose', streetName: 'Patrick Ball', streetNo: 67 }
]
const gridStyle = { minHeight: 500 }
export default () => <div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
/>
</div>
String|React.Node
default: undefined
groups.header
property to customize the content inside the group header. Think of group headers just like column headers.<ReactDataGrid />
is smart enough to know how to split group headers and where new groups begin.<ReactDataGrid />
is the array of columns you want to display and it will figure out the correct nesting/stacking of column group headers.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', type: 'number', minWidth: 50, header: 'Id', defaultVisible: false },
{ name: 'firstName', group: 'personalInfo', defaultFlex: 2, header: 'First Name' },
{ name: 'age', group: 'personalInfo', type: 'number', minWidth: 50, header: 'Age' },
{ name: 'email', group: 'contactInfo', defaultFlex: 2, header: 'Email' },
{ name: 'phone', group: 'contactInfo', defaultFlex: 1, header: 'Phone' },
{ name: 'city', group: 'location', defaultFlex: 1, header: 'City' },
{ name: 'streetName', group: 'street', defaultFlex: 1, header: 'Street name' },
{ name: 'streetNo', group: 'street', type: 'number', minWidth: 50, header: 'Street no' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Information about you' },
{ name: 'contactInfo', header: <span style={{ color: '#7986cb' }}>Contact</span> },
{ name: 'location', header: <span style={{ color: '#ef9a9a' }}>Where you live</span> }
]
const dataSource = [
{ id: 0, firstName: 'Bob', age: 25, email: 'bobby@whocares.com', phone: '+7403 456 768', city: 'Paris', streetName: 'Champs Elysee', streetNo: 34 },
{ id: 1, firstName: 'Lynda', age: 38, email: 'lynda@idont.com', phone: '+7103 66 98 768', city: 'London', streetName: 'St Mary', streetNo: 14 },
{ id: 2, firstName: 'Richard', age: 18, email: 'richy@rich.com', phone: '+173 668 08 83', city: 'Manchester', streetName: 'St Robert', streetNo: 53 },
{ id: 3, firstName: 'Michael', age: 45, email: 'mike@mikey.com', phone: '+075 0628 156 74', city: 'Los Angeles', streetName: 'Greenfield', streetNo: 24 },
{ id: 4, firstName: 'Martin', age: 12, email: 'martin@bobson.com', phone: '+173 5624 675 462', city: 'San Jose', streetName: 'Patrick Ball', streetNo: 67 }
]
const gridStyle = { minHeight: 500 }
export default () => <div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
/>
</div>
{ initialValue: any, reducer: (acc, current) => any, complete: (value, arr) => any}
default: undefined
groupSummaryReducer
object has the following shape:initialValue
- the initial value to be used for the summary computation - generally a number/string/etcreducer(accumulator, data)
- the reducer function - basically computes the summary from the accumulated value (at first call, this will equal the initialValue
) and the data object for the item at which we are doing the computationcomplete(accumulatedValue, array)
- can be used for doing one last computation at the end of the iteration - for example useful for computing the average of a value. The first argument is the accumulated value, while the second is the array on which the summary was computed againstcolumns.groupSummaryReducer
.render
functions defined for columns, when the group row is being rendered, you have access to the group summaries via the data.groupColumnSummary
object, which has a key for each of the columns that define a column.groupSummaryReducer
.data.groupSummary
is available in the render function in case you have definedgroupSummaryReducer
at grid-level.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600, marginTop: 10 }
let cities;
const sum = (a,b) => a + b
const columns = [
{
name: 'name',
defaultFlex: 1,
header: 'City',
render: ({ value, data }) => {
if (data.__group){
return <React.Fragment>
<b>Avg city population: {Math.round(data.groupSummary)}</b>
</React.Fragment>
}
return value
},
},
{ name: 'country', defaultFlex: 1, header: 'Country'},
{
name: 'population',
type: 'number',
defaultFlex: 1,
header: 'Population',
render: ({ value, data }) => {
// if you want to custom-render the summary value for this column
// you can do so
return data.__group ? (
<React.Fragment>
<b>Total: </b>
{value}{' '}
</React.Fragment>
) : (
value
);
},
groupSummaryReducer: {
initialValue: 0,
reducer: sum
}
}
];
const App = () => {
return (
<div>
<h3>groupSummaryReducer demo at grid-level</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
groupColumn={{
defaultWidth: 250,
renderGroupValue: ({ value, data }) => {
return <React.Fragment>
{value} - avg city population: {Math.round(data.groupSummary)}
</React.Fragment>
}
}}
groupSummaryReducer={{
initialValue: 0,
reducer: (acc, data) => acc + data.population,
complete: (value, arr) => value/arr.length
}}
columns={columns}
dataSource={cities}
defaultGroupBy={['country']}
/>
</div>
);
}
cities = [
{
id: 'ny',
country: 'USA',
name: 'New York City',
population: 1000
},
{
id: 'la',
country: 'USA',
name: 'Los Angeles',
population: 150
},
{
id: 'paris',
country: 'France',
name: 'Paris',
population: 2000
},
{
id: 'london',
name: 'London',
country: 'UK',
population: 3000
},
{
id: 'SF',
name: 'San Francisco',
country: 'USA',
population: 3900
},
{
id: 'ly',
name: 'Lyon',
country: 'France',
population: 980
},
{
id: 'ma',
name: 'Manchester',
country: 'UK',
population: 2000
}
]
export default () => <App />
(computedPropsRef: MutableRef) => void
default: undefined
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import Button from '@inovua/reactdatagrid-community/packages/Button'
const gridStyle = { minHeight: 550 }
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{
id: 1,
name: 'App store',
size: '4.5Mb'
},
{
id: 2,
name: 'iMovie',
size: '106Mb'
},
{
id: 3,
name: 'IRecall',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
nodes: [
{
id: 1,
name: 'Todo.md',
size: '2Kb'
},
{
id: 2,
name: 'Calendar.md',
size: '15.2Kb'
},
{ id: 3, name: 'Shopping list.csv',size: '20Kb' }
]
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{
id: 1,
name: 'Personal.xls',
size: '100Gb'
},
{ id: 2, name: 'Work.xls' }
]
},
{ id: 2, name: 'MacRestore.gzip' }
]
}
]
const defaultExpandedNodes = { 1: true, 2: true, '3/1': true }
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [dataSource, setDataSource] = useState(treeData)
const [expandedNodes, setExpandedNodes]= useState(defaultExpandedNodes)
const [clearNodeCacheOnDataSourceChange, setClearNodeCacheOnDataSourceChange] = useState(true)
const onExpandedNodesChange = useCallback(({ expandedNodes }) => {
setExpandedNodes(expandedNodes)
}, [])
return (
<div>
<p>
<CheckBox
checked={clearNodeCacheOnDataSourceChange}
onChange={setClearNodeCacheOnDataSourceChange}
>Clear node cache on data source change</CheckBox>
</p>
<p>
<Button
onClick={() => {
gridRef.current.setItemPropertyAt(0, 'name', 'Apps')
}}
>
Set "name" property for first node to "Apps"
</Button>
</p>
<p>
<Button
onClick={() => setDataSource([].concat(treeData))}>
Update dataSource
</Button>
<p>If "Clear node cache" is true, and the first node is changed, it should revert to the initial value when updating the dataSource
</p>
</p>
<ReactDataGrid
handle={setGridRef}
treeColumn="name"
clearNodeCacheOnDataSourceChange={clearNodeCacheOnDataSourceChange}
expandedNodes={expandedNodes}
onExpandedNodesChange={onExpandedNodesChange}
style={gridStyle}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
header (this is the wrapper component containing the headers for all grid columns) and be used as DOM props. Can contain properties like className
, style
, etc.columns.headerDOMProps
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const headerProps = {
style: {
height: 120,
background: 'tomato',
color: 'white'
}
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country' },
{ name: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age ' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
headerProps={headerProps}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'country', defaultFlex: 1, header: 'Country' },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' }
]
const App = () => {
const [hideGroupByColumns, sethHideGroupByColumns] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={hideGroupByColumns}
onChange={sethHideGroupByColumns}
>
Hide group by columns
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={['country']}
hideGroupByColumns={hideGroupByColumns}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
.DataGrid.defaultProps.i18n
!pageText='Page '
ofText=' of '
perPageText='Results per page'
showingText='Showing '
clearAll='Clear all'
clear='Clear'
showFilteringRow='Show filtering row'
hideFilteringRow='Hide filtering row'
dragHeaderToGroup='Drag header to group'
disable='Disable'
enable='Enable'
disable='Disable'
sortAsc='Sort ascending'
sortDesc='Sort descending'
unsort='Unsort'
group='Group'
ungroup='Ungroup'
lockStart='Lock start'
lockEnd='Lock end'
unlock='Unlock'
columns='Columns'
contains='Contains'
startsWith='Starts with'
endsWith='Ends with'
notContains='Does not contain'
neq='Does not equal'
eq='Equals'
notEmpty='Not empty'
empty='Empty'
lt='Less than'
lte='Less than or equal'
gt='Greater than'
gte='Greater than or equal'
calendar.todayButtonText='Today'
calendar.clearButtonText='Clear'
calendar.okButtonText='OK'
calendar.cancelButtonText='Cancel'
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1 }
]
const dataSource = [
{ name: 'John Lewis', age: 35, id: 'john4' },
{ name: 'Mary Stones', age: 25, id: 'mary8' },
{ name: 'Mary Stones', age: 43, id: 'mary67' },
{ name: 'Andrew Clark', age: 31, id: 'and99' },
{ name: 'Vanessa Williams', age: 29, id: 'vane2' },
{ name: 'Terence More', age: 27, id: 'tere0' },
{ name: 'Leonard Stevenson', age: 48, id: 'leo64' }
]
const gridStyle = {
minHeight: 450
}
const i18n = Object.assign({}, ReactDataGrid.defaultProps.i18n, {
sortAsc: 'Execute ASC sort',
sortDesc: 'Execute DESC sort',
clear: 'Remove',
clearAll: 'Remove All'
})
export default () => <ReactDataGrid
i18n={i18n}
columns={columns}
dataSource={dataSource}
style={gridStyle}
/>
String
default: "id"
<ReactDataGrid />
columns. DataSource objects can contain any other properties, and will generally contain an identifier property - most of the times named id
that gives uniqueness to <ReactDataGrid />
rows. This identifier property name should be used as the idProperty
to help uniquely identify <ReactDataGrid />
rows.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'uniqueId', header: 'Id', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1 }
]
const dataSource = [
{ name: 'John Lewis', age: 35, uniqueId: 'john4' },
{ name: 'Mary Stones', age: 25, uniqueId: 'mary8' },
{ name: 'Mary Stones', age: 43, uniqueId: 'mary67' },
{ name: 'Andrew Clark', age: 31, uniqueId: 'and99' },
{ name: 'Vanessa Williams', age: 29, uniqueId: 'vane2' },
{ name: 'Terence More', age: 27, uniqueId: 'tere0' },
{ name: 'Leonard Stevenson', age: 48, uniqueId: 'leo64' }
]
const gridStyle = {
minHeight: 250
}
export default () => <div>
<ReactDataGrid
idProperty="uniqueId"
columns={columns}
dataSource={dataSource}
style={gridStyle}
/>
</div>
dataSource
contains nested objects, the <ReactDataGrid />
rows can be uniquely identified by the nested objects indentifier (the id
of nested objects, for example).import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const dataSource = [
{
id: 0,
person: {
personId: 0,
name: 'Amanda Soaresz',
personalData: { age: 35, location: 'Rome' },
},
},
{
id: 1,
person: {
personId: 1,
name: 'Mary Adamson',
personalData: { age: 25, location: 'Madrid' },
},
},
{
id: 2,
person: {
personId: 2,
name: 'Robert Fil',
personalData: { age: 27, location: 'Seattle' },
},
},
{
id: 3,
person: {
personId: 3,
name: 'Roger Bob',
personalData: { age: 81, location: 'Frankfurt' },
},
},
{
id: 4,
person: {
personId: 4,
name: 'Billary Konwik',
personalData: { age: 18, location: 'Vienna' },
},
},
{
id: 5,
person: {
personId: 5,
name: 'Bob Marc',
personalData: { age: 18, location: 'Brussels' },
},
},
{
id: 6,
person: {
personId: 6,
name: 'Matthew Richardson',
personalData: { age: 54, location: 'Amsterdam' },
},
},
{
id: 7,
person: {
personId: 7,
name: 'Richy Peterson',
personalData: { age: 54, location: 'Salzburg' },
},
},
];
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
type: 'number',
defaultWidth: 80,
},
{
name: 'person',
header: 'Person',
defaultWidth: 200,
render: ({ data }) => {
return <span>{data.person.name}</span>;
},
},
{
name: 'person.personalData.age',
header: 'Age',
defaultWidth: 100,
render: ({ data }) => <span>{data.person.personalData.age}</span>,
},
{
name: 'person.personalData.location',
header: 'Location',
defaultWidth: 120,
render: ({ data }) => {
return <span>{data.person.personalData.location}</span>;
},
},
];
const gridStyle = {
minHeight: 450
}
export default () => <div>
<ReactDataGrid
idProperty="person.personId"
columns={columns}
dataSource={dataSource}
style={gridStyle}
/>
</div>
String
default: "."
dataSource
objects (see idProperty
).import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const dataSource = [
{
id: 0,
person: {
personId: 0,
name: 'Amanda Soaresz',
personalData: { age: 35, location: 'Rome' },
},
},
{
id: 1,
person: {
personId: 1,
name: 'Mary Adamson',
personalData: { age: 25, location: 'Madrid' },
},
},
{
id: 2,
person: {
personId: 2,
name: 'Robert Fil',
personalData: { age: 27, location: 'Seattle' },
},
},
{
id: 3,
person: {
personId: 3,
name: 'Roger Bob',
personalData: { age: 81, location: 'Frankfurt' },
},
},
{
id: 4,
person: {
personId: 4,
name: 'Billary Konwik',
personalData: { age: 18, location: 'Vienna' },
},
},
{
id: 5,
person: {
personId: 5,
name: 'Bob Marc',
personalData: { age: 18, location: 'Brussels' },
},
},
{
id: 6,
person: {
personId: 6,
name: 'Matthew Richardson',
personalData: { age: 54, location: 'Amsterdam' },
},
},
{
id: 7,
person: {
personId: 7,
name: 'Richy Peterson',
personalData: { age: 54, location: 'Salzburg' },
},
},
];
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
type: 'number',
defaultWidth: 80,
},
{
name: 'person',
header: 'Person',
defaultWidth: 200,
render: ({ data }) => {
return <span>{data.person.name}</span>;
},
},
{
name: 'person.personalData.age',
header: 'Age',
defaultWidth: 100,
render: ({ data }) => <span>{data.person.personalData.age}</span>,
},
{
name: 'person.personalData.location',
header: 'Location',
defaultWidth: 120,
render: ({ data }) => {
return <span>{data.person.personalData.location}</span>;
},
},
];
const gridStyle = {
minHeight: 450
}
export default () => <div>
<ReactDataGrid
idProperty="person.personId"
idPropertySeparator="-"
columns={columns}
dataSource={dataSource}
style={gridStyle}
/>
</div>
Fn(info)
default: undefined
Alt+ArrowLeft
is pressed. The default implementation of this function is ({event}) => event.key === 'ArrowLeft' && event.altKey;
isExpandKeyPressed
info
param has an event
property and also many properties with information about the currently active row:event
- the event objectdata
- the current active row. An alias of activeItem
index
- the current active index. An alias of activeIndex
activeItem
- the current active rowactiveIndex
- the current active indexgrid
- a reference to the <ReactDataGrid />
instanceisGroup
- boolean - whether the current row is a group rowselectionEnabled
- boolean - whether row selection is enabledtreeEnabled
- boolean - whether tree functionality is enabledrowExpandEnabled
- boolean - whether row expand is enablednodeExpanded
- boolean - whether the node is expandednodeExpandable
- boolean - whether the node is expandablerowExpandable
- boolean - whether the row is expandablerowExpanded
- boolean - whether the row is expandedimport React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const isExpandKeyPressed = ({ event }) => event.key === 'ArrowRight' && event.shiftKey
const isCollapseKeyPressed = ({ event }) => event.key === 'ArrowLeft' && event.shiftKey
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const defaultExpandedRows = { 1: true, 2: true }
const App = () => {
return (
<div>
<p>
Use Shift + Arrow keys to expand/collapse rows.
</p>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
isExpandKeyPressed={isExpandKeyPressed}
isCollapseKeyPressed={isCollapseKeyPressed}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(info)
default: undefined
Alt+ArrowRight
is pressed. The default implementation of this function is ({event}) => event.key === 'ArrowRight' && event.altKey;
isCollapseKeyPressed
info
param has an event
property and also many properties with information about the currently active row:event
- the event objectdata
- the current active row. An alias of activeItem
index
- the current active index. An alias of activeIndex
activeItem
- the current active rowactiveIndex
- the current active indexgrid
- a reference to the <ReactDataGrid />
instanceisGroup
- boolean - whether the current row is a group rowselectionEnabled
- boolean - whether row selection is enabledtreeEnabled
- boolean - whether tree functionality is enabledrowExpandEnabled
- boolean - whether row expand is enablednodeExpanded
- boolean - whether the node is expandednodeExpandable
- boolean - whether the node is expandablerowExpandable
- boolean - whether the row is expandablerowExpanded
- boolean - whether the row is expandedimport React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const isExpandKeyPressed = ({ event }) => event.key === 'ArrowRight' && event.shiftKey
const isCollapseKeyPressed = ({ event }) => event.key === 'ArrowLeft' && event.shiftKey
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const defaultExpandedRows = { 1: true, 2: true }
const App = () => {
return (
<div>
<p>
Use Shift + Arrow keys to expand/collapse rows.
</p>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
isExpandKeyPressed={isExpandKeyPressed}
isCollapseKeyPressed={isCollapseKeyPressed}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ node, nodeProps })
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{
id: 1,
name: 'App store',
size: '4.5Mb',
nodes: null
},
{
id: 2,
name: 'iMovie',
size: '106Mb',
nodes: null
},
{
id: 3,
name: 'IRecall',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
nodes: [
{
id: 1,
name: 'Todo.md',
size: '2Kb'
},
{
id: 2,
name: 'Calendar.md',
size: '15.2Kb'
},
{ id: 3, name: 'Shopping list.csv',size: '20Kb' }
]
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{
id: 1,
name: 'Personal.xls',
size: '100Gb'
},
{ id: 2, name: 'Work.xls' }
]
},
{ id: 2, name: 'MacRestore.gzip' }
]
}
]
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const defaultExpandedNodes = { 3: true, '3/1': true }
const loadNode = ({ node, nodeProps }) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Array.isArray(node.nodes)) {
return resolve(node.nodes)
}
if (nodeProps.depth >=4 ) {
resolve([
{ id: 1, name: 'First child of ' + node.name },
{ id: 2, name: 'Second child of ' + node.name }
])
}
resolve([
{ id: 1, name: 'First child of ' + node.name, nodes: null },
{ id: 2, name: 'Second child of ' + node.name, nodes: null }
])
}, 200)
})
}
const isNodeAsync = ({ node }) => {
if (node.name === 'Applications') {
return true
}
return node.nodes === null
}
const App = () => {
return (
<div>
<p>DataGrid with the "Applications" node forced to async</p>
<ReactDataGrid
isNodeAsync={isNodeAsync}
loadNode={loadNode}
defaultExpandedNodes={defaultExpandedNodes}
treeColumn={'name'}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn({ node, nodeProps })
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const treeData = [
{
id: 1,
name: 'Applications',
folder: true,
nodes: [
{
id: 1,
name: 'App store',
size: '4.5Mb',
nodes: null
},
{
id: 2,
name: 'iMovie',
size: '106Mb',
nodes: null
},
{
id: 3,
name: 'IRecall',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
nodes: [
{
id: 1,
name: 'Todo.md',
size: '2Kb'
},
{
id: 2,
name: 'Calendar.md',
size: '15.2Kb'
},
{ id: 3, name: 'Shopping list.csv',size: '20Kb' }
]
},
{
id: 3,
name: '3 Downloads',
nodes: [
{
id: 1,
name: 'Email data',
nodes: [
{
id: 1,
name: 'Personal.xls',
size: '100Gb'
},
{ id: 2, name: 'Work.xls' }
]
},
{ id: 2, name: 'MacRestore.gzip' }
]
}
]
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const defaultExpandedNodes = { 3: true, '3/1': true }
const loadNode = ({ node, nodeProps }) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (nodeProps.depth >=4 ) {
resolve([
{ id: 1, name: 'First child of ' + node.name },
{ id: 2, name: 'Second child of ' + node.name }
])
}
resolve([
{ id: 1, name: 'First child of ' + node.name, nodes: null },
{ id: 2, name: 'Second child of ' + node.name, nodes: null }
])
}, 200)
})
}
const isNodeLeaf = ({ node }) => {
if (node.name === 'Applications') {
return true
}
return node.nodes === null
}
const App = () => {
return (
<div>
<p>DataGrid with the "Applications" node forced to be a leaf</p>
<ReactDataGrid
isNodeLeaf={isNodeLeaf}
loadNode={loadNode}
defaultExpandedNodes={defaultExpandedNodes}
treeColumn={'name'}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn({ id, data, rowIndex })
default: undefined
id
, data
or rowIndex
properties, but rather store the property values.unexpandableRows
.unexpandableRows
prop is specified, this prop is no longer called.import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map(name => {
return <tr key={name}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' },
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const App = () => {
const isRowExpandable = useCallback(({ data }) => {
return data.age >= 30
}, [])
return (
<ReactDataGrid
idProperty="id"
isRowExpandable={isRowExpandable}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
);
}
export default () => <App />
Fn({ event })
default: undefined
Ctrl+E
.({ event }) => event.key === 'e' && event.ctrlKey
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const isStartEditKeyPressed = ({ event }) => event.key === 'g' && event.ctrlKey
const columns = [
{ name: 'id', minWidth: 70, type: 'number', header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, minWidth: 200, header: 'Name' },
{ name: 'country', defaultFlex: 1, minWidth: 100, render: ({ value })=> flags[value] ? flags[value] : value, header: 'Country' },
{ name: 'city', defaultFlex: 1, minWidth: 200, header: 'City' },
{ name: 'age', minWidth: 150, type: 'number', header: 'Age' }
]
const App = () => {
const [dataSource, setDataSource] = useState(people)
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
return (
<div>
<h3>Trigger inline edit via a custom keyboard shortcut: Ctrl+G</h3>
<ReactDataGrid
isStartEditKeyPressed={isStartEditKeyPressed}
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
editable={true}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Number
default: 10
<ReactDataGrid />
with keyboard navigation and hits PageUp
or PageDown
, the activeIndex
is incremented (on PageDown
) or decremented (on PageUp
) by the amount specified via the keyPageStep
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'country', defaultWidth: 150, header: 'Country' },
{ name: 'age', defaultWidth: 150, type: 'number', header: 'Age' },
{
id: 'desc',
header: 'Description',
defaultWidth: 250,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
return (
<div>
<h3>Grid with keyPageStep=4</h3>
<p>Focus the grid and press PageDown/PageUp to navigate by 4 rows downwards/upwards!</p>
<ReactDataGrid
idProperty="id"
keyPageStep={4}
defaultActiveIndex={6}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
string
default: undefined
<ReactDataGrid />
.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
licenseKey="" /* USE LICENSE KEY HERE */
/>
);
}
export default () => <App />
Number
default: 50
<ReactDataGrid />
, when pagination
is enabled.defaultLimit
.onLimitChange
is triggered, so the dataSource
(most often, a function when the <ReactDataGrid />
has remote pagination) can be reloaded with the correct limit
value.