<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
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import flags from './flags'
const gridStyle = { height: 300 }
const columns = [
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{
name: 'lastName',
defaultFlex: 1,
header: 'Last Name',
setValue({ value }: { value: string }) {
if (value === 'Fil' || value === 'Twain') {
return 'Johnny';
}
return value;
},
},
{
name: 'country',
header: 'Country',
defaultWidth: 100,
textAlign: 'center',
render: ({ value }: { value: string }) => 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>
),
setValue({ value }) {
if (value > 16 && value < 21) {
return 'teenager';
}
if (value >= 21 && value < 30) {
return 'young';
}
return 'adult';
},
},
];
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 },
{ firstName: 'Karl', lastName: 'May', country: 'usa', age: 19, id: 4 }
]
export default () => <ReactDataGrid
idProperty="id"
columns={columns}
dataSource={dataSource}
style={gridStyle}
/>
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.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: 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 [limit, setLimit] = useState(10);
const [loading, setLoading] = useState(false);
const dataSource = useCallback(loadData, [])
const updateLimit = useCallback((amount) => {
let newLimit = limit + amount;
newLimit = Math.min(newLimit, 100);
newLimit = Math.max(newLimit, 0);
setLimit(newLimit);
}, [limit])
const disabled = loading || Array.isArray(dataSource)
return (
<div>
<p>Try to update the page size in the combo to see the limit change</p>
<p>Current limit (page size): {limit}.</p>
<div style={{ marginBottom: 20 }}>
<Button style={{ marginRight: 8 }} onClick={() => updateLimit(10)} disabled={disabled}>limit += 10</Button>
<Button onClick={() => updateLimit(-10)} disabled={disabled || limit === 0}>limit -= 10</Button>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
pagination
limit={limit}
onLimitChange={setLimit}
loading={loading}
onLoadingChange={setLoading}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
<ReactDataGrid />
should use live paginationimport 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: 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 }) => {
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 App = () => {
const [livePagination, setLivePagination] = useState(true);
const dataSource = useCallback(loadData, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={livePagination} onChange={setLivePagination} >
Live pagination
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
key={'grid-' + livePagination}
style={gridStyle}
columns={columns}
livePagination={livePagination}
pagination
sortable={false}
dataSource={dataSource}
limit={15}
/>
</div>
);
}
export default () => <App />
Number
default: 50
livePagination
is used, and subsequent pages need to be loaded, the load mask is hidden with this configured delay in order to avoid flashing.Bool
default: undefined
defaultLoading
.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 } 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', defaultVisible: false, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultWidth: 150, type: 'number' }
]
const App = () => {
const [loading, setLoading] = useState(false)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={loading} onChange={setLoading}>
Show load mask
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
loading={loading}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
React.Node
default: undefined
loading
), you can optionally show a custom message, as specified by this prop.import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const pleaseWait = <b>Please wait while loading ... </b>
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultFlex: 1, defaultWidth: 100 },
{ name: 'country', header: 'Country', defaultFlex: 1, defaultWidth: 100 },
{ name: 'city', header: 'City', defaultFlex: 1, defaultWidth: 100 },
{ name: 'age', header: 'Age', defaultWidth: 150, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
loading={true}
loadingText={pleaseWait}
columns={columns}
dataSource={[]}
/>
</div>
);
}
export default () => <App />
Fn({ node, nodeProps })
default: undefined
nodes===null
), will be called when the node is expanded (on every expand). Should either return an array or a Promise resolving to an array.loadNodeOnce
.loadNodeAsync
property available on the columns.render function.node
is a reference to the data item being expanded.nodeProps
is an object with the following properties:expanded
: Booleanloading
: Booleandepth
: Number - the depth from the topmost node to the current node. Top-level nodes have a depth of 0
path
: String - the path from the topmost node to the current nodeparentNodeId
: String/Number - the id of the parent nodeleafNode
: BooleanasyncNode
: BooleanchildIndex
: Number - the index of the current node among its sibling nodesloadNode
is used, all it's children at any level of nesting are also collapsed (in order to have fresh data on the next expand) - to modify this behaviour, see collapseChildrenOnAsyncNodeCollapse
.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 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 }
const App = () => {
return (
<div>
<h3>TreeGrid with async nodes</h3>
<ReactDataGrid
treeColumn="name"
loadNode={loadNode}
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn({ node, nodeProps })
default: undefined
nodes===null
), will be called when the node is first expanded (on subsequent expand actions, the same nodes returned initially by this method will be used). Should either return an array or a Promise resolving to an array.loadNode
.loadNodeAsync
property available on the columns.render function.node
is a reference to the data item being expanded.nodeProps
is an object with the following properties:expanded
: Booleanloading
: Booleandepth
: Number - the depth from the topmost node to the current node. Top-level nodes have a depth of 0
path
: String - the path from the topmost node to the current nodeparentNodeId
: String/Number - the id of the parent nodeleafNode
: BooleanasyncNode
: BooleanchildIndex
: Number - the index of the current node among its sibling nodesimport 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 loadNodeOnce = ({ 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 }
const App = () => {
return (
<div>
<h3>TreeGrid with async nodes</h3>
<ReactDataGrid
treeColumn="name"
loadNodeOnce={loadNodeOnce}
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
false
. For the most part, this prop is an alias to showColumnMenuLockOptions
.showColumnMenuLockOptions
for details.columns.lockable
default: undefined
<ReactDataGrid />
- see locked rows page for more examples.start
and at the end
of the grid viewport.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 contactsDataSource from './data'
const gridStyle = { minHeight: 550, marginTop: 10 }
const columns = [
{ name: 'id', header: 'ID', defaultVisible: false, type: 'number', defaultWidth: 100 },
{ name: 'firstName', header: 'First Name', defaultWidth: 200 },
{ name: 'lastName', header: 'Last Name', defaultWidth: 200 },
{ name: 'email', header: 'Email', defaultFlex: 1 }
];
const App = () => {
const [first, setFirst] = useState();
const [second, setSecond] = useState();
const [last, setLast] = useState();
const [firstLocked, setFirstLocked] = useState(false);
const [secondLocked, setSecondLocked] = useState(false);
const [lastLocked, setLastLocked] = useState(false);
const [showZebraRows, setShowZebraRows] = useState(false);
const [useRowHeightForLockedRows, setUseRowHeightForLockedRows] = useState(true);
const [dataSource, setDataSource] = useState(contactsDataSource);
const update = useCallback((newState, fn) => {
let data = [].concat(contactsDataSource)
// we don't want to show locked rows in the dataSource
if (newState.lastLocked) {
// delete last 3
setLast(data.splice(-3,3))
}
if (newState.secondLocked) {
setSecond(data.splice(1, 1)[0])
}
if (newState.firstLocked) {
setFirst(data.splice(0, 1)[0])
}
const newStateValue = Object.values(newState)[0];
fn(newStateValue);
}, [firstLocked, secondLocked, lastLocked])
const lockedRows = []
if (firstLocked) {
lockedRows.push({
position: 'start',
render: ({column}, computedProps) => {
return first ? first[column.name] : null
}
})
}
if (secondLocked) {
lockedRows.push({
position: 'start',
render: ({column}, computedProps) => {
return second ? second[column.name] : null
}
})
}
if (lastLocked) {
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = last? last[0] : null
return item ? item[column.name] : null
}
})
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = last? last[1] : null
return item ? item[column.name] : null
}
})
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = last? last[2] : null
return item ? item[column.name] : null
}
})
}
return (
<div>
<h3>Locked rows demo</h3>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={firstLocked}
onChange={firstLocked => update({ firstLocked }, setFirstLocked)}
>
Lock row 1
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={secondLocked}
onChange={secondLocked => update({secondLocked}, setSecondLocked)}
>
Lock row 2
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={lastLocked}
onChange={lastLocked => update({lastLocked}, setLastLocked)}
>
Lock last 3 rows at the bottom
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={showZebraRows}
onChange={setShowZebraRows}
>
Show zebra rows
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={useRowHeightForLockedRows}
onChange={setUseRowHeightForLockedRows}
>
Use same row height for locked rows
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
lockedRows={lockedRows}
style={gridStyle}
rowHeight={45}
columns={columns}
dataSource={dataSource}
useRowHeightForLockedRows={useRowHeightForLockedRows}
showZebraRows={showZebraRows}
/>
</div>
);
}
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 lockedRows = [
{
position: 'start',
render: {
population: ({ summary }) => <div>Population min: {summary.min}</div>
},
country: <b>Nothing to render</b>
},
{
position: 'start',
render: {
population: ({ summary }) => <div>Population max: {summary.max}</div>
}
},
{
position: 'start',
render: {
population: ({ summary }) => <div>Population average: {summary.avg}</div>
}
},
{
position: 'end',
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>Locked rows with custom render and colspan</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
dataSource={cities}
summaryReducer={summaryReducer}
lockedRows={lockedRows}
/>
</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 />
'start'|'end
default: undefined
"start"
or "end"
.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: 550, marginTop: 10 }
const loadData = ({ skip, limit, sortInfo }) => {
return fetch(DATASET_URL + '?limit=' + limit + '&sortInfo=' + JSON.stringify(sortInfo))
.then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: totalCount * 1 };
})
});
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 100 },
{ name: 'firstName', defaultWidth: 200, header: 'First Name' },
{ name: 'lastName', defaultWidth: 200, header: 'Last Name' },
{ name: 'email', defaultFlex: 1, header: 'Email' }
]
const App = () => {
const [firstLocked, setFirstLocked] = useState(false);
const [secondLocked, setSecondLocked] = useState(false);
const [lastLocked, setLastLocked] = useState(false);
const dataSource = useCallback(loadData, [])
const lockedRows = []
if (firstLocked) {
lockedRows.push({
position: 'start',
render: ({column}, computedProps) => {
const item = computedProps.data[0]
return item ? item[column.name] : null
}
})
}
if (secondLocked) {
lockedRows.push({
position: 'start',
render: ({column}, computedProps) => {
const item = computedProps.data[1]
return item ? item[column.name] : null
}
})
}
if (lastLocked) {
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = computedProps.data[computedProps.data.length - 3]
return item ? item[column.name] : null
}
})
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = computedProps.data[computedProps.data.length - 2]
return item ? item[column.name] : null
}
})
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = computedProps.data[computedProps.data.length - 1]
return item ? item[column.name] : null
}
})
}
return (
<div>
<h3>Locked rows position demo</h3>
<div style={{ marginBottom: 20}}>
<CheckBox checked={firstLocked} onChange={setFirstLocked}>
Lock row 1 at the top (position="start")
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox checked={secondLocked} onChange={setSecondLocked}>
Lock row 2 at the top (position="start")
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox checked={lastLocked} onChange={setLastLocked}>
Lock last 3 rows at the bottom (position="end")
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
lockedRows={lockedRows}
style={gridStyle}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
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 lockedRows = [
{
position: 'start',
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 locked row cell.</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={cities}
summaryReducer={summaryReducer}
lockedRows={lockedRows}
/>
</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 />
Number
default: undefined
<ReactDataGrid />
rows.rowIndexColumn
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import RadioButtonGroup from '@inovua/reactdatagrid-community/packages/RadioButtonGroup'
import people from './people'
const gridStyle = { minHeight: 550 }
const rowHeights = [
{ label: 'small', value: 25 },
{ label: 'normal', value: 40 },
{ label: 'large', value: 80 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ 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 = () => {
const [rowHeight, setRowHeight] = useState(40);
return (
<div>
<p>Max row height is {rowHeight}px</p>
<div style={{ display: 'inline-flex', marginBottom: 20 }}>
<div style={{ marginRight: 16 }}>
Select row height
</div>
<RadioButtonGroup
radioOptions={rowHeights}
radioValue={rowHeight}
onChange={({ checkedItemValue }) => setRowHeight(checkedItemValue)}
orientation="horizontal"
/>
</div>
<ReactDataGrid
key={rowHeight}
idProperty="id"
style={gridStyle}
rowHeight={rowHeight}
columns={columns}
dataSource={people}
maxRowHeight={50}
/>
</div>
);
}
export default () => <App />
Number
default: 20
<ReactDataGrid />
is configured to have dynamic row height (rowHeight=null
). In this situation, the <ReactDataGrid />
needs a minimum height for rows - configured via the mandatory minRowHeight
prop.minRowHeight
is used when the<ReactDataGrid />
is configured to have natural row heights, it's important to understand performance issues that can occur. Read more in the Performance and virtualization page.minRowHeight
is actually applied to <ReactDataGrid />
cells (and not rows), which dictate the height of <ReactDataGrid />
rows.<ReactDataGrid />
rows can be higher than this, but the closer the average row height is to the value specified by minRowHeight
, the better the virtualization performs.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 bigCellStyle = {
minHeight: 80,
display: 'flex',
alignItems: 'center'
}
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 2, header: 'Name', render: ({ rowIndex }) => rowIndex % 2 ? <div style={bigCellStyle}>big cell</div> : 'this has minHeight' },
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
minRowHeight={50}
rowHeight={null}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
multiRowExpand=false
- in this case, expanding one row will collapse the other.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' }
]
const App = () => {
const [multiRowExpand, setMultiRowExpand] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={multiRowExpand}
onChange={setMultiRowExpand}
>
Multi row expand
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
renderRowDetails={renderRowDetails}
multiRowExpand={multiRowExpand}
style={gridStyle}
rowExpandHeight={400}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
cellSelection
. Cell selection is multiple selection by default.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, defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [multiSelect, setMultiSelect] = useState(true)
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={multiSelect} onChange={setMultiSelect}>
Enable multiSelect - applies for cells
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
multiSelect={multiSelect}
defaultCellSelection={{}}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
true
, native browser scrollbars will be used instead of the default custom scrollbars of the 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'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [autoHide, setAutoHide] = useState(false);
const [alwaysShowTrack, setAlwaysShowTrack] = useState(false);
const [redBackground, setRedBackground] = useState(false);
const [customSize, setCustomSize] = useState(false);
const [customRadius, setCustomRadius] = useState(false);
const [nativeScroll, setNativeScroll] = useState(false);
const scrollProps = Object.assign({}, ReactDataGrid.defaultProps.scrollProps, {
autoHide,
alwaysShowTrack
})
if (customSize) {
scrollProps.scrollThumbWidth = 15
scrollProps.scrollThumbOverWidth = 20
}
if (customRadius) {
scrollProps.scrollThumbRadius = 20
}
if (redBackground) {
scrollProps.scrollThumbStyle = {
background: '#ff7474'
}
}
return (
<div>
<h3>Customized scrollbars</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={nativeScroll}
onChange={setNativeScroll}
>
Use native scroll
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && autoHide}
onChange={setAutoHide}
>
Auto-hide scrollbars
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && alwaysShowTrack}
onChange={setAlwaysShowTrack}
>
Always show track
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && redBackground}
onChange={setRedBackground}
>
Red background for scroll thumbs
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customSize}
onChange={setCustomSize}
>
Custom scrollbar size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customRadius}
onChange={setCustomRadius}
>
Custom radius (20px)
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
scrollProps={scrollProps}
nativeScroll={nativeScroll}
columns={columns}
enableKeyboardNavigation={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: "/"
<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 this prop). So, for example, expandedNodes
could look like this for a grid: expandedNodes={ 1: true, 3: true, '3/1': true', '3/2/1': true }
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600 }
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', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const App = () => {
const [expandedNodes, setExpandedNodes] = useState({ 3: 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}
nodePathSeparator="#"
onExpandedNodesChange={onExpandedNodesChange}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
String
default: "nodes"
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,
items: [
{
id: 1,
name: 'App store',
size: '4.5Mb',
items: null
},
{
id: 2,
name: 'iMovie',
size: '106Mb',
items: null
},
{
id: 3,
name: 'IRecall',
size: '200Mb'
}
]
},
{
id: 2,
name: 'Documents',
items: [
{
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',
items: [
{
id: 1,
name: 'Email data',
items: [
{
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 = { 1: true }
const App = () => {
return (
<div>
<p>DataGrid with nodes in "items" prop of each node</p>
<ReactDataGrid
nodesProperty="items"
defaultExpandedNodes={defaultExpandedNodes}
treeColumn={'name'}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Number[]
default: [5, 10, 20, 50, 100]
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, 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={10}
pageSizes={[5, 10, 20, 40, 80]}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Boolean|String
default: undefined
<ReactDataGrid />
- supports both local and remote pagination.pagination=true
to have the pagination toolbar displayed. By default, if local or remote pagination is not explicitly specified (by using pagination="local"
or pagination="remote"
), the <ReactDataGrid />
will figure out if it should use local or remote pagination depending on how the dataSource
is defined - if it's a remote dataSource
(a Promise
or a function) or a local one (an array).pagination="local"
pagination="remote"
.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', 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 [pagination, setPagination] = useState(true);
const dataSource = useCallback(loadData, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={pagination} onChange={setPagination}>
Pagination
</CheckBox>
</div>
<ReactDataGrid
key={'grid-' + pagination}
idProperty="id"
style={gridStyle}
columns={columns}
pagination={pagination}
sortable={false}
dataSource={dataSource}
defaultLimit={10}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
paginationProps
you can customize any prop that PaginationToolbar accepts and tweak it to fit your own specific configuration needs.limit
- used to configure the page size for the <ReactDataGrid />
.skip
- used to control skip value for the <ReactDataGrid />
.defaultLimit
- used to configure the default page size for the <ReactDataGrid />
.defaultSkip
- used to control the default skip value for the <ReactDataGrid />
.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: 500, marginTop: 10 }
const empty = () => null
const buttonStyle = { marginRight: 8 }
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 [skip, setSkip] = useState(10);
const [limit, setLimit] = useState(10);
const [sortInfo, setSortInfo] = useState(null);
const [loading, setLoading] = useState(false);
const dataSource = useCallback(loadData, [])
const updateSkip = useCallback((amount) => {
return () => {
let newSkip = skip + amount
newSkip = Math.min(newSkip, 100)
newSkip = Math.max(newSkip, 0)
setSkip(newSkip);
}
}, [skip])
const updateLimit = useCallback((amount) => {
return () => {
let newLimit = limit + amount
newLimit = Math.min(newLimit, 100)
newLimit = Math.max(newLimit, 0)
setLimit(newLimit);
}
}, [limit])
const sortByHandle = useCallback((colName, dir) => {
return () => {
setSortInfo({ name: colName, dir });
}
}, [])
const disabled = loading || Array.isArray(dataSource)
return (
<div>
<p>Current skip: {skip}. Current limit: {limit}.</p>
<div style={{ marginBottom: 20 }}>
<Button style={buttonStyle} onClick={updateSkip(10)} disabled={disabled}>skip += 10</Button>
<Button style={buttonStyle} onClick={updateSkip(-10)} disabled={disabled || skip==0}>skip -= 10</Button>
<Button style={buttonStyle} onClick={updateLimit(10)} disabled={disabled}>limit += 10</Button>
<Button onClick={updateLimit(-10)} disabled={disabled || limit<=10}>limit -= 10</Button>
</div>
<div style={{ marginBottom: 20 }}>
<Button style={buttonStyle} onClick={sortByHandle("firstName", 1)} disabled={disabled}>sort by First Name, ASC</Button>
<Button onClick={sortByHandle("lastName", -1)} disabled={disabled}>sort by Last Name, DESC</Button>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
sortInfo={sortInfo}
onSortInfoChange={setSortInfo}
pagination
limit={limit}
skip={skip}
onLimitChange={setLimit}
onSkipChange={setSkip}
renderPaginationToolbar={empty}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Array<string|{name,summaryReducer,summaryColumn}>
default: undefined
column.groupSummaryReducer
prop, so it can aggregate values, in order to display them in the pivoted cells.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: 500, marginTop: 10 }
const dataSource = () =>
Promise.resolve([
{
country: 'USA',
continent: 'North America',
year: 2000,
sport: 'footbal',
gold: 2,
silver: 3,
bronze: 1,
team: 'red',
},
{
country: 'USA',
continent: 'North America',
year: 2000,
sport: 'footbal',
gold: 1,
silver: 4,
bronze: 2,
team: 'blue',
},
{
country: 'USA',
continent: 'North America',
year: 2000,
sport: 'swim',
gold: 6,
silver: 4,
bronze: 2,
team: 'swim-blue',
},
{
country: 'USA',
continent: 'North America',
year: 2002,
sport: 'footbal',
gold: 1,
silver: 4,
bronze: 2,
team: 'star',
},
{
country: 'USA',
continent: 'North America',
year: 2002,
sport: 'swim',
gold: 10,
silver: 4,
bronze: 2,
team: 'swimmers',
},
{
country: 'USA',
continent: 'North America',
year: 2003,
sport: 'swim',
gold: 10,
silver: 4,
bronze: 2,
team: 'swimmers',
},
{
country: 'France',
continent: 'Europe',
year: 2003,
sport: 'footbal',
gold: 1,
silver: 4,
bronze: 2,
team: 'paris-team',
},
{
country: 'France',
continent: 'Europe',
year: 2004,
sport: 'swim',
gold: 3,
silver: 1,
bronze: 1,
team: 'paris-team',
},
{
country: 'France',
continent: 'Europe',
year: 2005,
sport: 'swim',
gold: 3,
silver: 1,
bronze: 1,
team: 'toulouse-team',
},
]);
const sumReducer = {
initialValue: 0,
reducer: (a: number, b: number) => a + b,
};
const countReducer = {
initialValue: 0,
reducer: (v: number) => v + 1,
};
const columns = [
{
name: 'country',
defaultFlex: 1,
header: 'Country'
},
{
name: 'continent',
defaultFlex: 1,
header: 'Continent'
},
{
name: 'year',
type: 'number',
header: 'Year',
},
{
name: 'gold',
groupSummaryReducer: sumReducer,
render: ({ value }) => (value || 0) + " gold",
renderSummary: ({ value, data }) => (value || 0) + " gold medals",
header: 'Gold medals'
},
{
name: 'silver',
groupSummaryReducer: sumReducer,
header: 'Silver medals'
},
{
name: 'bronze',
groupSummaryReducer: sumReducer,
header: 'Bronze medals'
},
{
name: 'sport',
header: 'Sport'
},
];
const App = () => {
const [enablePivot, setEnablePivot] = useState(true);
const [groupBy, setGroupBy] = useState(['continent','country','year']);
const [pivot, setPivot] = useState(['sport']);
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, ['continent','country','year'])
}, groupBy)
const updatePivot = useCallback((keys) => {
updateArray(pivot, setPivot, keys)
}, [pivot])
return (
<div>
<h3>DataGrid with pivot example</h3>
<div style={{ marginTop: 20}}>
<CheckBox
checked={enablePivot}
onChange={setEnablePivot}
>
Enable pivot
</CheckBox>
</div>
<div style={{ marginTop: 20}}>
<CheckBox
disabled={!enablePivot}
checked={pivot.indexOf('sport') !== -1}
onChange={checked => updatePivot({ sport: checked})}
>
Pivot by <b>sport</b> column values
</CheckBox>
</div>
<div style={{ marginTop: 20}}>
<CheckBox
checked={groupBy.indexOf('continent') !== -1}
onChange={checked => updateGroupBy({ continent: checked })}
>
Group by continent
</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('year') !== -1}
onChange={checked => updateGroupBy({ year: checked})}
>
Group by year
</CheckBox>
</div>
<ReactDataGrid
style={gridStyle}
columns={columns}
dataSource={dataSource}
pivot={enablePivot? pivot: null}
groupBy={groupBy}
groupNestingSize={40}
onGroupByChange={setGroupBy}
groupSummaryReducer={countReducer}
groupColumn={{
defaultFlex: 1,
minWidth: 250,
renderGroupValue: ({ value, groupSummary }) => (
<React.Fragment>
{value} ({groupSummary} records)
</React.Fragment>
),
}}
/>
</div>
)
}
export default () => <App />
Array<string|{name,summaryReducer,summaryColumn}>
default: undefined
column.groupSummaryReducer
prop, so it can aggregate values, in order to display them in the pivoted cells.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: 500, marginTop: 10 }
const dataSource = () =>
Promise.resolve([
{
country: 'USA',
continent: 'North America',
year: 2000,
sport: 'footbal',
gold: 2,
silver: 3,
bronze: 1,
team: 'red',
},
{
country: 'USA',
continent: 'North America',
year: 2000,
sport: 'footbal',
gold: 1,
silver: 4,
bronze: 2,
team: 'blue',
},
{
country: 'USA',
continent: 'North America',
year: 2000,
sport: 'swim',
gold: 6,
silver: 4,
bronze: 2,
team: 'swim-blue',
},
{
country: 'USA',
continent: 'North America',
year: 2002,
sport: 'footbal',
gold: 1,
silver: 4,
bronze: 2,
team: 'star',
},
{
country: 'USA',
continent: 'North America',
year: 2002,
sport: 'swim',
gold: 10,
silver: 4,
bronze: 2,
team: 'swimmers',
},
{
country: 'USA',
continent: 'North America',
year: 2003,
sport: 'swim',
gold: 10,
silver: 4,
bronze: 2,
team: 'swimmers',
},
{
country: 'France',
continent: 'Europe',
year: 2003,
sport: 'footbal',
gold: 1,
silver: 4,
bronze: 2,
team: 'paris-team',
},
{
country: 'France',
continent: 'Europe',
year: 2004,
sport: 'swim',
gold: 3,
silver: 1,
bronze: 1,
team: 'paris-team',
},
{
country: 'France',
continent: 'Europe',
year: 2005,
sport: 'swim',
gold: 3,
silver: 1,
bronze: 1,
team: 'toulouse-team',
},
]);
const sumReducer = {
initialValue: 0,
reducer: (a: number, b: number) => a + b,
};
const countReducer = {
initialValue: 0,
reducer: (v: number) => v + 1,
};
const columns = [
{
name: 'country',
defaultFlex: 1,
header: 'Country'
},
{
name: 'continent',
defaultFlex: 1,
header: 'Continent'
},
{
name: 'year',
type: 'number',
header: 'Year',
},
{
name: 'gold',
groupSummaryReducer: sumReducer,
render: ({ value }) => (value || 0) + " gold",
renderSummary: ({ value, data }) => (value || 0) + " gold medals",
header: 'Gold medals'
},
{
name: 'silver',
groupSummaryReducer: sumReducer,
header: 'Silver medals'
},
{
name: 'bronze',
groupSummaryReducer: sumReducer,
header: 'Bronze medals'
},
{
name: 'sport',
header: 'Sport'
},
];
const App = () => {
const [enablePivot, setEnablePivot] = useState(true)
const [groupBy, setGroupBy] = useState(['continent','country','year'])
const [pivot, setPivot] = useState([])
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, ['continent','country','year'])
}, [groupBy])
const updatePivot = useCallback((keys) => {
updateArray(pivot, setPivot, keys)
}, [pivot])
return (
<div>
<div style={{ marginTop: 20}}>
<CheckBox
checked={enablePivot}
onChange={setEnablePivot}
>
Enable pivot
</CheckBox>
</div>
<div style={{ marginTop: 20}}>
<CheckBox
disabled={!enablePivot}
checked={pivot.indexOf('sport') !== -1}
onChange={checked => updatePivot({ sport: checked})}
>
Pivot by <b>sport</b> column values
</CheckBox>
</div>
<div style={{ marginTop: 20}}>
<CheckBox
checked={groupBy.indexOf('continent') !== -1}
onChange={checked => updateGroupBy({ continent: checked })}
>
Group by continent
</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('year') !== -1}
onChange={checked => updateGroupBy({ year: checked})}
>
Group by year
</CheckBox>
</div>
<ReactDataGrid
style={gridStyle}
columns={columns}
dataSource={dataSource}
pivot={enablePivot? pivot: null}
groupBy={groupBy}
groupNestingSize={40}
onGroupByChange={setGroupBy}
groupSummaryReducer={countReducer}
groupColumn={{
defaultFlex: 1,
minWidth: 250,
renderGroupValue: ({ value, groupSummary }) => (
<React.Fragment>
{value} ({groupSummary} records)
</React.Fragment>
),
}}
/>
</div>
);
}
export default () => <App />
IColumn | () => IColumn
default: undefined
showPivotSummaryColumns=true
summaryColumn
can be a a column configuration object, or a function that returns a column configuration.pivot
array also needs to contain a name
- the name
or the id
of a column to be used for pivoting.summaryReducer
in order to specify how the pivot column summary will be computed.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',
hedaer: 'Id',
defaultVisible: false,
type: 'number',
maxWidth: 100,
},
{
id: 'year',
name: 'date',
header: 'Year',
pivotToString: (_, { data }) => {
return data.date.split('-')[0];
},
},
{
id: 'q1',
header: 'Q1',
name: 'amount',
pivotName: 'q1',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month <= 3),
render: ({ value }) => currency(value)
},
{
id: 'q2',
header: 'Q2',
name: 'amount',
pivotName: 'q2',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 3 && month <= 6),
render: ({ value }) => currency(value)
},
{
id: 'q3',
header: 'Q3',
pivotName: 'q3',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 6 && month <= 9),
render: ({ value }) => currency(value)
},
{
id: 'q4',
header: 'Q4',
pivotName: 'q4',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 9 && month <= 12),
render: ({ value }) => currency(value)
},
];
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: {
style: { color: '#7986cb' }
}
}
]
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</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={180}
pivot={enablePivot ? pivot : null}
groupBy={groupBy}
showPivotSummaryColumns={showPivotSummaryColumns}
pivotGrandSummaryColumn={{
header: 'TOTAL',
style: { color: '#ef9a9a' },
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;
if (groupColumn) {
return <div style={footerCellStyle}>
<b>Total sales</b>
</div>
}
let result;
if (pivotSummaryPath && pivotSummaryPath.length) {
const pivotInfo = [...pivotSummaryPath].pop();
const pivotValue = pivotInfo.value;
result = summary[pivotValue];
} else if (pivotColumnPath) {
result = summary[(pivotColumnPath || []).join('-')] || 0;
} else if (pivotGrandSummaryColumn) {
result = summary.total;
}
return (
<div style={footerCellStyle}>
<b>{currency(result || 0)}</b>
</div>
);
},
},
]}
/>
</div>
);
}
export default () => <App />;
{reducer,initialValue,complete}
default: undefined
showPivotSummaryColumns=true
pivot
array also needs to contain a name
, and can also contain a summaryColumn
- which can be a a column configuration object, or a function that returns a column configuration.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',
header: 'Q1',
name: 'amount',
pivotName: 'q1',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month <= 3),
render: ({ value }) => currency(value),
textAlign: 'end',
},
{
id: 'q2',
header: 'Q2',
name: 'amount',
pivotName: 'q2',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 3 && month <= 6),
render: ({ value }) => currency(value),
textAlign: 'end',
},
{
id: 'q3',
header: 'Q3',
pivotName: 'q3',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 6 && month <= 9),
render: ({ value }) => currency(value),
textAlign: 'end',
},
{
id: 'q4',
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: {
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])
const updatePivot = useCallback((keys) => {
updateArray(pivot, keys);
}, [pivot])
return (
<div>
<h3>Grid pivoted by year</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={180}
pivot={enablePivot ? pivot : null}
groupBy={groupBy}
showPivotSummaryColumns={showPivotSummaryColumns}
pivotGrandSummaryColumn={{
header: 'TOTAL',
style: { color: '#ef9a9a' },
render: ({ data }) => <b>{currency(data.groupSummary.grandTotal)}</b>
}}
onGroupByChange={groupBy => setGroupBy(groupBy)}
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;
if (groupColumn) {
return <div style={footerCellStyle}>
<b>Total sales</b>
</div>
}
let result;
if (pivotSummaryPath && pivotSummaryPath.length) {
const pivotInfo = [...pivotSummaryPath].pop();
const pivotValue = pivotInfo.value;
result = summary[pivotValue];
} else if (pivotColumnPath) {
result = summary[(pivotColumnPath || []).join('-')] || 0;
} else if (pivotGrandSummaryColumn) {
result = summary.total;
}
return (
<div style={footerCellStyle}>
<b>{currency(result || 0)}</b>
</div>
);
},
},
]}
/>
</div>
);
}
export default () => <App />;
IColumn
default: undefined
showPivotSummaryColumns=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 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: 'Contry' },
{ 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',
header: 'Q1',
name: 'amount',
pivotName: 'q1',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month <= 3),
render: ({ value }) => currency(value)
},
{
id: 'q2',
header: 'Q2',
name: 'amount',
pivotName: 'q2',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 3 && month <= 6),
render: ({ value }) => currency(value),
textAlign: 'center'
},
{
id: 'q3',
header: 'Q3',
pivotName: 'q3',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 6 && month <= 9),
render: ({ value }) => currency(value),
textAlign: 'center'
},
{
id: 'q4',
header: 'Q4',
pivotName: 'q4',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 9 && month <= 12),
render: ({ value }) => currency(value),
textAlign: 'center'
},
];
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: {
textAlign: 'center',
style: { color: '#7986cb' }
}
}
]
const App = () => {
const [enablePivot, setEnablePivot] = useState(true)
const [groupBy, setGroupBy] = useState(['region', 'city'])
const [showPivotSummaryColumns, setShowPivotSummaryColumns] = useState(true)
const [showPivotGrandSummaryColumn, setShowPivotGrandSummaryColumn] = 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</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={180}
pivot={enablePivot ? pivot : null}
groupBy={groupBy}
showPivotSummaryColumns={showPivotSummaryColumns}
pivotGrandSummaryColumn={showPivotGrandSummaryColumn? {
header: 'TOTAL',
style: { color: '#ef9a9a' },
render: ({ data }) => <b>{currency(data.groupSummary.grandTotal)}</b>
}: null}
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;
if (groupColumn) {
return <div style={footerCellStyle}>
<b>Total sales</b>
</div>
}
let result;
if (pivotSummaryPath && pivotSummaryPath.length) {
const pivotInfo = [...pivotSummaryPath].pop();
const pivotValue = pivotInfo.value;
result = summary[pivotValue];
} else if (pivotColumnPath) {
result = summary[(pivotColumnPath || []).join('-')] || 0;
} else if (pivotGrandSummaryColumn) {
result = summary.total;
}
return (
<div style={footerCellStyle}>
<b>{currency(result || 0)}</b>
</div>
);
},
},
]}
/>
</div>
);
}
export default () => <App />
Bool
default: true
shift
key when clicking to end/extend a selection.event.preventDefault()
for the mouseDown
event that occurs inside <ReactDataGrid />
rows.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 defaultSelected={}
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 [preventDefaultTextSelectionOnShiftMouseDown, setPreventDefaultTextSelectionOnShiftMouseDown] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={preventDefaultTextSelectionOnShiftMouseDown}
onChange={setPreventDefaultTextSelectionOnShiftMouseDown}
>
Prevent default text selection on shift + mouseDown
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultSelected={defaultSelected}
enableSelection
columnUserSelect
preventDefaultTextSelectionOnShiftMouseDown={preventDefaultTextSelectionOnShiftMouseDown}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
onSelectionChange
) being triggered on click on a row when the user moves the mouse before releasing it - this defaults to true
in order to avoid selecting the row when in fact text selection/highlight is intended.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 defaultSelected = {}
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 [preventRowSelectionOnClickWithMouseMove, setPreventRowSelectionOnClickWithMouseMove] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={preventRowSelectionOnClickWithMouseMove}
onChange={setPreventRowSelectionOnClickWithMouseMove}
>
Prevent row selection on click with mouse move
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultSelected={defaultSelected}
enableSelection
columnUserSelect
preventRowSelectionOnClickWithMouseMove={preventRowSelectionOnClickWithMouseMove}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(menuProps, { cellProps, props, grid })
default: undefined
<ReactDataGrid />
column header. This function prop is called with menuProps
as a first param. Either modify those props and set the desired properties on this object (like items
) and return undefined
, or return the <Menu />
component you want to render.renderColumnContextMenu
function prop returns undefined
, the default Menu is rendered (beware, it has no items
by default).renderColumnContextMenu
function prop is an object with { cellPRops, props, grid }
, where cellPRops
are the props of the clicked column header, props
are the computed props of the <ReactDataGrid />
and grid
is a reference to the <ReactDataGrid />
instance.import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 600 }
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 renderColumnContextMenu = useCallback((menuProps, { cellProps }) => {
menuProps.items = menuProps.items.concat([
{
label: 'Custom item for "' + cellProps.name + '"',
onClick: () => {
inovua.notification.first.addNotification({
title: 'Custom notification for column ' + cellProps.name,
content: 'Column context menu item clicked'
})
menuProps.onDismiss()
}
},
{
label: 'Another custom menu item',
onClick: () => {
inovua.notification.first.addNotification({
title: 'Custom notification for column ' + cellProps.name,
content: 'Second custom column context menu item clicked!!!'
})
menuProps.onDismiss()
}
}
])
}, [])
return (
<div>
<NotificationBoard id="first" />
<ReactDataGrid
idProperty="id"
style={gridStyle}
renderColumnContextMenu={renderColumnContextMenu}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(menuProps, { cellProps, props, grid })
default: undefined
<ReactDataGrid />
column filter. This function prop is called with menuProps
as a first param. Either modify those props and set the desired properties on this object (like items
) and return undefined
, or return the <Menu />
component you want to render.renderColumnFilterContextMenu
function prop returns undefined
, the default Menu is rendered (beware, it has no items
by default).renderColumnFilterContextMenu
function prop is an object with { cellPRops, props, grid }
, where cellPRops
are the props of the clicked column header, props
are the computed props of the <ReactDataGrid />
and grid
is a reference to the <ReactDataGrid />
instance.import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 600 }
const defaultFilterValue = [
{ name: 'name', type: 'string', value: '', operator: 'contains' },
{ name: 'country', type: 'string', value: '', operator: 'contains' },
{ name: 'city', type: 'string', value: '', operator: 'contains' },
{ name: 'age', type: 'number', value: null, operator: 'gt' }
];
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultFlex: 1,
heade: '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 renderColumnFilterContextMenu = useCallback((menuProps, { cellProps }) => {
menuProps.items = menuProps.items.concat([
{
label: 'Custom filter item for "' + cellProps.name + '"',
onClick: () => {
inovua.notification.first.addNotification({
title: 'Custom notification for column ' + cellProps.name,
content: 'Column context menu item clicked'
})
}
},
{
label: 'Another custom filter item',
onClick: () => {
inovua.notification.first.addNotification({
title: 'Custom notification for column ' + cellProps.name,
content: 'Second custom column context menu item clicked!!!'
})
}
}
])
}, [])
return (
<div>
<NotificationBoard id="first" />
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={defaultFilterValue}
renderColumnFilterContextMenu={renderColumnFilterContextMenu}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(props): ReactNode
default: undefined
<ReactDataGrid />
to show a custom proxy on column reordering.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 CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox';
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 [reorderColumns, setReorderColumns] = useState(true);
const renderColumnReorderProxy = props => {
return <div style={{ color: 'lightgreen' }}>{props.children}</div>;
};
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
theme="default-dark"
checked={reorderColumns}
onChange={setReorderColumns}
>
Enable column reordering
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
reorderColumns={reorderColumns}
columns={columns}
dataSource={people}
sortable={false}
renderColumnReorderProxy={renderColumnReorderProxy}
/>
</div>
);
};
export default () => <App />;
Fn(rowDetailsInfo)
default: undefined
data
- the data item corresponding to the current expanded rowrowSelected
- specifies if the current row is selected
rowActive
- specifies if the current row is active
rowExpanded
- specifies if the current row is currently expandedrowId
- the value of the idProperty
for the current row data objecttoggleRowExpand
- you can call this function with no arguments to collapse the current rowdataSource
- a reference to the current dataSource
array that the <ReactDataGrid />
displaysrenderRowDetails
- which you can use to render anything as a row detail.rowExpandHeight
to determine the height of the expanded content.renderDetailsGrid
. Further levels are possible, but not yet fully supported - this will be released in a future minor version.import React, { useState, useCallback } 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 Button from '@inovua/reactdatagrid-community/packages/Button'
import API_URL from './API_URL'
const accountsGridStyle = { minHeight: 800 }
const getDataSource = (entity) => {
return ({ skip, limit, sortInfo, groupBy, filterValue }) => {
const queryParams = [
skip ? "skip=" + skip : null,
limit ? "limit=" + limit : null,
groupBy && groupBy.length ? "groupBy=" + groupBy : null,
filterValue && filterValue.length
? "filterBy=" + JSON.stringify(
filterValue.filter(v => v.active !== false).map(v => ({
value: v.value,
name: v.name,
operator: v.operator,
type: v.type
}))
)
: null,
sortInfo ? "sortInfo=" + JSON.stringify(sortInfo) : null
]
.filter(value => value)
.join('&');
return fetch(API_URL + '/' + entity + '?' + queryParams).then(response => {
const totalCount = response.headers.get('X-Total-Count');
return response.json().then(data => {
return { data, count: parseInt(totalCount) };
})
})
}
}
const accountsDataSource = getDataSource('accounts')
const floatNumber = value => Number(value).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
const renderGroupTitle = value => value || 'N/A';
const renderLabeledGroupTitle = value => value ? value.label : 'N/A';
const defaultVisible = false
const GridLink = ({ value }) => <a style={{ color: '#9ba7b4' }} href={value} target="_blank">
{value}
</a>
const columns = [
{ name: 'id', maxWidth: 50, defaultVisible, header: 'Id', defaultVisible: false },
{ name: 'name', renderGroupTitle, header: 'Name' },
{ name: 'email', renderGroupTitle, header: 'Email' },
{ name: 'phone', renderGroupTitle, header: 'Phone' },
{
name: 'website',
header: 'Website',
renderGroupTitle,
render: ({ data }) => <GridLink value={data.website} />
},
{
name: 'type',
header: 'Type',
renderGroupTitle,
groupToString: value => value ? value.label: 'N/A',
filterEditor: SelectFilter,
sortName: 'type.label',
groupByName: 'type.label',
render: ({ data }) => {
return data.type && data.type.label;
}
},
{
name: 'industry',
header: 'Industry',
filterEditor: SelectFilter,
renderGroupTitle,
groupToString: value => value ? value.label: 'N/A',
sortName: 'industry.label',
groupByName: 'industry.label',
render: ({ data }) => {
return data.industry && data.industry.label;
}
},
{
name: 'annualRevenue',
header: 'Annual Revenue',
filterEditor: NumberFilter,
defaultVisible,
renderGroupTitle,
type: 'number',
filterDelay: 500,
render: ({ data }) => "$ " + floatNumber(data.annualRevenue)
},
{
name: 'noOfEmployees',
header: '# of Employees',
filterEditor: NumberFilter,
defaultVisible,
renderGroupTitle
},
{
name: 'facebook',
header: 'Facebook',
renderGroupTitle,
defaultVisible,
render: ({ data }) => <GridLink value={data.facebook} />
},
{
name: 'twitter',
header: 'Twitter',
renderGroupTitle,
defaultVisible,
render: ({ data }) => <GridLink value={data.twitter} />
},
{
name: 'linkedIn',
header: 'LinkedIn',
renderGroupTitle,
defaultVisible,
render: ({ data }) => <GridLink value={data.linkedIn} />
}
];
const dataSourceCache = {}
const contactsColumns = [
{ name: 'id', maxWidth: 50, defaultVisible, header: 'Id', defaultVisible: false },
{
name: 'firstName',
header: 'Name',
renderGroupTitle,
render: ({ data }) => data.firstName + " " + data.lastName
},
{ name: "email", renderGroupTitle, header: 'Email' },
{ name: "phone", renderGroupTitle, header: 'Phone' },
{
name: "account",
header: 'Account',
defaultVisible,
groupByName: "account.name",
sortName: "account.name",
filterName: "account.name",
minWidth: 250
},
{
name: 'dateOfBirth',
header: 'Date of Birth',
defaultVisible,
renderGroupTitle,
render: ({ data }) => {
return data.dateOfBirth.toString();
}
},
{
name: 'facebook',
header: 'Facebook',
defaultVisible,
resizable: true,
renderGroupTitle,
group: 'socialMedia',
render: ({ data }) => {
return <GridLink value={data.facebook} />;
}
},
{
name: 'twitter',
header: 'Twitter',
group: 'socialMedia',
resizable: true,
defaultVisible,
renderGroupTitle,
render: ({ data }) => {
return <GridLink value={data.twitter} />;
}
},
{
name: 'linkedIn',
header: 'Linked In',
defaultVisible,
group: 'socialMedia',
resizable: true,
renderGroupTitle,
render: ({ data }) => {
return <GridLink value={data.linkedIn} />;
}
},
{
name: 'address',
header: 'Address',
defaultVisible,
renderGroupTitle,
group: 'contactInfo'
}
];
const getContactsFilterValue = (account) => {
return [
{
name: 'account.id',
value: account ? account.id: '',
operator: 'eq',
type: 'string'
},
{
name: 'firstName',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'phone',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'email',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'account',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'facebook',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'twitter',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'address',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'createdBy',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'linkedIn',
type: 'string',
operator: 'contains',
value: ''
},
{
name: 'permissionToCall',
type: 'bool',
operator: 'eq',
value: null
},
{
name: 'permissionToEmail',
type: 'bool',
operator: 'eq',
value: null
}
]
}
const defaultGroupBy = []
const accountRowHeight = 40
const contactRowHeight = accountRowHeight
const accountExpandHeight = 500
const contactsDataSource = getDataSource('contacts')
const App = () => {
const [accountRowHeights, setAccountRowHeights] = useState({})
const renderContactsGrid = useCallback(({ data }) => {
const defaultFilterValue = getContactsFilterValue(data);
return (
<ReactDataGrid
defaultFilterValue={defaultFilterValue}
dataSource={contactsDataSource}
pagination
columns={contactsColumns}
columnDefaultWidth={200}
/>
);
}, [])
return (
<ReactDataGrid
dataSource={accountsDataSource}
style={accountsGridStyle}
rowHeight={accountRowHeight}
pagination
rowExpandHeight={accountExpandHeight}
rowHeights={accountRowHeights}
renderDetailsGrid={renderContactsGrid}
defaultGroupBy={defaultGroupBy}
columnDefaultWidth={200}
columns={columns}
/>
);
}
export default () => <App />
Fn({ domProps: Object, size: Number, rtl: 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'
const gridStyle = { minHeight: 400 };
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 defaultGroupBy = ['country'];
const renderGroupCollapseTool = ({ domProps, size, rtl }) => {
return (
<svg {...domProps} height={size} width={size} viewBox="0 0 48 48">
{rtl ? (
<g transform="rotate(180, 24, 24)">
<path d="M24 40 21.9 37.85 34.25 25.5H8V22.5H34.25L21.9 10.15L24 8L40 24Z" />
</g>
) : (
<path d="M24 40 21.9 37.85 34.25 25.5H8V22.5H34.25L21.9 10.15L24 8L40 24Z" />
)}
</svg>
);
};
const renderGroupExpandTool = ({ domProps, size }) => {
return (
<svg {...domProps} height={size} width={size} viewBox="0 0 48 48">
<path d="M24 40 8 24 10.1 21.9 22.5 34.3V8H25.5V34.3L37.9 21.9L40 24Z" />
</svg>
);
};
const App = () => {
const [rtl, setRtl] = useState(false);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={rtl}
onChange={setRtl}
>
Right-to-left
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={defaultGroupBy}
columns={columns}
dataSource={people}
rtl={rtl}
renderGroupCollapseTool={renderGroupCollapseTool}
renderGroupExpandTool={renderGroupExpandTool}
/>
</div>
)
}
export default () => <App />
Fn({ domProps: Object, size: Number, rtl: 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'
const gridStyle = { minHeight: 400 };
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 defaultGroupBy = ['country'];
const renderGroupCollapseTool = ({ domProps, size, rtl }) => {
return (
<svg {...domProps} height={size} width={size} viewBox="0 0 48 48">
{rtl ? (
<g transform="rotate(180, 24, 24)">
<path d="M24 40 21.9 37.85 34.25 25.5H8V22.5H34.25L21.9 10.15L24 8L40 24Z" />
</g>
) : (
<path d="M24 40 21.9 37.85 34.25 25.5H8V22.5H34.25L21.9 10.15L24 8L40 24Z" />
)}
</svg>
);
};
const renderGroupExpandTool = ({ domProps, size }) => {
return (
<svg {...domProps} height={size} width={size} viewBox="0 0 48 48">
<path d="M24 40 8 24 10.1 21.9 22.5 34.3V8H25.5V34.3L37.9 21.9L40 24Z" />
</svg>
);
};
const App = () => {
const [rtl, setRtl] = useState(false);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={rtl}
onChange={setRtl}
>
Right-to-left
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={defaultGroupBy}
columns={columns}
dataSource={people}
rtl={rtl}
renderGroupCollapseTool={renderGroupCollapseTool}
renderGroupExpandTool={renderGroupExpandTool}
/>
</div>
)
}
export default () => <App />
Fn({ value, name, fieldPath, ... }, rowProps)
default: undefined
groupBy
.column.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 renderGroupTitle = (value, { data }) => {
const columns = data.fieldPath.map(col => col === data.name ? col.toUpperCase() : col)
const path = columns && columns.length && columns.join('>');
return path + ': ' + data.value
}
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}
renderGroupTitle={renderGroupTitle}
/>
</div>
);
}
export default () => <App />
({visible,livePagination,zIndex,loadingText})=>ReactNode
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 550 }
const renderLoadMask = ({
visible,
livePagination,
loadingText,
zIndex
}) => {
return <div style={{
top: 0, left: 0, right: 0, bottom: 0,
zIndex,
background: 'rgba(121, 134, 203, 0.25)',
color: '#ef9a9a',
opacity: 0.6,
display: 'flex',
position: 'absolute',
alignItems: 'center',
justifyContent: 'center'
}}>
Loading...
</div>
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultFlex: 1, defaultWidth: 100 },
{ name: 'country', header: 'Country', defaultFlex: 1, defaultWidth: 100 },
{ name: 'city', header: 'City', defaultFlex: 1, defaultWidth: 100 },
{ name: 'age', header: 'Age', defaultWidth: 150, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
loading={true}
renderLoadMask={renderLoadMask}
columns={columns}
dataSource={[]}
/>
</div>
);
}
export default () => <App />
Fn(props: Object)
default: undefined
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 renderMenuTool = ({ className }) => {
return (
<svg className={className} height="24px" viewBox="0 0 24 24" width="24px">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M3 18h13v-2H3v2zm0-5h10v-2H3v2zm0-7v2h13V6H3zm18 9.59L17.42 12 21 8.41 19.59 7l-5 5 5 5L21 15.59z" />
</svg>
);
};
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,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
renderMenuTool={renderMenuTool}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(domProps, cellProps)
default: undefined
<ReactDataGrid />
with the tree functionality.undefined
is possible - it's a common scenario, if you just want to enhance/update the passed domProps
.cellProps
object received as a second parameter is an enhanced cellProps
object, meaning it also contains information about the current tree node - it contains the following extra props:leafNode
- specifies if the current node is a leafnodeCollapsed
- bool prop that specifies if the current node is collapsednodeLoading
- bool prop that specifies if the current node is currently loadingnodeProps
- an object with more info about the node - parentId, path, depth, etctoggleNodeExpand
- function which can be called if you want to update the expand/collapsed state of the node. When you call this function you don't have to pass any params to it.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600 }
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 renderNodeTool = (domProps) => {
domProps.style.color = '#7986cb'
domProps.style.fill = '#7986cb'
}
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const App = () => {
const [expandedNodes, setExpandedNodes] = useState({ 3: 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"
renderNodeTool={renderNodeTool}
expandedNodes={expandedNodes}
onExpandedNodesChange={onExpandedNodesChange}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn(paginationProps: Object)
default: undefined
paginationProps
argument contains all the necessary info & callback functions to display a pagination toolbar and respond to user interaction properly.<ReactDataGrid />
PaginationToolbar
is an independent component, and it is rendered using the same paginationProps
object.import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import PaginationToolbar from '@inovua/reactdatagrid-community/packages/PaginationToolbar'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 300, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 40 },
{ name: 'firstName', header: 'First Name', groupBy: false, defaultWidth: 135 },
{ name: 'lastName', header: 'Last Name', defaultWidth: 135 },
{ name: 'email', header: 'Email', groupBy: false, defaultWidth: 135 },
{
name: 'permissionToCall', header: 'Permission to call', minWidth: 100,
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value === true || value === 'true' ? 'Calls allowed' : 'No calls allowed'
}
]
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 dataSource = useCallback(loadData, [])
const renderPaginationToolbar = useCallback((paginationProps) => {
return <div style={{ height: 89 }}>
<PaginationToolbar {...paginationProps} bordered={false} />
<div style={{background: '#7986cb', color: '#2e3439', padding: '16px 8px' }}>
This section is part of the customized pagination toolbar
</div>
</div>
}, [])
return (
<div>
<ReactDataGrid
idProperty="id"
renderPaginationToolbar={renderPaginationToolbar}
style={gridStyle}
columns={columns}
pagination
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(menuProps, { rowProps, cellProps, computedProps, grid })
default: undefined
<ReactDataGrid />
rows. This function prop is called with menuProps
as a first param. Either modify those props and set the desired properties on this object (like items
) and return undefined
, or return the <Menu />
component you want to render.renderRowContextMenu
function prop returns undefined
, the default Menu is rendered (beware, it has no items
by default).renderRowContextMenu
function prop is an object with { rowProps, cellProps, computedProps, computedPropsRef }
, where rowProps
are the props of the clicked row, cellProps
are the props of the clicked cell, computedProps
are the computed props of the <ReactDataGrid />
and computedPropsRef
is a ref to the latest computedProps
objectimport React, { 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', 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 renderRowContextMenu = useCallback((menuProps, { rowProps }) => {
menuProps.autoDismiss = true
menuProps.items = [
{
label: 'Row ' + rowProps.rowIndex
},
{
label: 'Want to visit ' + rowProps.data.country + '?'
}
]
}, [])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
renderRowContextMenu={renderRowContextMenu}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ data, rowSelected, rowActive, dataSource, rowIndex, toggleRowExpand })
default: undefined
data
- the data item corresponding to the current expanded rowrowSelected
- specifies if the current row is selected
rowActive
- specifies if the current row is active
rowExpanded
- specifies if the current row is currently expandedrowId
- the value of the idProperty
for the current row data objecttoggleRowExpand
- you can call this function with no arguments to collapse the current rowdataSource
- a reference to the current dataSource
array that the <ReactDataGrid />
displaysrowExpandHeight
to control the height of the expanded rows. As a result, the row details available height is equal to rowExpandHeight - rowHeight
.rowDetailsWidth
.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 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' }
]
const App = () => {
return (
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
renderRowDetails={renderRowDetails}
style={gridStyle}
rowExpandHeight={400}
columns={columns}
dataSource={people}
/>
);
}
export default () => <App />
Fn()
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 renderRowDetails = ({ data }) => {
return (
<div style={{ padding: 20 }}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map((name, i) => {
return (
<tr key={i}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
};
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'email', header: 'Email', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120 },
{ name: 'city', header: 'City', defaultWidth: 120 },
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 },
];
const renderRowDetailsExpandIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z" />
</svg>
);
};
const renderRowDetailsCollapsedIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" />
</svg>
);
};
const renderRowDetailsMoreIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
</svg>
);
};
const App = () => {
return (
<div>
<h3>Grid showing row details on expand - controlled</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
renderRowDetailsExpandIcon={renderRowDetailsExpandIcon}
renderRowDetailsCollapsedIcon={renderRowDetailsCollapsedIcon}
renderRowDetailsMoreIcon={renderRowDetailsMoreIcon}
/>
</div>
);
};
export default () => <App />;
Fn()
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 renderRowDetails = ({ data }) => {
return (
<div style={{ padding: 20 }}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map((name, i) => {
return (
<tr key={i}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
};
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'email', header: 'Email', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120 },
{ name: 'city', header: 'City', defaultWidth: 120 },
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 },
];
const renderRowDetailsExpandIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z" />
</svg>
);
};
const renderRowDetailsCollapsedIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" />
</svg>
);
};
const renderRowDetailsMoreIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
</svg>
);
};
const App = () => {
return (
<div>
<h3>Grid showing row details on expand - controlled</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
renderRowDetailsExpandIcon={renderRowDetailsExpandIcon}
renderRowDetailsCollapsedIcon={renderRowDetailsCollapsedIcon}
renderRowDetailsMoreIcon={renderRowDetailsMoreIcon}
/>
</div>
);
};
export default () => <App />;
Fn()
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 renderRowDetails = ({ data }) => {
return (
<div style={{ padding: 20 }}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map((name, i) => {
return (
<tr key={i}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
};
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'email', header: 'Email', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120 },
{ name: 'city', header: 'City', defaultWidth: 120 },
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 },
];
const renderRowDetailsExpandIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z" />
</svg>
);
};
const renderRowDetailsCollapsedIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" />
</svg>
);
};
const renderRowDetailsMoreIcon = () => {
return (
<svg height="24px" viewBox="0 0 24 24" width="24px" fill="#fafafa">
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" />
</svg>
);
};
const App = () => {
return (
<div>
<h3>Grid showing row details on expand - controlled</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
renderRowDetailsExpandIcon={renderRowDetailsExpandIcon}
renderRowDetailsCollapsedIcon={renderRowDetailsCollapsedIcon}
renderRowDetailsMoreIcon={renderRowDetailsMoreIcon}
/>
</div>
);
};
export default () => <App />;
Fn({ data, dragIndex }): ReactNode
default: undefined
<ReactDataGrid />
to show a custom proxy on row reordering.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 renderRowReorderProxy = ({data}) => {
return <div style={{ paddingLeft: 30 }}>ID: {data.id} - Name: {data.name}</div>
}
const columns = [
{ name: 'id', header: 'Id', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 }
]
const App = () => {
return (
<div>
<h3>Drag to reorder - also notice custom reorder proxy</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={40}
rowReorderColumn
renderRowReorderProxy={renderRowReorderProxy}
columns={columns}
dataSource={[].concat(people)}
/>
</div>
)
}
export default () => <App />
Fn(direction, extraProps)
default: undefined
columns.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 },
{ name: 'firstName', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
defaultSortInfo={defaultSortInfo}
style={gridStyle}
renderSortTool={renderSortTool}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ domProps: Object, size: number })
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'
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 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 custom collapse tool</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={showTools} onChange={setShowTools}>Show tools</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
renderTreeCollapseTool={showTools ? renderCollapseTool : null}
renderTreeExpandTool={showTools ? renderExpandTool : null}
expandOnMouseDown
/>
</div>
);
}
export default () => <App />
Fn({ domProps: Object, size: number })
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'
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 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 custom expand tool</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={showTools} onChange={setShowTools}>Show tools</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
renderTreeCollapseTool={showTools ? renderCollapseTool : null}
renderTreeExpandTool={showTools ? renderExpandTool : null}
expandOnMouseDown
/>
</div>
);
}
export default () => <App />
Fn({ domProps: Object, size: number, className: string })
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'
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 [showLoadingSpinner, setShowLoadingSpinner] = useState(true);
const renderTreeLoadingTool = ({ domProps, size, className }) => {
if (!showLoadingSpinner) {
return (
<div style={Object.assign(domProps.style, { width: size })}></div>
);
}
return (
<svg
{...domProps}
className={className}
height={size}
viewBox="0 0 24 24"
width={size}
fill="#49ffff"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" />
</svg>
);
};
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 },
]);
}, 2000);
});
};
return (
<div>
<h3>TreeGrid with custom loading spinner</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={showLoadingSpinner} onChange={setShowLoadingSpinner}>Show loading spinner</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
renderTreeLoadingTool={renderTreeLoadingTool}
loadNode={loadNode}
/>
</div>
);
}
export default () => <App />
Bool
default: true
column.draggable=false
will not allow the user to drag the column and move it somewhere else. Note, however, that although a column is not draggable, it can change its position because other draggable columns can be drag-dropped and change column order.column.draggable=false
, this will ensure no other columns can be dropped over, so it will remain the first or the last column.columnOrder
. When the column order is changed via user interaction, onColumnOrderChange(columnOrder: String[])
is called.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 [reorderColumns, setReorderColumns] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={reorderColumns} onChange={setReorderColumns}>
Enable column reordering
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
reorderColumns={reorderColumns}
columns={columns}
dataSource={people}
sortable={false}
/>
</div>
);
}
export default () => <App />
Number
default: undefined
<ReactDataGrid />
has flex columns.reservedViewportWidth
is specified to be 200
, there will be a 200px empty space at the end, so the flex column will only be 600px wide.null
or undefined
means there will be no reserved space, so the whole viewport will be used.shareSpaceOnResize=false
), the <ReactDataGrid />
will fire onReservedViewportWidthChange(reservedViewportWidth)
(in our case, reservedViewportWidth=100
)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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultFlex: 1 },
{ name: 'firstName', header: 'Name', defaultFlex: 3 },
{ name: 'country', header: 'Country', defaultFlex: 2,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultFlex: 1 }
]
const App = () => {
const [reservedViewportWidth, setReservedViewportWidth] = useState(null);
return (
<div>
<div style={{marginBottom: 20}}>
Columns with flex values of 1, 2, and 3
</div>
<div style={{marginBottom: 20}}>
Reserved viewport width: {reservedViewportWidth ? reservedViewportWidth + 'px' : 'none'}.
Resize/shrink columns and then click the reset button below.
</div>
<div style={{marginBottom: 20}}>
<Button onClick={() => setReservedViewportWidth(null)}>
Clear reserved width
</Button>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
reservedViewportWidth={reservedViewportWidth}
onReservedViewportWidthChange={setReservedViewportWidth}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
<ReactDataGrid />
columns. Specify resizable=false
to make all columns unresizable.resizable=false
only for one column, see column.resizable.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: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'country', defaultFlex: 1, header: 'Country' },
{
id: 'desc',
header: 'Description',
defaultFlex: 2,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [resizable, setResizable] = useState(true)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={resizable}
onChange={setResizable}
>
Toggle resizable for all columns
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
resizable={resizable}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String|HTMLElement|Boolean|Fn
default: undefined
<ReactDataGrid />
constrains the row 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, { 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: 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 = () => {
const renderRowContextMenu = useCallback((menuProps, { rowProps }) => {
menuProps.autoDismiss = true
menuProps.items = [
{
label: 'Row ' + rowProps.rowIndex
},
{
label: 'You clicked row ' + rowProps.rowIndex
},
{
label: 'Want to visit ' + rowProps.data.country + '?'
},
{
label: 'Menu for row ' + rowProps.rowIndex
}
]
}, [])
return (
<div>
<p>Row context menu constrained to document.documentElement</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowContextMenuConstrainTo={true}
rowContextMenuPosition={"fixed"}
renderRowContextMenu={renderRowContextMenu}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
position: absolute
.rowContextMenuConstrainTo
to make the menu constrained to a different element - in which case, you should use "fixed"
positioning.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: 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 = () => {
const renderRowContextMenu = useCallback((menuProps, { rowProps }) => {
menuProps.autoDismiss = true
menuProps.items = [
{
label: 'Row ' + rowProps.rowIndex
},
{
label: 'You clicked row ' + rowProps.rowIndex
},
{
label: 'Want to visit ' + rowProps.data.country + '?'
},
{
label: 'Menu for row ' + rowProps.rowIndex
}
]
}, [])
return (
<div>
<p>Row context menu constrained to document.documentElement</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowContextMenuConstrainTo={true}
rowContextMenuPosition={"fixed"}
renderRowContextMenu={renderRowContextMenu}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: "max-viewport-width"
"max-viewport-width"
- the width of the row details will be maximum the width of the grid viewport width. When columns take up less space, the row details will be sized to the total width of the columns. If columns don't fit in the grid viewport and horizontal scrollbar is needed, the row details will be still constrained to the width of the grid viewport."min-viewport-width"
- the width of the row details will be minimum the width of the grid viewport width. When columns take up less space, the row details will be sized to fill the grid viewport. If columns don't fit in the grid viewport and horizontal scrollbar is needed, the row details will grow with the total columns width, and will be scrolled together with the grid viewport."viewport-width"
- the width of the row details will be exactly the width of the grid viewport width, no matter the size of grid columns.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import RadioButtonGroup from '@inovua/reactdatagrid-community/packages/RadioButtonGroup'
import people from './people'
const rowDetailsWidthOptions = [
{ value: 'max-viewport-width', label: 'max-viewport-width' },
{ value: 'min-viewport-width', label: 'min-viewport-width' },
{ value: 'viewport-width', label: 'viewport-width' }
]
const gridStyle = { minHeight: 550 };
const renderRowDetails = ({ data }) => {
return (
<div style={{ background: '#434d65', color: '#c5cae9', 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 expandedRows = { 1: true };
const columns = [
{ name: 'id', defaultWidth: 300, header: 'Id', defaultVisible: false },
{ name: 'name', defaultWidth: 600, header: 'Name' },
{ name: 'country', defaultWidth: 600, header: 'Country' },
{ name: 'age', type: 'number', defaultWidth: 600, header: 'Age' }
]
const App = () => {
const [rowDetailsWidth, setRowDetailsWidth] = useState('max-viewport-width');
return (
<div>
<p>Select a value for rowDetailsWidth:</p>
<RadioButtonGroup
style={{ marginTop: 20, marginBottom: 20 }}
radioOptions={rowDetailsWidthOptions}
radioValue={rowDetailsWidth}
onChange={({ checkedItemValue }) => setRowDetailsWidth(checkedItemValue)}
orientation="horizontal"
/>
<p>
Resize grid columns to see the rowDetailsWidth in action
</p>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={expandedRows}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
rowDetailsWidth={rowDetailsWidth}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />;
Object|Boolean
default: undefined
<ReactDataGrid />
has row expand enabled, this column is displayed.false
will hide this column.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', defaultWidth: 180, header: 'Age',
render: ({ value, toggleRowExpand }) => <div>
{value} - <Button onClick={() => toggleRowExpand()}>Toggle row</Button>
</div>
},
{ name: 'email', header: 'Email', defaultFlex: 1 }
]
const App = () => {
const [rowExpandColumn, setRowExpandColumn] = useState(true);
const [customRowExpandHeader, setCustomRowExpandHeader] = useState(false);
let rowExpandCol;
if (!rowExpandCol && customRowExpandHeader) {
rowExpandCol = { header: 'Expand/collapse', defaultWidth: 125 }
}
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={rowExpandColumn}
onChange={setRowExpandColumn}
>
Show row expand column
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={!rowExpandColumn}
checked={customRowExpandHeader}
onChange={setCustomRowExpandHeader}
>
Custom row expand header icon
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
renderRowDetails={renderRowDetails}
rowExpandColumn={rowExpandCol}
style={gridStyle}
rowExpandHeight={400}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number|Fn({ data })
default: 80
<ReactDataGrid />
.renderRowDetails
in order to render the row details on expand.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import RadioButtonGroup from '@inovua/reactdatagrid-community/packages/RadioButtonGroup'
import people from './people'
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 rowExpandHeights = [
{ label: 'small', value: 250 },
{ label: 'normal', value: 350 },
{ label: 'large', value: 450 }
]
const defaultExpandedRows = { 1: true }
const columns = [
{ name: 'id', type: 'number', header: 'Id', defaultVisible: false },
{ name: 'name', defaultWidth: 150, minWidth: 80, header: 'Name' },
{ name: 'country', defaultWidth: 150, minWidth: 80, header: 'Country' },
{ name: 'city', defaultWidth: 150, minWidth: 80, header: 'City' },
{ name: 'age', minWidth: 80, type: 'number', header: 'Age' }
]
const App = () => {
const [rowExpandHeight, setRowExpandHeight] = useState(350);
return (
<div>
<p>
Select row expand height
</p>
<RadioButtonGroup
radioOptions={rowExpandHeights}
radioValue={rowExpandHeight}
onChange={({ checkedItemValue }) => setRowExpandHeight(checkedItemValue)}
orientation="horizontal"
style={{ marginBottom: 20 }}
/>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowExpandHeight={rowExpandHeight}
renderRowDetails={renderRowDetails}
defaultExpandedRows={defaultExpandedRows}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
rowExpandHeight
is a function, you can specify different heights for row details, as in example bellow.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'
const gridStyle = { minHeight: 700 }
const renderRowDetails = ({ data }) => {
return <div style={{ padding: 20}}>
<h3>Row details:</h3>
<table>
<tbody>
{Object.keys(data).map((name, i) => {
return <tr key={i}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
};
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'email', header: 'Email', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120 },
{ name: 'city', header: 'City', defaultWidth: 120 },
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 }
];
const App = () => {
const [expandedRows, setExpandedRows] = useState({ 2: true, 3: true });
const [collapsedRows, setCollapsedRows] = useState(null);
const onExpandedRowsChange = useCallback(({ expandedRows, collapsedRows }) => {
setExpandedRows(expandedRows);
setCollapsedRows(collapsedRows);
}, [])
const rowExpandHeight = ({ data }) => {
if (data.id % 3 === 0) {
return 400;
}
return 200;
}
return (
<div>
<h3>Grid showing row details with variable heights</h3>
<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={rowExpandHeight}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 40
<ReactDataGrid />
rows.rowHeights
rowHeight
- defaults to 40
). Column virtualization is performed when the number of columns is greater or equal to virtualizeColumnsThreshold
(defaults to 15
) or when virtualizeColumns=true
.rowHeight
value will improve the <ReactDataGrid />
rendering performance - since less rows fit into the visible <ReactDataGrid />
viewport and thus less rows are actually being rendered.rowHeight=null
. Read more about this topic at Flexible or natural row height. For small datasets you may also use the virtualized=false
prop.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import RadioButtonGroup from '@inovua/reactdatagrid-community/packages/RadioButtonGroup'
import people from './people'
const gridStyle = { minHeight: 550 }
const rowHeights = [
{ label: 'small', value: 25 },
{ label: 'normal', value: 40 },
{ label: 'large', value: 60 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ 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 = () => {
const [rowHeight, setRowHeight] = useState(40);
return (
<div>
<div style={{ display: 'inline-flex', marginBottom: 20 }}>
<div style={{ marginRight: 16 }}>
Select row height
</div>
<RadioButtonGroup
radioOptions={rowHeights}
radioValue={rowHeight}
onChange={({ checkedItemValue }) => setRowHeight(checkedItemValue)}
orientation="horizontal"
/>
</div>
<ReactDataGrid
key={rowHeight}
idProperty="id"
style={gridStyle}
rowHeight={rowHeight}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
{[key: string]: number}
default: undefined
rowHeights
object represent the ids of the rows for which to use custom heights. The values are the heights those rows should have.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import ComboBox from '@inovua/reactdatagrid-community/packages/ComboBox'
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: 3, name: 'FinancePersonal.xls' },
]
},
{ id: 2, name: 'MacRestore.gzip' },
{ id: 3, name: 'VSCode.dmg' },
{ id: 4, name: 'SublimeText.dmg' },
]
}
]
const columns = [
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'size', defaultWidth: 120, header: 'Size' }
]
const defaultExpandedNodes = { 1: true }
const rowHeights = {
// the root nodes should have a different height
'1': 100,
'2': 100,
'3': 100,
}
const App = () => {
const [treeColumn, setTreeColumn] = useState('name');
return (
<div>
<ReactDataGrid
defaultExpandedNodes={defaultExpandedNodes}
rowHeights={rowHeights}
stickyTreeNodes
treeColumn={"name"}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Bool|Object
default: undefined
true
for the column to show with all defaults, or 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.rowIndexColumn.renderIndex
.maxRowIndex
is taken into account when using the row index column, so rows cannot be sized bigger than that.rowHeight
.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', defaultWidth: 60, header: 'Id' },
{ 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' }
]
const App = () => {
return (
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={40}
maxRowHeight={100}
rowIndexColumn
columns={columns}
dataSource={people}
/>
);
}
export default () => <App />
Fn(index: number): ReactNode
default: undefined
rowIndexColumn
.rowIndexColumn.renderIndex(index)
is to render index+1
.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', defaultWidth: 60, header: 'Id' },
{ 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' }
]
const App = () => {
return (
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={40}
maxRowHeight={100}
rowIndexColumn={{
header: '#',
renderIndex: (index) => <b>{index + 10}</b>
}}
columns={columns}
dataSource={people}
/>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
rows. For conditional row styling, see rowStyle
.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 rowProps = {
style: { color: '#ef9a9a' }
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number' },
{ name: 'firstName', header: 'First Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowProps={rowProps}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Boolean
default: false
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: 250 }
const columns = [
{ name: 'id', header: 'Id', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 }
]
const App = () => {
return (
<div>
<h3>Drag the proxy up or down to the edge of the grid</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowReorderColumn
columns={columns}
dataSource={[].concat(people)}
rowReorderAutoScroll
rowReorderScrollByAmount={10}
/>
</div>
)
}
export default () => <App />
Number
default: 40
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import ComboBox from '@inovua/reactdatagrid-community/packages/ComboBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 250 }
const columns = [
{ name: 'id', header: 'Id', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 }
]
const speedsDataSource = [
{ label: '5ms', id: 5 },
{ label: '15ms', id: 15 },
{ label: '25ms', id: 25 },
{ label: '50ms', id: 50 },
{ label: '100ms', id: 100 }
]
const App = () => {
const [speed, setSpeed] = useState(15)
return (
<div>
<h3>Drag the proxy up or down to the edge of the grid</h3>
<div style={{ marginBottom: 20 }}>
<ComboBox
style={{ width: 200 }}
collapseOnSelect
changeValueOnNavigation
dataSource={speedsDataSource}
value={speed}
onChange={setSpeed}
/>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowReorderColumn
columns={columns}
dataSource={[].concat(people)}
rowReorderAutoScroll
rowReorderAutoScrollSpeed={speed}
rowReorderScrollByAmount={10}
/>
</div>
)
}
export default () => <App />
Bool|Object
default: undefined
true
for the column to show with all defaults, or 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.rowReorderColumn.render
.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', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 }
]
const App = () => {
return (
<div>
<h3>Drag to reorder</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={40}
rowReorderColumn
columns={columns}
dataSource={[].concat(people)}
/>
</div>
)
}
export default () => <App />
Bool
default: false
<ReactDataGrid />
should use right-to-left direction.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: 350 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', defaultFlex: 1, header: 'First Name' },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', defaultFlex: 1, header: 'Country' },
{ name: 'age', defaultFlex: 1, type: 'number', header: 'Age' }
]
const App = () => {
const [rtl, setRtl] = useState(false)
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={rtl}
onChange={setRtl}
>
Enable RTL
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
rtl={rtl}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
<ReactDataGrid />
.scrollProps
object supports many properties, but here is a short list of the most important ones:autoHide
- whether to hide the scrollbars while not scrolling. Defaults to true
.alwaysShowTrack
- whether to show the scroll track all the time or only when the mouse is over it. Defaults to false
, so it will only be displayed on mouseover.scrollThumbWidth
- the width of the scrollthumb. Defaults to 7
.scrollThumbStyle
- a style object for the scroll thumb.scrollThumbRadius
- the radius of the scroll thumb. Defaults to the value of scrollThumbWidth
.nativeScroll=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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [autoHide, setAutoHide] = useState(false);
const [alwaysShowTrack, setAlwaysShowTrack] = useState(false);
const [redBackground, setRedBackground] = useState(false);
const [customSize, setCustomSize] = useState(false);
const [customRadius, setCustomRadius] = useState(false);
const [nativeScroll, setNativeScroll] = useState(false);
const scrollProps = Object.assign({}, ReactDataGrid.defaultProps.scrollProps, {
autoHide,
alwaysShowTrack
})
if (customSize) {
scrollProps.scrollThumbWidth = 15
scrollProps.scrollThumbOverWidth = 20
}
if (customRadius) {
scrollProps.scrollThumbRadius = 20
}
if (redBackground) {
scrollProps.scrollThumbStyle = {
background: '#ff7474'
}
}
return (
<div>
<h3>Customized scrollbars</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={nativeScroll}
onChange={setNativeScroll}
>
Use native scroll
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && autoHide}
onChange={setAutoHide}
>
Auto-hide scrollbars
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && alwaysShowTrack}
onChange={setAlwaysShowTrack}
>
Always show track
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && redBackground}
onChange={setRedBackground}
>
Red background for scroll thumbs
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customSize}
onChange={setCustomSize}
>
Custom scrollbar size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customRadius}
onChange={setCustomRadius}
>
Custom radius (20px)
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
scrollProps={scrollProps}
nativeScroll={nativeScroll}
columns={columns}
enableKeyboardNavigation={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
nativeScroll=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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [autoHide, setAutoHide] = useState(false);
const [alwaysShowTrack, setAlwaysShowTrack] = useState(false);
const [redBackground, setRedBackground] = useState(false);
const [customSize, setCustomSize] = useState(false);
const [customRadius, setCustomRadius] = useState(false);
const [nativeScroll, setNativeScroll] = useState(false);
const scrollProps = Object.assign({}, ReactDataGrid.defaultProps.scrollProps, {
autoHide,
alwaysShowTrack
})
if (customSize) {
scrollProps.scrollThumbWidth = 15
scrollProps.scrollThumbOverWidth = 20
}
if (customRadius) {
scrollProps.scrollThumbRadius = 20
}
if (redBackground) {
scrollProps.scrollThumbStyle = {
background: '#ff7474'
}
}
return (
<div>
<h3>Customized scrollbars</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={nativeScroll}
onChange={setNativeScroll}
>
Use native scroll
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && autoHide}
onChange={setAutoHide}
>
Auto-hide scrollbars
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && alwaysShowTrack}
onChange={setAlwaysShowTrack}
>
Always show track
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && redBackground}
onChange={setRedBackground}
>
Red background for scroll thumbs
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customSize}
onChange={setCustomSize}
>
Custom scrollbar size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customRadius}
onChange={setCustomRadius}
>
Custom radius (20px)
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
scrollProps={scrollProps}
nativeScroll={nativeScroll}
columns={columns}
enableKeyboardNavigation={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
<ReactDataGrid />
should hide when no scrolling is in progress. Defaults to true
.nativeScroll=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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [autoHide, setAutoHide] = useState(false);
const [alwaysShowTrack, setAlwaysShowTrack] = useState(false);
const [redBackground, setRedBackground] = useState(false);
const [customSize, setCustomSize] = useState(false);
const [customRadius, setCustomRadius] = useState(false);
const [nativeScroll, setNativeScroll] = useState(false);
const scrollProps = Object.assign({}, ReactDataGrid.defaultProps.scrollProps, {
autoHide,
alwaysShowTrack
})
if (customSize) {
scrollProps.scrollThumbWidth = 15
scrollProps.scrollThumbOverWidth = 20
}
if (customRadius) {
scrollProps.scrollThumbRadius = 20
}
if (redBackground) {
scrollProps.scrollThumbStyle = {
background: '#ff7474'
}
}
return (
<div>
<h3>Customized scrollbars</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={nativeScroll}
onChange={setNativeScroll}
>
Use native scroll
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && autoHide}
onChange={setAutoHide}
>
Auto-hide scrollbars
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && alwaysShowTrack}
onChange={setAlwaysShowTrack}
>
Always show track
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && redBackground}
onChange={setRedBackground}
>
Red background for scroll thumbs
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customSize}
onChange={setCustomSize}
>
Custom scrollbar size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customRadius}
onChange={setCustomRadius}
>
Custom radius (20px)
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
scrollProps={scrollProps}
nativeScroll={nativeScroll}
columns={columns}
enableKeyboardNavigation={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 7
scrollProps.scrollThumbWidth
.nativeScroll=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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [autoHide, setAutoHide] = useState(false);
const [alwaysShowTrack, setAlwaysShowTrack] = useState(false);
const [redBackground, setRedBackground] = useState(false);
const [customSize, setCustomSize] = useState(false);
const [customRadius, setCustomRadius] = useState(false);
const [nativeScroll, setNativeScroll] = useState(false);
const scrollProps = Object.assign({}, ReactDataGrid.defaultProps.scrollProps, {
autoHide,
alwaysShowTrack
})
if (customSize) {
scrollProps.scrollThumbWidth = 15
scrollProps.scrollThumbOverWidth = 20
}
if (customRadius) {
scrollProps.scrollThumbRadius = 20
}
if (redBackground) {
scrollProps.scrollThumbStyle = {
background: '#ff7474'
}
}
return (
<div>
<h3>Customized scrollbars</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={nativeScroll}
onChange={setNativeScroll}
>
Use native scroll
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && autoHide}
onChange={setAutoHide}
>
Auto-hide scrollbars
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && alwaysShowTrack}
onChange={setAlwaysShowTrack}
>
Always show track
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && redBackground}
onChange={setRedBackground}
>
Red background for scroll thumbs
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customSize}
onChange={setCustomSize}
>
Custom scrollbar size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customRadius}
onChange={setCustomRadius}
>
Custom radius (20px)
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
scrollProps={scrollProps}
nativeScroll={nativeScroll}
columns={columns}
enableKeyboardNavigation={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
nativeScroll=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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [autoHide, setAutoHide] = useState(false);
const [alwaysShowTrack, setAlwaysShowTrack] = useState(false);
const [redBackground, setRedBackground] = useState(false);
const [customSize, setCustomSize] = useState(false);
const [customRadius, setCustomRadius] = useState(false);
const [nativeScroll, setNativeScroll] = useState(false);
const scrollProps = Object.assign({}, ReactDataGrid.defaultProps.scrollProps, {
autoHide,
alwaysShowTrack
})
if (customSize) {
scrollProps.scrollThumbWidth = 15
scrollProps.scrollThumbOverWidth = 20
}
if (customRadius) {
scrollProps.scrollThumbRadius = 20
}
if (redBackground) {
scrollProps.scrollThumbStyle = {
background: '#ff7474'
}
}
return (
<div>
<h3>Customized scrollbars</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={nativeScroll}
onChange={setNativeScroll}
>
Use native scroll
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && autoHide}
onChange={setAutoHide}
>
Auto-hide scrollbars
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && alwaysShowTrack}
onChange={setAlwaysShowTrack}
>
Always show track
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && redBackground}
onChange={setRedBackground}
>
Red background for scroll thumbs
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customSize}
onChange={setCustomSize}
>
Custom scrollbar size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customRadius}
onChange={setCustomRadius}
>
Custom radius (20px)
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
scrollProps={scrollProps}
nativeScroll={nativeScroll}
columns={columns}
enableKeyboardNavigation={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number
default: 7
nativeScroll=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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1 },
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [autoHide, setAutoHide] = useState(false);
const [alwaysShowTrack, setAlwaysShowTrack] = useState(false);
const [redBackground, setRedBackground] = useState(false);
const [customSize, setCustomSize] = useState(false);
const [customRadius, setCustomRadius] = useState(false);
const [nativeScroll, setNativeScroll] = useState(false);
const scrollProps = Object.assign({}, ReactDataGrid.defaultProps.scrollProps, {
autoHide,
alwaysShowTrack
})
if (customSize) {
scrollProps.scrollThumbWidth = 15
scrollProps.scrollThumbOverWidth = 20
}
if (customRadius) {
scrollProps.scrollThumbRadius = 20
}
if (redBackground) {
scrollProps.scrollThumbStyle = {
background: '#ff7474'
}
}
return (
<div>
<h3>Customized scrollbars</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={nativeScroll}
onChange={setNativeScroll}
>
Use native scroll
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && autoHide}
onChange={setAutoHide}
>
Auto-hide scrollbars
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && alwaysShowTrack}
onChange={setAlwaysShowTrack}
>
Always show track
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && redBackground}
onChange={setRedBackground}
>
Red background for scroll thumbs
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customSize}
onChange={setCustomSize}
>
Custom scrollbar size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={nativeScroll}
checked={!nativeScroll && customRadius}
onChange={setCustomRadius}
>
Custom radius (20px)
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
scrollProps={scrollProps}
nativeScroll={nativeScroll}
columns={columns}
enableKeyboardNavigation={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Number | String
default: undefined
scrollThreshold
is specified, the next page will be loaded when the user reaches the scroll max height minus scrollThreshold
of the page - if the threshold is specified as a string, in pixels (for example, scrollThreshold="150px"
). If scrollThreshold
is a number or it is a percentage (for example, scrollThreshold="60%"
or scrollThreshold=0.6
), the next page will be loaded when the user reaches the specified percentage of the scroll max height.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'
import flags from './flags'
const gridStyle = { minHeight: 250 }
const defaultFilterValue = [
{
name: 'firstName', value: '', operator: 'contains', type: 'string'
}
]
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,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [scrollTopOnFilter, setScrollTopOnFilter] = useState(true)
return (
<div>
<div>
<CheckBox
checked={scrollTopOnFilter}
onChange={setScrollTopOnFilter}
>
Scroll top on filter
</CheckBox>
<p>Try filtering by "i" on name column</p>
</div>
<ReactDataGrid
idProperty="id"
defaultFilterValue={defaultFilterValue}
scrollTopOnFilter={scrollTopOnFilter}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
false
might not work.Bool|'always'
default: true
scrollTopOnSort
works with remote data and the type it is a boolean, which if it is true
, the scrollTop
is set to 0
when sorting. But if you want the same effect with local data, specify it to 'always'
.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: 350 }
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,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [scrollTopOnSort, setScrollTopOnSort] = useState(true)
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={scrollTopOnSort}
onChange={setScrollTopOnSort}
>
scrollTopOnSort
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
scrollTopOnSort={scrollTopOnSort}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String|Number|Object|Boolean
default: undefined
<ReactDataGrid />
. This is a controlled prop. For the uncontrolled version, see defaultSelected
.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.dataSource
is configured, you might need to use unselected
(or the uncontrolled defaultUnselected
) together with selected
.selected=true
will render all rows as selected (even rows on other pages). At this point, you can use unselected
to specify exceptions (rows that will not be rendered as unselected).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 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({ 1: true, 2: true });
const onSelectionChange = useCallback(({ selected: selectedMap }) => {
setSelected(selectedMap)
}, [])
return (
<div>
<p>
Selected rows: {selected == null ? 'none' : JSON.stringify(Object.keys(selected))}.
</p>
<ReactDataGrid
idProperty="id"
multiSelect
selected={selected}
onSelectionChange={onSelectionChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
cellSelection
is enabled.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 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 [selectOnDrag, setSelectOnDrag] = useState(false)
const [cellSelection, setCellSelection] = useState(defaultCellSelection)
return (
<div>
<p>When selectOnDrag is enabled you can hold the mouse down on a cell and drag to another cell to create multiple cell selection.</p>
<p>selectOnDrag: {selectOnDrag}</p>
<div>
<CheckBox checked={selectOnDrag} onChange={setSelectOnDrag}>
Enable select on drag
</CheckBox>
</div>
<p>
Selected cells: {Object.keys(cellSelection).length == 0 ? 'none' : JSON.stringify(cellSelection)}.
</p>
<ReactDataGrid
idProperty="id"
selectOnDrag={selectOnDrag}
defaultCellSelection={defaultCellSelection}
onCellSelectionChange={setCellSelection}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
true
, when columns are resized, sibling/adjacent columns will share their resize space. If false
, any resize that increases column width will push the next columns to the right.<ReactDataGrid />
has flexible columns, and shareSpaceOnResize=false
, when a column is resized (eg: made smaller), the flexible columns keep their current size and don't grow to fill the newly available space. However, they do keep their proportional size to all other flexible columns. Also, when the <ReactDataGrid />
has more available space (i.e., is resized), they do resize to keep the same empty space in the <ReactDataGrid />
.<ReactDataGrid />
is configured with shareSpaceOnResize=true
, and a column is resized, flexible columns are resized to fill all available space to ensure that columns always fill the grid viewport horizontally.<ReactDataGrid />
and not as a mandatory behaviour - since there are cases when sharing space is not desirable/possible (eg - a resizable column adjacent to a non-resizable column).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 [shareSpaceOnResize, setShareSpaceOnResize] = useState(false);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={shareSpaceOnResize} onChange={setShareSpaceOnResize}>
Share space on resize
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
shareSpaceOnResize={shareSpaceOnResize}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
true
, row details will be rendered in the DOM even for rows which are not expanded - but will be rendered with display: none
.rowDetailsStyle
.Bool
default: true
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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 60, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value })=> flags[value]? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
];
const App = () => {
const [enableSelection, setEnableSelection] = useState(true);
const [showActiveRowIndicator, setShowActiveRowIndicator] = useState(true);
return (
<div>
<h3>DataGrid with active row indicator</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableSelection}
onChange={setEnableSelection}>
Enable selection
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showActiveRowIndicator}
onChange={setShowActiveRowIndicator}>
Enable active row indicator
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
enableSelection={enableSelection}
showActiveRowIndicator={showActiveRowIndicator}
/>
</div>
);
}
export default () => <App />
Bool
default: true
columns.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 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 [showColumnMenuFilterOptions, setShowColumnMenuFilterOptions] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuFilterOptions}
onChange={setShowColumnMenuFilterOptions}
>
Show menu item for showing/hiding filtering row in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultFilterValue={filterValue}
showColumnMenuFilterOptions={showColumnMenuFilterOptions}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
columns.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 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 [showColumnMenuGroupOptions, setShowColumnMenuGroupOptions] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuGroupOptions}
onChange={setShowColumnMenuGroupOptions}
>
Show column group/ungroup option in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showColumnMenuGroupOptions={showColumnMenuGroupOptions}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
columns.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 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 [showColumnMenuLockOptions, setShowColumnMenuLockOptions] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuLockOptions}
onChange={(showColumnMenuLockOptions) => setShowColumnMenuLockOptions(showColumnMenuLockOptions)}
>
Show column lock/unlock option in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showColumnMenuLockOptions={showColumnMenuLockOptions}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
columns.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 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 [showColumnMenuSortOptions, setShowColumnMenuSortOptions] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuSortOptions}
onChange={setShowColumnMenuSortOptions}
>
Show column sort/unsort option in column menu
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showColumnMenuSortOptions={showColumnMenuSortOptions}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
true
.columns.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 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 [showColumnMenuTool, setShowColumnMenuTool] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuTool}
onChange={setShowColumnMenuTool}
>
Show column header tool
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showColumnMenuTool={showColumnMenuTool}
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.columns.showColumnMenuToolOnHover
, 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 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 [showColumnMenuToolOnHover, setShowColumnMenuToolOnHover] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showColumnMenuToolOnHover}
onChange={setShowColumnMenuToolOnHover}
>
Show column header tool on hover
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showColumnMenuToolOnHover={showColumnMenuToolOnHover}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Boolean|String
default: undefined
groupSummaryReducer
.true
, false
,"start"
or "end"
. true
is the same as specifying "end"
groupColumn
is used, the group summary row is not displayed.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 [showGroupColumn, setShowGroupColumn] = useState(false);
const [showGroupSummaryRow, setShowGroupSummaryRow] = useState(true);
const [groupSummaryRowPosition, setGroupSummaryRowPosition] = useState('end');
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={showGroupColumn}
onChange={showGroupColumn => {
if (showGroupColumn) {
setShowGroupSummaryRow(false);
setGroupSummaryRowPosition('end');
}
setShowGroupColumn(showGroupColumn);
}}
>
Use dedicated group column
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={!!showGroupSummaryRow}
onChange={showGroupSummaryRow => {
if (showGroupSummaryRow) {
setShowGroupColumn(false);
}
setShowGroupSummaryRow(showGroupSummaryRow);
}}
>
Show group summary row
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
disabled={!showGroupSummaryRow}
checked={groupSummaryRowPosition === 'start' && showGroupSummaryRow}
onChange={groupSummaryRowPosition => {
const newState = groupSummaryRowPosition ? 'start' : 'end';
setGroupSummaryRowPosition(newState);
}}
>
Group summary row position - START
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
groupColumn={showGroupColumn}
showGroupSummaryRow={showGroupSummaryRow ? groupSummaryRowPosition : false}
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 />;
Bool
default: true
showHeader=false
to hide <ReactDataGrid />
headers.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: 'city', defaultFlex: 1, header: 'City' },
{ name: 'age', type: 'number', defaultFlex: 1, header: 'Age' }
]
const App = () => {
const [showHeader, setShowHeader] = useState(true);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={showHeader}
onChange={setShowHeader}
>
Show header
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
columns={columns}
dataSource={people}
showHeader={showHeader}
/>
</div>
);
}
export default () => <App />
bool
default: true
showPivotSummaryColumns=true
, the pivoted grid will show pivot summary columns for each pivot
item that specifies a pivot.summaryReducer
.pivot
array also needs to contain a name
, and can also contain a summaryColumn
- which can be a a column configuration object, or a function that returns a column configuration.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',
header: 'Q1',
name: 'amount',
pivotName: 'q1',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month <= 3),
render: ({ value }) => currency(value)
},
{
id: 'q2',
header: 'Q2',
name: 'amount',
pivotName: 'q2',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 3 && month <= 6),
render: ({ value }) => currency(value)
},
{
id: 'q3',
header: 'Q3',
pivotName: 'q3',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 6 && month <= 9),
render: ({ value }) => currency(value)
},
{
id: 'q4',
header: 'Q4',
pivotName: 'q4',
name: 'amount',
type: 'number',
groupSummaryReducer: quarterSumReducer(month => month > 9 && month <= 12),
render: ({ value }) => currency(value)
},
];
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: {
style: { color: '#7986cb' }
}
}
]
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</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={180}
pivot={enablePivot ? pivot : null}
groupBy={groupBy}
showPivotSummaryColumns={showPivotSummaryColumns}
pivotGrandSummaryColumn={{
header: 'TOTAL',
style: { color: '#ef9a9a' },
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;
if (groupColumn) {
return <div style={footerCellStyle}>
<b>Total sales</b>
</div>
}
let result;
if (pivotSummaryPath && pivotSummaryPath.length) {
const pivotInfo = [...pivotSummaryPath].pop();
const pivotValue = pivotInfo.value;
result = summary[pivotValue];
} else if (pivotColumnPath) {
result = summary[(pivotColumnPath || []).join('-')] || 0;
} else if (pivotGrandSummaryColumn) {
result = summary.total;
}
return (
<div style={footerCellStyle}>
<b>{currency(result || 0)}</b>
</div>
);
},
},
]}
/>
</div>
);
}
export default () => <App />;
Number
default: undefined
<ReactDataGrid />
, when pagination
is enabled.defaultSkip
.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 Button from '@inovua/reactdatagrid-community/packages/Button'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 400, 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 [skip, setSkip] = useState(10);
const [loading, setLoading] = useState(false);
const dataSource = useCallback(loadData, [])
const updateSkip = useCallback((amount) => {
return () => {
const newSkip = skip + amount
setSkip(Math.max(0, Math.min(newSkip, 100)))
}
}, [skip])
const disabled = loading || Array.isArray(dataSource)
return (
<div>
<p>Current skip: {skip}.</p>
<div style={{ marginBottom: 20 }}>
<Button style={{ marginRight: 8 }} onClick={updateSkip(10)} disabled={disabled}>skip += 10</Button>
<Button onClick={updateSkip(-10)} disabled={disabled || skip == 0}>skip -= 10</Button>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
pagination
defaultLimit={10}
skip={skip}
onSkipChange={setSkip}
loading={loading}
onLoadingChange={setLoading}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool
default: false
skipHeaderOnAutoSize
to true
.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';
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);
const [skipHeaderOnAutoSize, setSkipHeaderOnAutoSize] = useState(false);
const setColumnsSizesAuto = useCallback(
() => {
if (gridRef.current.setColumnsSizesAuto) {
gridRef.current.setColumnsSizesAuto();
}
},
[gridRef]
);
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 }}>
<CheckBox checked={skipHeaderOnAutoSize} onChange={setSkipHeaderOnAutoSize}>
Skip header on auto size
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => setColumnsSizesAuto()}>
Set column sizes auto
</Button>
</div>
<ReactDataGrid
idProperty="id"
handle={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
enableColumnAutosize={enableColumnAutosize}
skipHeaderOnAutoSize={skipHeaderOnAutoSize}
/>
</div>
);
};
export default () => <App />;
Bool
default: true
<ReactDataGrid />
.sortable
prop specified on the <ReactDataGrid />
. If however they specify a custom column.sortable
value, it will be honoured, even if the <ReactDataGrid />
specifies a different value for sortable
prop .allowUnsort
, see Single and multiple sorting.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: 'First Name', defaultFlex: 1 },
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 100 },
{
id: 'desc',
header: 'Description, not sortable',
sortable: false,
minWidth: 100,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country,
flex: 2
}
]
const App = () => {
const [sortable, setSortable] = useState(true)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox checked={sortable} onChange={setSortable}>
Sortable grid
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
sortable={sortable}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
column.type
to ensure proper sorting. For now, supported values are "string"
and "number"
. Or you can specify a custom column.sort
function (it should always sort records in ascending order) to accomplish custom local sorting.Object|Object[]
default: undefined
<ReactDataGrid />
. This is a controlled prop. For the uncontrolled version, see defaultSortInfo
. The sortInfo
object should contain at least two properties: name
(which should be the column identifier) and dir
(valid values are 1
or -1
).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.sortInfo
prop when onSortInfoChange(sortInfo)
is called.columns.renderSortTool
.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: 300 }
const getComparer = (sortInfo) => {
const key = sortInfo.name;
const direction = sortInfo.dir;
return (a, b) => {
if (a === b) return 0;
return b[key] > a[key] ? -direction : direction;
}
}
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: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 }
]
const defaultSortInfo = { name: 'age', type: 'number', dir: 1 }
const initialData = [].concat(people).sort(getComparer(defaultSortInfo))
const App = () => {
const [sortInfo, setSortInfo] = useState(defaultSortInfo)
const [dataSource, setDataSource] = useState(initialData)
const onSortInfoChange = useCallback(sortInfo => {
const newData = !sortInfo?[].concat(people):[].concat(people).sort(getComparer(sortInfo))
setSortInfo(sortInfo)
setDataSource(newData)
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
Current sort info: {sortInfo ? <code>{JSON.stringify(sortInfo, null, 2)}</code>: 'none'}.
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
sortInfo={sortInfo}
columns={columns}
dataSource={dataSource}
onSortInfoChange={onSortInfoChange}
/>
</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'
import flags from './flags'
const gridStyle = { minHeight: 400 }
const columns = [
{ name: 'id', type: 'number', defaultWidth: 80, groupBy: false, header: 'Id', defaultVisible: false },
{ name: 'name', defaultFlex: 1, header: 'Name' },
{ name: 'country', defaultWidth: 150, header: 'Country',
render: ({ value }) => flags[value] ? flags[value]: value
},
{ name: 'city', defaultWidth: 150, header: 'City' },
{ name: 'age', defaultWidth: 100, type: 'number', header: 'Age' },
{ name: 'email', defaultWidth: 150, defaultFlex: 1, header: 'Email' },
]
const App = () => {
const [defaultGroupBy, setDefaultGroupBy] = useState(['country','city']);
const [stickyGroupRows, setStickyGroupRows] = useState(false);
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={stickyGroupRows}
onChange={setStickyGroupRows}
>
Use sticky group rows
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
stickyGroupRows={stickyGroupRows}
defaultGroupBy={defaultGroupBy}
columns={columns}
dataSource={people}
/>
</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'
const columns = [
{ name: 'name', header: 'Name', minWidth: 50, defaultFlex: 2 },
{ name: 'age', header: 'Age', maxWidth: 1000, defaultFlex: 1 }
]
const gridStyle = { minHeight: 2500 }
const dataSource = [
{ id: 1, name: 'John McQueen', age: 35 },
{ id: 2, name: 'Mary Stones', age: 25 },
{ id: 3, name: 'Robert Fil', age: 27 },
{ id: 4, name: 'Roger Robson', age: 81 },
{ id: 5, name: 'Billary Konwik', age: 18 },
{ id: 6, name: 'Bob Martin', age: 18 },
{ id: 7, name: 'Matthew Richardson', age: 54 },
{ id: 8, name: 'Ritchie Peterson', age: 54 },
{ id: 9, name: 'Bryan Martin', age: 40 },
{ id: 10, name: 'Mark Martin', age: 44 },
{ id: 11, name: 'Michelle Sebastian', age: 24 },
{ id: 12, name: 'Michelle Sullivan', age: 61 },
{ id: 13, name: 'Jordan Bike', age: 16 },
{ id: 14, name: 'Nelson Ford', age: 34 },
{ id: 15, name: 'Tim Cheap', age: 3 },
{ id: 16, name: 'Robert Carlson', age: 31 },
{ id: 17, name: 'Johny Perterson', age: 40 }
];
const App = () => {
const [stickyHeader, setStickyHeader] = useState(true);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={stickyHeader} onChange={setStickyHeader}>Sticky header</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
columns={columns}
dataSource={dataSource}
style={gridStyle}
stickyHeader={stickyHeader}
/>
</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'
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', header: 'Size', defaultWidth: 160 }
];
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 nestingSizes = [
{ label: '10px', id: 10},
{ label: '15px', id: 15},
{ label: '22px', id: 22},
{ label: '25px', id: 25},
{ label: '50px', id: 50}
]
const defaultExpandedNodes = { 1: true }
const App = () => {
const [stickyTreeNodes, setStickyTreeNodes] = useState(false);
return (
<div>
<h3>TreeGrid with sticky tree nodes</h3>
<div style={{marginBottom: 20}}>
<CheckBox
checked={stickyTreeNodes}
onChange={setStickyTreeNodes}
>
Use sticky tree nodes (expand nodes to have vertical scrollbar)
</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
loadNode={loadNode}
stickyTreeNodes={stickyTreeNodes}
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
{ initialValue: any, reducer: (acc, current) => any, complete: (value, arr) => any}
default: undefined
summaryReducer
- which are simple objects with the following props:initialValue
- the initial value to be used for the summary computation - generally a number/string/etcreducer(accumulator, currentItem)
- the reducer function - basically computes the summary from the accumulated value (at first call, this will equal the initialValue
) and the current 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 againstmin
, max
and average
values for the population column.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>
<div>Min: {summary.min}</div>
<div>Max: {summary.max}</div>
<div>Average: {summary.avg}</div>
</div>
}
}
]
const summaryReducer = {
initialValue: {
min: Infinity,
max: 0,
avg: 0
},
reducer: (accumulator, item) => {
if (item.population) {
accumulator.min = Math.min(accumulator.min, item.population)
accumulator.max = Math.max(accumulator.max, item.population)
accumulator.avg += item.population
}
return accumulator
},
complete: (accumulator, arr) => {
accumulator.avg = Math.round(accumulator.avg / arr.length)
return accumulator
}
}
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>Multiple footer summaries for the population 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
multiSelect=false
) cell selection. If true
(which is the default), clicking the selected cell will deselect it. If false
, clicking the selected cell would not unselect it - to unselect the user has to crtl+click
the cell.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 defaultCellSelection = {"2,name": 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 [toggleCellSelectOnClick, setToggleCellSelectOnClick] = useState(true);
return (
<div>
<div>
<CheckBox
checked={toggleCellSelectOnClick}
onChange={setToggleCellSelectOnClick}
>
Toggle cell select on click
</CheckBox>
</div>
<p>
When clicking a cell it becomes both the active cell & the selected cell. Make sure you notice the difference in styling when both are applied.
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
multiSelect={false}
toggleCellSelectOnClick={toggleCellSelectOnClick}
defaultCellSelection={defaultCellSelection}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
true
, clicking the selected row will deselect it. If false
(which is the default), clicking the selected row would not unselect it - to unselect the user has to crtl+click
the row.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: '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(1);
const [toggleRowSelectOnClick, setToggleRowSelectOnClick] = useState(true);
const onSelectionChange = useCallback(({ selected: selectedMap }) => {
setSelected(selectedMap)
}, [])
return (
<div>
<div>
<CheckBox
checked={toggleRowSelectOnClick}
onChange={setToggleRowSelectOnClick}
>
Toggle row select on click
</CheckBox>
</div>
<p>Selected row id: {selected}</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
toggleRowSelectOnClick={toggleRowSelectOnClick}
defaultSelected={1}
onSelectionChange={onSelectionChange}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
dataSource
can be configured to have child nodes.<ReactDataGrid />
is not compatible with grouping rows.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import ComboBox from '@inovua/reactdatagrid-community/packages/ComboBox'
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 = { 1: true }
const comboDataSource = columns.map(c=> {
return {
id: c.name,
label: c.name
}
})
const App = () => {
const [treeColumn, setTreeColumn] = useState('name');
return (
<div>
<div style={{ marginBottom: 20 }}>
<p>Please select the treeColumn</p>
<ComboBox
style={{ width: 150}}
collapseOnSelect
clearIcon={false}
searchable={false}
changeValueOnNavigation
dataSource={comboDataSource}
value={treeColumn}
onChange={setTreeColumn}
/>
</div>
<ReactDataGrid
defaultExpandedNodes={defaultExpandedNodes}
treeColumn={treeColumn}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
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: 160 }
];
const expandedNodes = { 1: true, 3: true, '3/1': true };
const App = () => {
const [
treeGridChildrenSelectionEnabled,
setTreeGridChildrenSelectionEnabled,
] = useState(true);
const [
treeGridChildrenDeselectionEnabled,
setTreeGridChildrenDeselectionEnabled,
] = useState(true);
return (
<div>
<h3>TreeGrid with children deselection enabled</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={treeGridChildrenSelectionEnabled}
onChange={setTreeGridChildrenSelectionEnabled}
>
Children selection enabled
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={treeGridChildrenDeselectionEnabled}
onChange={setTreeGridChildrenDeselectionEnabled}
>
Children deselection enabled
</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={expandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
checkboxColumn
treeGridChildrenSelectionEnabled={treeGridChildrenSelectionEnabled}
treeGridChildrenDeselectionEnabled={treeGridChildrenDeselectionEnabled}
/>
</div>
);
}
export default () => <App />
Bool
default: undefined
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
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: 160 }
];
const expandedNodes = { 1: true, 3: true, '3/1': true };
const App = () => {
const [
treeGridChildrenSelectionEnabled,
setTreeGridChildrenSelectionEnabled,
] = useState(true);
return (
<div>
<h3>TreeGrid with children selection enabled</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={treeGridChildrenSelectionEnabled}
onChange={setTreeGridChildrenSelectionEnabled}
>
treeGridChildrenSelectionEnabled
</CheckBox>
</div>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={expandedNodes}
style={gridStyle}
columns={columns}
dataSource={treeData}
checkboxColumn
treeGridChildrenSelectionEnabled={treeGridChildrenSelectionEnabled}
/>
</div>
);
}
export default () => <App />
Number
default: 22
import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import ComboBox from '@inovua/reactdatagrid-community/packages/ComboBox'
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 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 nestingSizes = [
{ label: '10px', id: 10},
{ label: '15px', id: 15},
{ label: '22px', id: 22},
{ label: '25px', id: 25},
{ label: '50px', id: 50}
]
const defaultExpandedNodes = { 1: true }
const App = () => {
const [treeNestingSize, setTreeNestingSize] = useState(22)
return (
<div>
<h3>TreeGrid with treeNestingSize configuration</h3>
<div style={{ marginBottom: 20 }}>
<p>Please select the tree nesting size
</p>
<ComboBox
style={{ width: 150}}
collapseOnSelect
clearIcon={false}
searchable={false}
changeValueOnNavigation
dataSource={nestingSizes}
value={treeNestingSize}
onChange={setTreeNestingSize}
/>
</div>
<ReactDataGrid
treeColumn="name"
loadNode={loadNode}
defaultExpandedNodes={defaultExpandedNodes}
treeNestingSize={treeNestingSize}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
isRowExpandable
.unexpandableRows
prop is specified, isRowExpandable
is no longer called.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 unexpandableRows = { 1: true, 2: true }
const App = () => {
return (
<div>
<p>Rows with the ids 1 and 3 are not expandable.</p>
<ReactDataGrid
idProperty="id"
unexpandableRows={unexpandableRows}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
dataSource
and selected
.<ReactDataGrid />
rows should be rendered as unselected. When selected=true
, all items but those specified by this prop should be selected.unselected
object should be keyed using item ids, as specified by their idProperty
.defaultSelected
. When the user selects/deselects new rows, onSelectionChange({ selected, unselected })
is called, and you need to make sure you update the value of the unselected
prop to reflect the selection changes.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 [unselected, setUnselected] = useState({ 1: true, 3: true });
const [selected, setSelected] = useState(true);
const [checkboxOnlyRowSelect, setCheckboxOnlyRowSelect] = useState(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 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
columns={columns}
checkboxOnlyRowSelect={checkboxOnlyRowSelect}
pagination
selected={selected}
unselected={unselected}
onSelectionChange={onSelectionChange}
sortable={false}
dataSource={dataSource}
/>
</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';
import flags from './flags';
const gridStyle = { minHeight: 550 };
const columns = [
{
name: 'id',
header: 'Id',
defaultVisible: false,
defaultWidth: 60,
type: 'number',
},
{ name: 'name', header: 'Name', defaultFlex: 1 },
{
name: 'country',
header: 'Country',
defaultFlex: 1,
render: ({ value }) => (flags[value] ? flags[value] : value),
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' },
];
const App = () => {
const [
updateMenuPositionOnColumnsChange,
setUpdateMenuPositionOnColumnsChange,
] = useState(true);
return (
<div>
<h3>Grid with update menu position when columns change</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
theme="default-dark"
checked={updateMenuPositionOnColumnsChange}
onChange={setUpdateMenuPositionOnColumnsChange}
>
updateMenuPositionOnColumnsChange
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
updateMenuPositionOnColumnsChange={updateMenuPositionOnColumnsChange}
/>
</div>
);
};
export default () => <App />;
Bool
default: "true"
true
, will make lockedRows
have the same height as normal grid rows.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 contactsDataSource from './data'
const gridStyle = { minHeight: 550, marginTop: 10 }
const columns = [
{ name: 'id', header: 'ID', defaultVisible: false, type: 'number', defaultWidth: 100 },
{ name: 'firstName', header: 'First Name', defaultWidth: 200 },
{ name: 'lastName', header: 'Last Name', defaultWidth: 200 },
{ name: 'email', header: 'Email', defaultFlex: 1 }
];
const App = () => {
const [first, setFirst] = useState();
const [second, setSecond] = useState();
const [last, setLast] = useState();
const [firstLocked, setFirstLocked] = useState(false);
const [secondLocked, setSecondLocked] = useState(false);
const [lastLocked, setLastLocked] = useState(false);
const [showZebraRows, setShowZebraRows] = useState(false);
const [useRowHeightForLockedRows, setUseRowHeightForLockedRows] = useState(true);
const [dataSource, setDataSource] = useState(contactsDataSource);
const update = useCallback((newState, fn) => {
let data = [].concat(contactsDataSource)
// we don't want to show locked rows in the dataSource
if (newState.lastLocked) {
// delete last 3
setLast(data.splice(-3,3))
}
if (newState.secondLocked) {
setSecond(data.splice(1, 1)[0])
}
if (newState.firstLocked) {
setFirst(data.splice(0, 1)[0])
}
const newStateValue = Object.values(newState)[0];
fn(newStateValue);
}, [firstLocked, secondLocked, lastLocked])
const lockedRows = []
if (firstLocked) {
lockedRows.push({
position: 'start',
render: ({column}, computedProps) => {
return first ? first[column.name] : null
}
})
}
if (secondLocked) {
lockedRows.push({
position: 'start',
render: ({column}, computedProps) => {
return second ? second[column.name] : null
}
})
}
if (lastLocked) {
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = last? last[0] : null
return item ? item[column.name] : null
}
})
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = last? last[1] : null
return item ? item[column.name] : null
}
})
lockedRows.push({
position: 'end',
render: ({column}, computedProps) => {
const item = last? last[2] : null
return item ? item[column.name] : null
}
})
}
return (
<div>
<h3>Locked rows demo</h3>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={firstLocked}
onChange={firstLocked => update({ firstLocked }, setFirstLocked)}
>
Lock row 1
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={secondLocked}
onChange={secondLocked => update({secondLocked}, setSecondLocked)}
>
Lock row 2
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={lastLocked}
onChange={lastLocked => update({lastLocked}, setLastLocked)}
>
Lock last 3 rows at the bottom
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={showZebraRows}
onChange={setShowZebraRows}
>
Show zebra rows
</CheckBox>
</div>
<div style={{ marginBottom: 20}}>
<CheckBox
checked={useRowHeightForLockedRows}
onChange={setUseRowHeightForLockedRows}
>
Use same row height for locked rows
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
lockedRows={lockedRows}
style={gridStyle}
rowHeight={45}
columns={columns}
dataSource={dataSource}
useRowHeightForLockedRows={useRowHeightForLockedRows}
showZebraRows={showZebraRows}
/>
</div>
);
}
export default () => <App />
{ width: Number, height: Number }
default: undefined
<ReactDataGrid />
is reading the available viewport size from the DOM after the initial layout and in some cases, if you try to test with jsdom, for example, that doesn't happened. So, viewportSize
prop it sets an initial viewport size for the grid.Bool
default: undefined
undefined
, so column virtualization happens only when you have a number of columns
equal or greater than virtualizeColumnsThreshold
(which defaults to 15
).virtualizeColumns
is specified, column virtualization is applied depending on its value.<ReactDataGrid />
is also built to support a big number of columns
. Although most grids people use have 10 columns or less, the<ReactDataGrid />
should be able to handle 50 columns quite easily.<ReactDataGrid />
is snappier. So a performance tip when column virtualization is enabled would be to increase the column widths so less columns can be visible at a single moment in the viewport.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: 550, marginTop: 10 }
const empty = () => null
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 40 },
{ name: 'firstName', defaultWidth: 135, header: 'First Name' },
{ name: 'lastName', defaultWidth: 135, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultWidth: 135, header: 'Email' },
{ id: 'col_4', header: 'Column 4', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_5', header: 'Column 5', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_6', header: 'Column 6', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_7', header: 'Column 7', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_8', header: 'Column 8', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_9', header: 'Column 9', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_10', header: 'Column 10', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_11', header: 'Column 11', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_12', header: 'Column 12', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_13', header: 'Column 13', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_14', header: 'Column 14', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_15', header: 'Column 15', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_16', header: 'Column 16', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_17', header: 'Column 17', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_18', header: 'Column 18', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_19', header: 'Column 19', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_20', header: 'Column 20', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_21', header: 'Column 21', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_22', header: 'Column 22', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_23', header: 'Column 23', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_24', header: 'Column 24', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_25', header: 'Column 25', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_26', header: 'Column 26', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_27', header: 'Column 27', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_28', header: 'Column 28', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_29', header: 'Column 29', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) },
{ id: 'col_30', header: 'Column 30', minWidth: 135, render: ({ data, rowIndex, columnIndex }) => 'Row ' + rowIndex + ', col ' + (columnIndex + 1) }
]
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 [virtualizeColumns, setVirtualizeColumns] = useState(true);
const dataSource = useCallback(loadData, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={virtualizeColumns}
onChange={setVirtualizeColumns}
>Virtualize columns</CheckBox>
</div>
<ReactDataGrid
key={'grid-' + virtualizeColumns}
idProperty="id"
style={gridStyle}
columns={columns}
rowHeight={50}
dataSource={dataSource}
limit={800}
virtualizeColumns={virtualizeColumns}
/>
</div>
);
}
export default () => <App />
Number
default: 15
virtualizeColumns
is undefined
, column virtualization is applied when the number of columns
is greater or equal to the value of virtualizeColumnsThreshold
.virtualizeColumns
for performance considerations and recommendations.import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import DATASET_URL from './DATASET_URL'
const gridStyle = { minHeight: 550, marginTop: 10 }
const empty = () => null
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', maxWidth: 40 },
{ name: 'firstName', defaultWidth: 135, header: 'First Name' },
{ name: 'lastName', defaultWidth: 135, header: 'Last Name' },
{ name: 'email', groupBy: false, defaultWidth: 135, header: 'Email' },
{ id: 'col_5', header: 'Column 5', defaultWidth: 135, render: ({ data, rowIndex }) => 'dummy col1' },
{ id: 'col_6', header: 'Column 6', defaultWidth: 135, render: ({ data, rowIndex }) => 'dummy col2' },
{ id: 'col_7', header: 'Column 7', defaultWidth: 135, render: ({ data, rowIndex }) => 'dummy col3' },
{ id: 'col_8', header: 'Column 8', defaultWidth: 135, render: ({ data, rowIndex }) => 'dummy col4' },
{ id: 'col_9', header: 'Column 9', defaultWidth: 135, render: ({ data, rowIndex }) => 'dummy col5' },
{ id: 'col_10', header: 'Column 10', defaultWidth: 135, render: ({ data, rowIndex }) => 'dummy col6' }
]
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 dataSource = useCallback(loadData, [])
return (
<div>
<ReactDataGrid
idProperty="id"
virtualizeColumnsThreshold={10}
style={gridStyle}
columns={columns}
rowHeight={50}
dataSource={dataSource}
limit={800}
/>
</div>
);
}
export default () => <App />
Bool
default: true
<ReactDataGrid />
rows. When set to false
, the <ReactDataGrid />
renders all the rows in the dataSource
to the DOM without any optimization.virtualized=false
will in most cases lead to performance issues! It's only feasible (performance-wise) to use this when you are sure your dataset is small, as when no virtualization is applied all grid records end up being rendered into the DOM.<ReactDataGrid />
components configured with rowHeight=null
) where the contents of <ReactDataGrid />
cells make the rows have different heights and there is no fixed rowHeight
.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: 500, marginTop: 10 }
const emulateRowRenderComputations = () => {
for (let i = 0; i < 1000; i++) {
const array = new Array(i)
}
}
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' },
{
name: 'permissionToCall', minWidth: 200,
header: 'Permission to call',
render: ({data}) => {
emulateRowRenderComputations()
return data.permissionToCall ? 'Yes' : 'No'
},
renderGroupTitle: value => value ? 'Can be called' : 'Cannot be called'
}
]
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 App = () => {
const [virtualized, setVirtualized] = useState(false);
const dataSource = useCallback(loadData, [])
return (
<div>
<CheckBox
style={{ marginBottom: 20 }}
checked={virtualized}
onChange={setVirtualized}
>
virtualized
</CheckBox>
<ReactDataGrid
key={virtualized}
sortable={false}
idProperty="id"
style={gridStyle}
columns={columns}
pagination
pageSizes={[100, 400, 800]}
dataSource={dataSource}
defaultLimit={200}
virtualized={virtualized}
/>
</div>
);
}
export default () => <App />
Fn(filterRows: Number)
default: undefined
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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const defaultFilterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: '' },
{ name: 'age', operator: 'gte', type: 'number', value: null }
]
const App = () => {
const [filterValue, setFilterValue] = useState(defaultFilterValue)
const [filteredRows, setFilteredRows] = useState(null)
return (
<div>
<p>Number of rows: {filteredRows}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onFilterValueChange={setFilterValue}
filteredRowsCount={setFilteredRows}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(activeCell: Number[2])
default: undefined
activeCell
or defaultActiveCell
) and the user changes the currently active cell.activeCell
(an array of size two, the first number being the row index, while the second number is the column index).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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [activeCell, setActiveCell] = useState([4, 1])
const [enableKeyboardNavigation, setEnableKeyboardNavigation] = useState(true)
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 />
Fn(activeIndex: Number)
default: undefined
activeIndex
or the uncontrolled defaultActiveIndex
or using no active index at all but still have enableKeyboardNavigation=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'
import flags from './flags'
const gridStyle = { minHeight: 500 }
const columns = [
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
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>Currently active index: {activeIndex}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
activeIndex={activeIndex}
onActiveIndexChange={setActiveIndex}
enableKeyboardNavigation={enableKeyboardNavigation}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn([...{ column: Object, size: Number, defaultFlex: Number, width: Number }])
default: undefined
onColumnResize
.onBatchColumnResize
is called with an an array of objects, each having the following properties:column
- an object describing the column that has been resized. size
- a number representing the new size of the column, in pixelsflex
- indicates whether this column is configured to be flexbile or not. flexValue
- only for flex columns - the value of the flex propimport React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', group: 'personalInfo', defaultWidth: 120 },
{ name: 'age', header: 'Age', group: 'personalInfo', type: 'number', defaultWidth: 120 },
{ name: 'email', header: 'Email', group: 'contactInfo', defaultWidth: 120 },
{ name: 'phone', header: 'Phone', group: 'contactInfo', defaultWidth: 120 },
{ name: 'city', header: 'City', group: 'location', defaultWidth: 120 },
{ name: 'streetName', header: 'Street name', group: 'street', defaultWidth: 120 },
{ name: 'streetNo', header: 'Street no', group: 'street', type: 'number', defaultWidth: 120 }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Personal info' },
{ name: 'contactInfo', header: 'Contact info' },
{ name: 'location', header: 'Loacation' },
]
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 onBatchColumnResize = (columnsInfo) => {
inovua.notification.first.addNotification({
title: 'Resize occured',
content: JSON.stringify(columnsInfo.map(info => {
return {
column: info.column.name,
size: info.column.size,
flex: info.column.flex,
flexValue: info.column.flexValue
}
}))
})
}
export default () => <div>
<p>
Resize a column group
</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
onBatchColumnResize={onBatchColumnResize}
/>
<NotificationBoard id="first" />
</div>
Fn(event)
default: undefined
<ReactDataGrid />
body list is blurred (when it loses focus).import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { marginTop: 10, minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [focused, setFocused] = useState(false)
const onFocus = useCallback((event) => {
setFocused(true)
}, [])
const onBlur = useCallback((event) => {
setFocused(false)
inovua.notification.first.addNotification({
title: 'Grid has been blurred'
})
}, [])
return (
<div>
<p>
Click on the grid and outside it.
</p>
<p>
The grid is {focused ? 'focused' : 'blurred'}.
</p>
<ReactDataGrid
style={gridStyle}
idProperty="id"
onFocus={onFocus}
onBlur={onBlur}
columns={columns}
dataSource={people}
/>
<NotificationBoard id="first" />
</div>
);
}
export default () => <App />
Fn(cellProps: Object, event)
default: undefined
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: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [cellStyle, setCellStyle] = useState({})
const [lastClickedCell, setLastClickedCell] = useState(null)
const [columns, setColumns] = useState(defaultColumns)
const onCellClick = useCallback((event, cellProps) => {
const { columnIndex, rowIndex } = cellProps
const applyColumnStyle = (c, index) => {
if (index === columnIndex) {
c = Object.assign({}, c, {
style: (cellProps) => {
if (cellProps.rowIndex == rowIndex) {
return { background: '#ef9a9a', color: '#2e3439' }
}
}
})
} else {
c = Object.assign({}, c, { style: null })
}
return c
}
setLastClickedCell({ columnIndex, rowIndex })
setColumns(columns.map(applyColumnStyle))
}, [])
let cellText = null
if (lastClickedCell) {
cellText = <span>Row {lastClickedCell.rowIndex}, column: {lastClickedCell.columnIndex}</span>
}
return (
<div>
<p>Click on a grid cell!</p>
<p>Last clicked cell: {cellText}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
cellStyle={cellStyle}
onCellClick={onCellClick}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(event, cellProps: Object)
default: undefined
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: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [cellStyle, setCellStyle] = useState({})
const [lastClickedCell, setLastClickedCell] = useState(null)
const [columns, setColumns] = useState(defaultColumns)
const onCellDoubleClick = useCallback((event, cellProps) => {
const { columnIndex, rowIndex } = cellProps
const applyColumnStyle = (c, index) => {
if (index === columnIndex) {
c = Object.assign({}, c, {
style: (cellProps) => {
if (cellProps.rowIndex == rowIndex) {
return { background: '#ef9a9a', color: '#2e3439' }
}
}
})
} else {
c = Object.assign({}, c, { style: null })
}
return c
}
setLastClickedCell({ columnIndex, rowIndex })
setColumns(columns.map(applyColumnStyle))
}, [])
let cellText = null
if (lastClickedCell) {
cellText = <span>Row {lastClickedCell.rowIndex}, column: {lastClickedCell.columnIndex}</span>
}
return (
<div>
<p>Click on a grid cell!</p>
<p>Last clicked cell: {cellText}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
cellStyle={cellStyle}
onCellDoubleClick={onCellDoubleClick}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ column, locked })
default: undefined
column.locked
.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 people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const getColumns = ({ firstColLocked, lastColLocked }) => {
return [
{ name: 'firstName', header: 'First Name', defaultWidth: 250, locked: firstColLocked },
{ name: 'email', header: 'Email', defaultWidth: 250 },
{ name: 'country', header: 'Country', defaultWidth: 250,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', defaultWidth: 250, type: 'number', header: 'Age' },
{
id: 'desc',
header: 'Description',
defaultWidth: 250,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country,
locked: lastColLocked
}
]
}
const lockPositions = [
{ value: true, label: 'true' },
{ value: 'start', label: 'start' },
{ value: 'end', label: 'end' },
{ value: false, label: 'false' }
]
const App = () => {
const [locked, setLocked] = useState(false)
const [firstColLocked, setFirstColLocked] = useState()
const [lastColLocked, setLastColLocked] = useState()
const [columns, setColumns] = useState(getColumns({ firstColLocked, lastColLocked }))
const onColumnLockedChange = useCallback(({ column, locked }) => {
setLocked(locked)
}, [])
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
onColumnLockedChange={onColumnLockedChange}
/>
<div style={{marginTop: 20}}>
<div style={{marginBottom: 20}}>
Make sure the grid does NOT fit the window, so that column lock and scroll make sense.
</div>
<div style={{ marginRight: 8 }}>
First column lock:
</div>
<ComboBox
autoBlur
inlineFlex
idProperty="value"
displayProperty="label"
clearIcon={false}
searchable={false}
value={firstColLocked}
onChange={locked => {
setFirstColLocked(locked)
setColumns(getColumns({ firstColLocked: locked, lastColLocked }))
}}
dataSource={lockPositions}
/>
<div style={{ marginRight: 8 }}>
Last column lock:
</div>
<ComboBox
autoBlur
inlineFlex
idProperty="value"
displayProperty="label"
clearIcon={false}
searchable={false}
value={lastColLocked}
onChange={locked => {
setLastColLocked(locked)
setColumns(getColumns({ firstColLocked, lastColLocked: locked }))
}}
dataSource={lockPositions}
/>
</div>
</div>
);
}
export default () => <App />
Fn(columnOrder: String[]
default: undefined
<ReactDataGrid />
is configured with reorderColumns=true
.columnOrder
.columnOrder
or not.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: 'name', header: 'Name', defaultFlex: 1, draggable: false },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultFlex: 1 },
]
const defaultOrder = ['name', 'email', 'country', 'age',]
const App = () => {
const [reorderColumns, setReorderColumns] = useState(true)
const [columnOrder, setColumnOrder] = useState(defaultOrder)
return (
<div>
<div>
<div style={{marginBottom: 20}}>
First column is fixed, having draggable=false
</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}
/>
</div>
);
}
export default () => <App />
Fn({ column: Object, width: Number, defaultFlex: Number })
default: undefined
onColumnResize
is called with an object that contains the following properties:column
- an object describing the column that has been resized. width
- a number representing the new size of the column, in pixels. For flexed columns, this will be undefined
flex
- the flex prop that should be applied to the column. For fixed-sized columns, this will be undefined
<ReactDataGrid />
can choose to make the column fixed size or it can choose to give the column a new flex
value.width
and flex
values sent to this method.shareSpaceOnResize
works.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: 550 }
const defaultColumns = [
{ name: 'id', header: 'Id', width: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'age', header: 'Age', width: 80, type: 'number' }
]
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
})
setColumns(newColumns)
}, [])
const keys = [1, 2]
const sizes = columns.map((c, keys) => c.flex ? null : <li key={keys.toString()}>{c.name}: {c.width}px.</li>)
return (
<div>
<div key={sizes} style={{ marginBottom: 20 }}>Column sizes (only fixed columns): <ul>{sizes}</ul></div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
shareSpaceOnResize
columns={columns}
onColumnResize={onColumnResize}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ column, visible })
default: undefined
import React, { useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import CheckBox from '@inovua/reactdatagrid-community/packages/CheckBox'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const onColumnVisibleChange = useCallback(({ column, visible }) => {
inovua.notification.first.addNotification({
title: 'Visibility changed',
content: column.name + ' column visibility is set to: ' + visible
})
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
Change column visibility to test the event
</div>
<NotificationBoard id="first" />
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
onColumnVisibleChange={onColumnVisibleChange}
/>
</div>
);
}
export default () => <App />
Fn(event)
default: undefined
onRowContextMenu
.<ReactDataGrid />
, they are called with the event
object as the first argument.onRowContextMenu(rowProps, event)
(which is a custom <ReactDataGrid />
event) and onContextMenu(event)
, which is a native DOM event.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [contextMenuRow, setContextMenuRow] = useState(null)
const onContextMenu = useCallback((event, menuProps) => {
event.preventDefault();
setContextMenuRow(menuProps.rowIndex);
inovua.notification.first.addNotification({
title: 'Context menu event'
})
}, [])
return (
<div>
<p>Right-click on a grid row!</p>
<p>Context menu for row: {contextMenuRow == null? 'none' : contextMenuRow}.</p>
<NotificationBoard id="first" />
<ReactDataGrid
idProperty="id"
style={gridStyle}
onContextMenu={onContextMenu}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(row: Object)
default: undefined
onCopyActiveRowChange
callback is triggered when the active row is copied to clipboard.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 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)
const onCopyActiveRowChange = useCallback(row => {
console.log(row);
}, []);
const onPasteActiveRowChange = useCallback(row => {
console.log(row);
}, []);
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}
onCopyActiveRowChange={onCopyActiveRowChange}
onPasteActiveRowChange={onPasteActiveRowChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn(cells: Object)
default: undefined
onCopySelectedCellsChange
callback is triggered when the selected cells are copied to clipboard.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 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)
const [cellSelection, setCellSelection] = useState({
'2,name': true,
'2,city': true,
'3,name': true,
'3,city': true,
});
const onCopySelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
const onPasteSelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
return (
<div>
<h3>Grid with copy/paste the selected cells</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableClipboard}
onChange={setEnableClipboard}
>Enable clipboard</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
cellSelection={cellSelection}
onCellSelectionChange={setCellSelection}
enableClipboard={enableClipboard}
onCopySelectedCellsChange={onCopySelectedCellsChange}
onPasteSelectedCellsChange={onPasteSelectedCellsChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn(rows: Object[ ])
default: undefined
onCopySelectedRowsChange
callback is triggered when the selected rows are copied to clipboard.import React, { useCallback, 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 renderClipboardContextMenu = (
menuProps, { computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copySelectedRowsToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteSelectedRowsFromClipboard()
},
];
};
const App = () => {
const [checkboxColumn, setCheckboxColumn] = useState(true);
const onCopySelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
const onPasteSelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
return (
<div>
<h3>Select some rows and then copy/paste from custom context menu</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={checkboxColumn} onChange={setCheckboxColumn}>Checkbox column</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard
onCopySelectedRowsChange={onCopySelectedRowsChange}
onPasteSelectedRowsChange={onPasteSelectedRowsChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
checkboxColumn={checkboxColumn}
/>
</div>
);
};
export default () => <App />;
Fn({ columnId, rowIndex, data })
default: undefined
Tab
key, the value is persisted and onEditComplete
is called.Escape
key, the edit is cancelled and onEditCancel
is triggered.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [dataSource, setDataSource] = useState(people)
const [cancelledEdit, setCancelledEdit] = useState('')
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
const edit = cancelledEdit ?
<p>
Last cancelled edit: column - {cancelledEdit.columnId}; row - {cancelledEdit.rowIndex}.
</p> : null
return (
<div>
<div style={{marginBottom: 20}}>
{edit}
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
onEditCancel={setCancelledEdit}
editable
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn({ value, columnId, rowIndex, data })
default: undefined
dataSource
.Tab
key, the value is persisted and onEditComplete
is called.autoFocusOnEditComplete
defaults to true
.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
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
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn({ value, columnId, rowIndex, data })
default: undefined
<ReactDataGrid />
cell. See onEditCancel
or onEditComplete
) in order to be notified when an edit is finished.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [lastEdit, setLastEdit] = useState(null)
const [dataSource, setDataSource] = useState(people)
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
const edit = lastEdit ?
<p>
Last started edit: column - {lastEdit.columnId}; row = {lastEdit.rowIndex}
</p> : null
return (
<div>
{edit}
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditComplete={onEditComplete}
onEditStart={setLastEdit}
editable
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn({ value, columnId, rowIndex, data })
default: undefined
<ReactDataGrid />
cell. It's called both on edit cancel (see onEditCancel
) and edit complete (see onEditComplete
). See inline edit for more details on how to configure & use inline editing.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [lastEdit, setLastEdit] = useState(null)
const onEditStop = useCallback(({ value, columnId, rowIndex }) => {
setLastEdit({ columnId, rowIndex, value })
}, [])
const edit = lastEdit ?
<div style={{ marginBottom: 20 }}>
Last edited value: [{lastEdit.columnId}][{lastEdit.rowIndex}] = {lastEdit && lastEdit.value}
</div> : null
return (
<div>
{edit}
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditStop={onEditStop}
editable
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ value, columnId, rowIndex, data })
default: undefined
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 EditorFeedback = (props) => {
return (
<div style={{ margin: '10px 0px'}}>
Current value: {props.value}.
</div>
)
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [dataSource, setDataSource] = useState(people)
const [value, setValue] = useState('')
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setValue('')
setDataSource(data)
}, [dataSource])
const onEditValueChange = useCallback(({ value, columnId , rowIndex }) => {
setValue(value)
}, [])
const onEditStart = useCallback(({ value, columnId, rowIndex }) => {
setValue(value)
}, [])
return (
<div>
<EditorFeedback value={value} />
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEditStart={onEditStart}
onEditComplete={onEditComplete}
onEditValueChange={onEditValueChange}
editable
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(enableFiltering)
default: undefined
enableFiltering
is changed.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const App = () => {
const [enableFiltering, setEnableFiltering] = useState(true)
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => setEnableFiltering(!enableFiltering)}>
Toggle enable filtering: {enableFiltering ? 'true' : 'false'}
</Button>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onEnableFilteringChange={setEnableFiltering}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
enableFiltering={enableFiltering}
/>
</div>
);
}
export default () => <App />
Fn({ expandedNodes })
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.setNodeExpandedById
, toggleNodeExpandById
, toggleNodeExpand
.expandedNode
- an object containing the expanded nodes ids as keys - see expandedNodes
data
- in case the user clicked to expand/collapse a single node (most probably via the expand/collapse node tool/icon, but could also be a method call), the data
will contain the object corresponding to that nodeindex
- in case the user clicked to expand/collapse a single node (most probably via the expand/collapse node tool/icon, but could also be a method call), the index
will be the index of the node that was just collapsed/expandedid
- in case the user clicked to expand/collapse a single node (most probably via the expand/collapse tool/icon of the node, but could also be a method call), the id
will be the id of the node that was just collapsed/expandednodeExpanded
- in case the user clicked to expand/collapse a single node (most probably via the expand/collapse tool/icon of the node, but could also be a method call), nodeExpanded
will be the new expanded state of that specific nodeonExpandedNodeChange
):onNodeCollapse
- called if the node has been collapsed via the user actiononNodeExpand
- called if the node has been expanded via the user actiononNodeExpandChange
- called with the same argument object as onExpandedNodesChange
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 />
Fn({ expandedRows, collapsedRows, ... })
default: undefined
expandAllRows
, collapseAllRows
, setRowExpandedById
, etc).expandedRows
- an object containing the expanded rows ids as keys - see expandedRows
collapsedRows
- in case expandedRows=true
, the collapsedRows
will be present and contain the collapsed rows ids as keys in this object. See collapsedRows
data
- in case the user clicked to expand/collapse a single row (most probably via the expand/collapse button of the row, but could also be a method call), the data
will contain the object corresponding to that rowindex
- in case the user clicked to expand/collapse a single row (most probably via the expand/collapse button of the row, but could also be a method call), the index
will be the index of the row that was just collapsed/expandedid
- in case the user clicked to expand/collapse a single row (most probably via the expand/collapse button of the row, but could also be a method call), the id
will be the id of the row that was just collapsed/expandedrowExpanded
- in case the user clicked to expand/collapse a single row (most probably via the expand/collapse button of the row, but could also be a method call), rowExpanded
will be the new expanded state of that specific rowonExpandedRowsChange
):onRowCollapse
- called if the row has been collapsed via the user actiononRowExpand
- called if the row has been expanded via the user actiononRowExpandChange
- called with the same argument object as onExpandedRowsChange
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, index) => {
return <tr key={index}>
<td>{name}</td>
<td>{data[name]}</td>
</tr>
})}
</tbody>
</table>
</div>
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [expandedRowsFlag, setExpandedRowsFlag] = useState(null)
const [collapsedRowsFlag, setCollapsedRowsFlag] = useState(null)
const onExpandedRowsChange = useCallback(({ expandedRows, collapsedRows }) => {
setExpandedRowsFlag(expandedRows)
setCollapsedRowsFlag (collapsedRows)
}, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button
style={{ marginRight: 10 }}
onClick={() => gridRef.current.expandAllRows()}
>
Expand all
</Button>
<Button onClick={() => gridRef.current.collapseAllRows()}>
Collapse all
</Button>
</div>
<ReactDataGrid
handle={setGridRef}
idProperty="id"
onExpandedRowsChange={onExpandedRowsChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(filterValue)
default: undefined
filterValue
is changed.filterValue
) and uncontrolled (defaultFilterValue
) filter values.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const defaultFilterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: 'B' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const App = () => {
const [filterValue, setFilterValue] = useState(defaultFilterValue)
return (
<div>
<p>Current filter value: {JSON.stringify(filterValue, null, 2)}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onFilterValueChange={setFilterValue}
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(event)
default: undefined
<ReactDataGrid />
is focused by the user.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 = { marginTop: 10, minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [focused, setFocused] = useState(false)
const onFocus = useCallback((event) => {
setFocused(true)
}, [])
const onBlur = useCallback((event) => {
setFocused(false)
}, [])
return (
<div>
<p>
Click on the grid and outside it.
</p>
<p>
The grid is {focused ? 'focused' : 'blurred'}.
</p>
<ReactDataGrid
style={gridStyle}
idProperty="id"
onFocus={onFocus}
onBlur={onBlur}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(groupBy)
default: undefined
groupBy
is specified) or by removing a column from grouping (either via the clear icon or by dragging the column group item back into the grid header).groupBy
, make sure you use the onGroupByChange
callback prop to update the <ReactDataGrid />
grouping accordingly. 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: 500 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', groupBy: false, defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{
name: 'permissionToCall',
header: 'Permission to call',
flex: 1,
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'])}>Group by permission to call</Button></p>
<p><Button onClick={() => setGroupBy([])}>Ungroup</Button></p>
<div style={{marginBottom: 20}}>
Current grouping: {JSON.stringify(groupBy)}
</div>
<ReactDataGrid
defaultLimit={15}
pagination
idProperty="id"
style={gridStyle}
groupBy={groupBy}
onGroupByChange={setGroupBy}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(collapsedGroups: Object | true, expandedGroups: Object | true)
default: undefined
<ReactDataGrid />
. Often used together with the controlled collapsed
or the uncontrolled defaultCollapsed
.collapsedGroups
/expandedGroups
, make sure you update the collapsedGroups
/expandedGroups
value when onGroupCollapseChange
is triggered.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: 500 }
const columns = [
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [groupBy, setGroupBy] = useState(['country','city'])
const [collapsedGroups, setCollapsedGroups] = useState({ 'uk/London': true, 'usa': true })
const [expandedGroups, setExpandedGroups] = useState({})
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 />
Fn({ data: Object, dropIndex: Number, dropGroup: String })
default: undefined
onGroupRowReorderEnd
callback is triggered.data
- the row data at the drop index.dropIndex
- the drop index.dropGroup
- the drop group.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: 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);
const [movingGroup, setMovingGroup] = useState(null);
const onGroupRowReorderStart = useCallback(({ data, dragIndex, dragGroup }) => {
setMovingGroup(dragGroup);
}, []);
const onGroupRowReorderEnd = useCallback(({ data, dropIndex, dropGroup }) => {
setMovingGroup(dropGroup);
setTimeout(() => setMovingGroup(null), 2000);
}, []);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
theme="default-dark"
checked={allowRowReorderBetweenGroups}
onChange={setAllowRowReorderBetweenGroups}
>
allowRowReorderBetweenGroups
</CheckBox>
</div>
<p>{movingGroup ? 'The ' + movingGroup + ' group is moving.' : 'No group is moved.'}</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={defaultGroupBy}
columns={columns}
dataSource={people}
rowReorderColumn
allowRowReorderBetweenGroups={allowRowReorderBetweenGroups}
renderRowReorderProxy={renderRowReorderProxy}
onGroupRowReorderStart={onGroupRowReorderStart}
onGroupRowReorderEnd={onGroupRowReorderEnd}
/>
</div>
);
};
export default () => <App />;
Fn({ data: Object, dragIndex: Number, dragGroup: String })
default: undefined
onGroupRowReorderStart
callback is triggered.data
- the row data at the drag index.dragIndex
- the index to which drag begins.dragGroup
- the group from which the drag begins.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: 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);
const [movingGroup, setMovingGroup] = useState(null);
const onGroupRowReorderStart = useCallback(({ data, dragIndex, dragGroup }) => {
setMovingGroup(dragGroup);
}, []);
const onGroupRowReorderEnd = useCallback(({ data, dropIndex, dropGroup }) => {
setMovingGroup(dropGroup);
setTimeout(() => setMovingGroup(null), 2000);
}, []);
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
theme="default-dark"
checked={allowRowReorderBetweenGroups}
onChange={setAllowRowReorderBetweenGroups}
>
allowRowReorderBetweenGroups
</CheckBox>
</div>
<p>{movingGroup ? 'The ' + movingGroup + ' group is moving.' : 'No group is moved.'}</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
defaultGroupBy={defaultGroupBy}
columns={columns}
dataSource={people}
rowReorderColumn
allowRowReorderBetweenGroups={allowRowReorderBetweenGroups}
renderRowReorderProxy={renderRowReorderProxy}
onGroupRowReorderStart={onGroupRowReorderStart}
onGroupRowReorderEnd={onGroupRowReorderEnd}
/>
</div>
);
};
export default () => <App />;
Fn(event)
default: undefined
keydown
event happens on the <ReactDataGrid />
.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [lastKey, setLastKey] = useState(null)
const onKeyDown = useCallback(event => {
setLastKey(event.key)
}, [])
return (
<div>
<p>Focus the grid and press some printable characters!</p>
<p>Last pressed key: "{lastKey || 'unknown'}".</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onKeyDown={onKeyDown}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(limit: Number)
default: undefined
limit
is updated.onLimitChange
is called.limit
prop, make sure you update its value when onLimitChange
is triggered, so the dataSource
(most often, a function when the <ReactDataGrid />
has remote pagination) can be reloaded with the correct limit
value.limit
or the uncontrolled defaultLimit
.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: 300, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{ name: 'email', hedaer: 'Email', groupBy: false, defaultFlex: 1 }
]
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 [limit, setLimit] = useState(10)
const dataSource = useCallback(loadData, [])
return (
<div>
<p>Try to update the page size in the combo to see the limit change</p>
<p>Current limit (page size): {limit}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
limit={limit}
onLimitChange={setLimit}
pagination
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(loading: Bool)
default: undefined
loading
state changes.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', header: 'Name', defaultFlex: 1 },
{ name: 'age', header: 'Age' }
]
const App = () => {
const [loading, setLoading] = useState(false)
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: 'Angela Berkley', age: 44, id: 5 },
{ name: 'Franklin Richardson', age: 37, id: 6 }
])
}, 1000)
})
setLoading(true)
setDataSource(data)
}, [])
return (
<div>
<p>
<Button onClick={() => mockTimeConsumingLoad()}>
Start long loading...
</Button>
</p>
<p>
Loading: {loading.toString()}
</p>
<ReactDataGrid
style={{ marginTop: 10, minHeight: 300 }}
idProperty="id"
columns={columns}
dataSource={dataSource}
onLoadingChange={setLoading}
/>
</div>
);
}
export default () => <App />
Fn({ data, id, index })
default: undefined
false
will cancel the action and the node will not be collapsed.data
- will contain the object corresponding to the nodeindex
- will be the index of the nodeid
- the id of the nodenodeProps
- an object with information about the current node - depth, parentId, path, etconNodeExpand
.onExpandedNodesChange
.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 defaultExpandedNodes = { 3: true, '3/1': true}
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 120 }
]
const App = () => {
const [lastCollapsedId, setLastCollapsedId] = useState(null)
const onNodeCollapse = useCallback(({ id }) => {
setLastCollapsedId(id)
})
return (
<div>
<p>
Last collapsed id: {lastCollapsedId == null ? 'none': lastCollapsedId}.
</p>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
onNodeCollapse={onNodeCollapse}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn({ data, id, index })
default: undefined
false
will cancel the action and the node will not be expanded.data
- will contain the object corresponding to the nodeindex
- will be the index of the nodeid
- the id of the nodenodeProps
- an object with information about the current node - depth, parentId, path, etconNodeCollapse
.onExpandedNodesChange
.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 defaultExpandedNodes = { 3: true, '3/1': true}
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 120 }
]
const App = () => {
const [lastExpandedId, setLastExpandedId] = useState(null)
const onNodeExpand = useCallback(({ id }) => {
setLastExpandedId(id)
}, [])
return (
<div>
<p>
Last expanded id: {lastExpandedId == null ? 'none': lastExpandedId}.
</p>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
onNodeExpand={onNodeExpand}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn({ data, id, index })
default: undefined
false
will cancel the action and the node will not be expanded or collapsed.expandedNodes
- an object containing the expanded nodes ids as keys - see expandedNodes
data
- will contain the object corresponding to the nodeindex
- will be the index of the nodeid
- the id of the nodenodeProps
- an object with information about the current node - depth, parentId, path, etcnodeExpanded
- the new expanded state of the nodeonNodeExpand
.onNodeCollapse
.onExpandedNodesChange
.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 defaultExpandedNodes = { 3: true, '3/1': true}
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 120 }
]
const App = () => {
const [lastNodeId, setLastNodeId] = useState(null)
const [nodeExpanded, setNodeExpanded] = useState(null)
const onNodeExpandChange = useCallback(({ id: lastNodeId, nodeExpanded }) => {
setLastNodeId(lastNodeId)
setNodeExpanded(nodeExpanded)
}, [])
return (
<div>
<p>
Last node that was {nodeExpanded ? 'expanded': 'collapsed'}: {lastNodeId == null ? 'none': lastNodeId}.
</p>
<ReactDataGrid
treeColumn="name"
defaultExpandedNodes={defaultExpandedNodes}
onNodeExpandChange={onNodeExpandChange}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn(row: Object)
default: undefined
onPasteActiveRowChange
callback is triggered when the active row is pasted from clipboard.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 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)
const onCopyActiveRowChange = useCallback(row => {
console.log(row);
}, []);
const onPasteActiveRowChange = useCallback(row => {
console.log(row);
}, []);
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}
onCopyActiveRowChange={onCopyActiveRowChange}
onPasteActiveRowChange={onPasteActiveRowChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn(cells: Object)
default: undefined
onPasteSelectedCellsChange
callback is triggered when the selected cells are pasted from clipboard.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 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)
const [cellSelection, setCellSelection] = useState({
'2,name': true,
'2,city': true,
'3,name': true,
'3,city': true,
});
const onCopySelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
const onPasteSelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
return (
<div>
<h3>Grid with copy/paste the selected cells</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={enableClipboard}
onChange={setEnableClipboard}
>Enable clipboard</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
cellSelection={cellSelection}
onCellSelectionChange={setCellSelection}
enableClipboard={enableClipboard}
onCopySelectedCellsChange={onCopySelectedCellsChange}
onPasteSelectedCellsChange={onPasteSelectedCellsChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn(rows: Object[ ])
default: undefined
onCopySelectedRowsChange
callback is triggered when the selected rows are pasted from clipboard.import React, { useCallback, 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 renderClipboardContextMenu = (
menuProps, { computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copySelectedRowsToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteSelectedRowsFromClipboard()
},
];
};
const App = () => {
const [checkboxColumn, setCheckboxColumn] = useState(true);
const onCopySelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
const onPasteSelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
return (
<div>
<h3>Select some rows and then copy/paste from custom context menu</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={checkboxColumn} onChange={setCheckboxColumn}>Checkbox column</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard
onCopySelectedRowsChange={onCopySelectedRowsChange}
onPasteSelectedRowsChange={onPasteSelectedRowsChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
checkboxColumn={checkboxColumn}
/>
</div>
);
};
export default () => <App />;
(computedPropsRef: MutableRef) => void
default: undefined
DataGrid
layout is ready (columns are sized, the grid size is known).computedPropsRef.current
- as the object is changed on every render. Rather, keep a reference to computedPropsRef
- which is React ref.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', header: 'Name', defaultFlex: 1 },
{ name: 'size', header: 'Size', defaultWidth: 120 }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [expandedNodes, setExpandedNodes] = useState(defaultExpandedNodes)
const [dataSource, setDataSource] = useState(treeData)
const onExpandedNodesChange = useCallback(({ expandedNodes }) => {
setExpandedNodes(expandedNodes)
}, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => gridRef.current.setItemPropertyAt(0, 'name', 'Apps')}>
Set "name" property for first node to "Apps"
</Button>
</div>
<div style={{ marginBottom: 20 }}>
<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>
</div>
<ReactDataGrid
onReady={setGridRef}
treeColumn="name"
expandedNodes={expandedNodes}
onExpandedNodesChange={onExpandedNodesChange}
style={gridStyle}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(rowProps)|React.Node
default: undefined
renderRow
we recommend you use onRenderRow(rowProps)
, which has the same benefit of being called with the rowProps
object and be able to modify it, but it discards the returned value, so the default row rendering happens. This ensures all <ReactDataGrid />
features will probably work the same unless you change the layout related styling props.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 onRenderRow = ({ data, style }) => {
const { age } = data
if (age > 30) {
if (age > 35) {
style.color = '#ef9a9a'
} else {
style.color = '#7986cb'
}
}
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Customized row rendering, computed by age
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onRenderRow={onRenderRow}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(reservedViewportWidth: Number)
default: undefined
reservedViewportWidth
changes as a result of user interaction (user resizes columns).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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 2,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'email', header: 'Email', defaultFlex: 3 },
]
const App = () => {
const [reservedViewportWidth, setReservedViewportWidth] = useState()
return (
<div>
<div style={{marginBottom: 20}}>
Columns with flex values of 1, 2, and 3
</div>
<div style={{marginBottom: 20}}>
Reserved viewport width: {reservedViewportWidth ? reservedViewportWidth : 'none'}. Resize/shrink columns and then click the reset button below.
</div>
<div style={{marginBottom: 20}}>
<Button onClick={() => setReservedViewportWidth(null)}>
Clear reserved width
</Button>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
reservedViewportWidth={reservedViewportWidth}
onReservedViewportWidthChange={setReservedViewportWidth}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(rowProps: Object, event)
default: undefined
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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [lastClickedRow, setLastClickedRow] = useState(null)
const onRowClick = useCallback((rowProps, event) => {
setLastClickedRow(rowProps.rowIndex)
}, [])
return (
<div>
<p>Click on a grid row!</p>
<p>Last clicked row: {lastClickedRow === null? 'none' : lastClickedRow}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onRowClick={onRowClick}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ data, id, index })
default: undefined
collapseAllRows
).false
will cancel the action and the row will not be collapsed.data
- will contain the object corresponding to the rowindex
- will be the index of the rowid
- the id of the rowonRowExpand
.onExpandedRowsChange
.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 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 defaultExpandedRows = { 1: true, 2: true}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [lastCollapsedId, setLastCollapsedId] = useState(null)
const onRowCollapse = useCallback(({ id }) => {
setLastCollapsedId(id)
}, [])
return (
<div>
<p>
Last collapsed id: {lastCollapsedId == null ? 'none': lastCollapsedId}.
</p>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
onRowCollapse={onRowCollapse}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(rowProps: Object, event)
default: undefined
renderRowContextMenu
for a custom row context menu demo.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 columns = [
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [contextMenuRow, setContextMenuRow] = useState(null)
const onRowContextMenu = useCallback((rowProps, event) => {
event.preventDefault()
setContextMenuRow(rowProps.rowIndex)
}, [])
return (
<div>
<p>Right-click on a grid row!</p>
<p>Context menu row: {contextMenuRow == null? 'none' : contextMenuRow}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onRowContextMenu={onRowContextMenu}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(event, cellProps: Object)
default: undefined
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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [lastClickedRow, setLastClickedRow] = useState(null)
const onRowDoubleClick = useCallback((event, rowProps) => {
setLastClickedRow(rowProps.rowIndex)
}, [])
return (
<div>
<p>Click on a grid row!</p>
<p>Last clicked row: {lastClickedRow === null? 'none' : lastClickedRow}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
onRowDoubleClick={onRowDoubleClick}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ data, id, index })
default: undefined
expandAllRows
).false
will cancel the action and the row will not be expanded.data
- will contain the object corresponding to the rowindex
- will be the index of the rowid
- the id of the rowonRowCollapse
.onExpandedRowsChange
.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 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 defaultExpandedRows = {}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [lastExpandedId, setLastExpandedId] = useState(null)
const onRowExpand = useCallback(({ id }) => {
setLastExpandedId(id)
})
return (
<div>
<p>
Last expanded id: {lastExpandedId == null ? 'none': lastExpandedId}.
</p>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
onRowExpand={onRowExpand}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({ data, id, index, collapsedRows, expandedRows, rowExpanded })
default: undefined
expandAllRows
or collapseAllRows
).false
will cancel the action and the row will not be expanded or collapsed.expandedRows
- an object containing the expanded rows ids as keys - see expandedRows
collapsedRows
- in case expandedRows=true
, the collapsedRows
will be present and contain the collapsed rows ids as keys in this object. See collapsedRows
data
- will contain the object corresponding to the rowindex
- will be the index of the rowid
- the id of the rowrowExpanded
- the new expanded state of the rowonRowCollapse
.onRowExpand
.onExpandedRowsChange
.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 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 defaultExpandedRows = { 1: true }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
const [lastRowId, setLastRowId] = useState(null)
const [rowExpanded, setRowExpanded] = useState(null)
const onRowExpandChange = useCallback(({ id: lastRowId, rowExpanded }) => {
setLastRowId(lastRowId)
setRowExpanded(rowExpanded)
}, [])
return (
<div>
<p>
Last row that was {rowExpanded ? 'expanded': 'collapsed'}: {lastRowId == null ? 'none': lastRowId}.
</p>
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
onRowExpandChange={onRowExpandChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn({data, dragRowIndex, insertRowIndex })
default: undefined
<ReactDataGrid />
is configured with row reordering and the user reorders rows via drag and drop - more specifically, called when the row is dropped.import React, { useCallback, useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import people from './people'
import flags from './flags'
import moveXBeforeY from './moveXBeforeY'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{ name: 'country', header: 'Country', defaultWidth: 120,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 }
]
const App = () => {
const [dataSource, setDataSource] = useState([].concat(people))
const onRowReorder = useCallback(({ data, dragRowIndex, insertRowIndex }) => {
let newData = moveXBeforeY([...dataSource], dragRowIndex, insertRowIndex);
setDataSource(newData);
}, [dataSource])
return (
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={40}
onRowReorder={onRowReorder}
columns={columns}
dataSource={dataSource}
/>
)
}
export default () => <App />
Fn({ data: Object, dropIndex: Number })
default: undefined
onRowReorderEnd
callback is triggered.data
- the row data at the drop index.dropIndex
- the drop index.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 renderRowReorderProxy = ({data}) => {
return <div style={{ paddingLeft: 30 }}>ID: {data.id} - Name: {data.name}</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id' },
{ name: 'name', defaultWidth: 120, header: 'Name', },
{ name: 'country', defaultWidth: 120, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultWidth: 120, header: 'Age' }
];
const App = () => {
const [movingRow, setMovingRow] = useState(null);
const onGroupRowReorderStart = useCallback(({ data, dragIndex }) => {
setMovingRow(dragIndex);
}, []);
const onGroupRowReorderEnd = useCallback(({ data, dropIndex }) => {
setMovingRow(dragIndex);
setTimeout(() => setMovingRow(null), 2000);
}, []);
return (
<div>
<p>{movingRow != null ? 'The ' + movingRow + ' is moving.' : 'No row is moved.'}</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={40}
rowReorderColumn
renderRowReorderProxy={renderRowReorderProxy}
columns={columns}
dataSource={people}
onGroupRowReorderStart={onGroupRowReorderStart}
onGroupRowReorderEnd={onGroupRowReorderEnd}
/>
</div>
)
}
export default () => <App />
Fn({ data: Object, dragIndex: Number })
default: undefined
onRowReorderStart
callback is triggered.data
- the row data at the drag index.dragIndex
- the index to which drag begins.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 renderRowReorderProxy = ({data}) => {
return <div style={{ paddingLeft: 30 }}>ID: {data.id} - Name: {data.name}</div>
}
const columns = [
{ name: 'id', defaultWidth: 60, header: 'Id' },
{ name: 'name', defaultWidth: 120, header: 'Name', },
{ name: 'country', defaultWidth: 120, header: 'Country',
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', type: 'number', defaultWidth: 120, header: 'Age' }
];
const App = () => {
const [movingRow, setMovingRow] = useState(null);
const onGroupRowReorderStart = useCallback(({ data, dragIndex }) => {
setMovingRow(dragIndex);
}, []);
const onGroupRowReorderEnd = useCallback(({ data, dropIndex }) => {
setMovingRow(dragIndex);
setTimeout(() => setMovingRow(null), 2000);
}, []);
return (
<div>
<p>{movingRow != null ? 'The ' + movingRow + ' is moving.' : 'No row is moved.'}</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowHeight={40}
rowReorderColumn
renderRowReorderProxy={renderRowReorderProxy}
columns={columns}
dataSource={people}
onGroupRowReorderStart={onGroupRowReorderStart}
onGroupRowReorderEnd={onGroupRowReorderEnd}
/>
</div>
)
}
export default () => <App />
Fn({ selected, data, unselected })
default: undefined
selected
or an uncontrolled defaultSelected
or the enableSelection
prop).<ReactDataGrid />
and changes the current selection, onSelectionChange
is called with an object, that has the following keys:data
- an array that holds all the selected items.selected
- an object with the selected items, keyed using their id properties as specified by idProperty
.unselected
- an object with unselected items, keyed just like the selected
property. This is only used when remote dataSource
is used, since in this situation there are cases when the<ReactDataGrid />
needs to store unselected items rather than selected ones (eg: user selects all items, and then unselects one or two rows - selected
becomes true
, while unselected
stores the two unselected ids).preventRowSelectionOnClickWithMouseMove
.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 columns = [
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [selected, setSelected] = useState({ 1: true, 2: true })
const onSelectionChange = useCallback(({ selected: selectedMap, data }) => {
setSelected(selectedMap)
}, [])
return (
<div>
<p>
Selected rows: {selected == null ? 'none' : JSON.stringify(Object.keys(selected))}.
</p>
<p>
You can shift+click grid rows to select multiple rows
</p>
<ReactDataGrid
idProperty="id"
multiSelect
selected={selected}
onSelectionChange={onSelectionChange}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(skip: Number)
default: undefined
skip
is updated. When the user goes to the next page this callback prop is called.skip
, make sure you update its value when onSkipChange
is triggered, so the dataSource
(most often, a function when the <ReactDataGrid />
has remote pagination) can be reloaded with the correct skip
value.skip
or the uncontrolled defaultSkip
.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: 300, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{ name: 'email', hedaer: 'Email', groupBy: false, defaultFlex: 1 }
]
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 [skip, setSkip] = useState(50)
const dataSource = useCallback(loadData, [])
return (
<div>
<p>Try to navigate to the next pages to see the skip change. Loads page 2 on initial load</p>
<p>Current skip: {skip}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
skip={skip}
onSkipChange={setSkip}
pagination
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(sortInfo)
default: undefined
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: 500 }
const sort = (arr, sortInfo) => {
arr = [].concat(arr)
if (!sortInfo) {
return arr
}
return arr.sort((o1, o2) => {
const v1 = o1[sortInfo.name]
const v2 = o2[sortInfo.name]
const result = sortInfo.type == 'number'
? v1 - v2
: v1.localeCompare(v2)
return result * sortInfo.dir
})
}
const columns = [
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 },
{
id: 'desc',
header: 'Description',
minWidth: 150,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const defaultSortInfo = { name: 'age', type: 'number', dir: 1 }
const initialData = sort(people, defaultSortInfo)
const App = () => {
const [sortInfo, setSortInfo] = useState(defaultSortInfo)
const [dataSource, setDataSource] = useState(initialData)
const onSortInfoChange = useCallback((value) => {
const newSort = value ? { type: value.type, name: value.name, dir: value.dir } : value
setDataSource(sort(people, value))
setSortInfo(newSort)
}, [])
return (
<div>
<div style={{marginBottom: 20}}>
Current sort info: {sortInfo ? <code>{JSON.stringify(sortInfo, null, 2)}</code>: 'none'}.
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
sortInfo={sortInfo}
columns={columns}
dataSource={dataSource}
onSortInfoChange={onSortInfoChange}
/>
</div>
);
}
export default () => <App />
Fn({ updatedTreeData: Array[Object] })
default: undefined
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';
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 onTreeRowReorderEnd = useCallback(({ updatedTreeData: data }) => {
console.log(data);
}, []);
return (
<div>
<h3>TreeGrid with onTreeRowReorderEnd demo</h3>
<ReactDataGrid
treeColumn="name"
theme="default-dark"
style={gridStyle}
columns={columns}
dataSource={treeData}
defaultExpandedNodes={{ 1: true, 2: true, 3: true, '3/1': true }}
rowReorderColumn
enableTreeRowReorder
onTreeRowReorderEnd={onTreeRowReorderEnd}
/>
</div>
);
};
export default () => <App />;
Fn(rowProps)|React.Node
default: undefined
renderRow(rowProps)
function prop.rowProps
, object it receives as first parameter. For example, it can add styles to rowProps.style
or can manipulate classNames by modifying rowProps.className
. Or it can add other events or DOM properties to the rowProps
object.React.Node
, that node is rendered instead of the default implementation.React.Node
from renderRow
, be aware that you are probably breaking virtualization or other useful <ReactDataGrid />
features. So make sure you know what you're doing!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 renderRow = ({ data, style }) => {
const { age } = data
if (age > 30) {
if (age > 35) {
style.color = '#ef9a9a'
} else {
style.color = '#7986cb'
}
}
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80 },
{ name: 'name', header: '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', type: 'number', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<div style={{marginBottom: 20}}>
Customized row rendering, computed by age
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
renderRow={renderRow}
columns={columns}
dataSource={people}
/>
</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 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', defaultVisible: false, defaultWidth: 60, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value })=> flags[value]? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
];
const App = () => {
const [showActiveRowIndicator, setShowActiveRowIndicator] = useState(true);
return (
<div>
<h3>DataGrid with custom active row indicator</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={showActiveRowIndicator}
onChange={setShowActiveRowIndicator}>
Enable active row indicator
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
enableSelection
showActiveRowIndicator={showActiveRowIndicator}
activeRowIndicatorClassName="active-row-border"
/>
</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, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
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}
className="global-datagrid-3px-tomato-border"
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
className
, if enableColumnHover is enabled.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 custom column hover class</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}
columnHoverClassName="custom-column-hover-class-name"
/>
</div>
);
};
export default () => <App />;
Number
default: 9
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, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name - maxWidth: 300', defaultFlex: 2, maxWidth: 300 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City - flex 3', defaultFlex: 3 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<div>
<p>Try resizing a column.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnResizeHandleWidth={20}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import './index.global.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: 'name', header: 'Name', defaultFlex: 1, cellProps: { className: 'global-row-color-tomato' } },
{ name: 'country', header: 'Country', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1, cellProps: { className: 'global-row-color-blue' }},
{ name: 'age', header: 'Age', defaultFlex: 1 }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
columns.style
.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 blueStyle = {
color: '#7986cb'
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, cellProps: { style : blueStyle } },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1, cellProps: { style: { color: '#ef9a9a' } } },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
)
}
export default () => <App />
String | Fn(cellProps: Object)
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import './index.global.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const countryClass = "global-row-color-tomato"
const blueColor = "global-row-color-blue"
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1, className : blueColor },
{
name: 'age',
header: 'Age',
defaultFlex: 1,
type: 'number',
className: ({ value }) => {
if (value < 30) {
return countryClass;
}
return blueColor;
}
}
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import './index.global.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, headerProps: { className : 'global-row-color-blue' } },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1, headerProps: { className: 'global-row-color-tomato' } },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object
default: undefined
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 redStyle = {
color: '#ef9a9a'
}
const blueColor = {
color: '#7986cb'
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, headerProps: { style: blueColor }},
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1, headerProps: { style: redStyle }},
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object|Fn(cellProps: Object)
default: undefined
cellProps.style
.cellProps
of the current cell being rendered.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 cityStyle = ({ data }) => {
const colorMap = {
ca: '#ef9a9a',
uk: '#7986cb'
}
return {
color: colorMap[data.country] || 'orange',
textTransform: 'uppercase'
}
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1, style: { color: '##ff595e' } },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1, style: cityStyle },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
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: 'firstName', header: 'Fist Name', defaultFlex: 1 },
{ name: 'country', header: 'Country', defaultWidth: 100,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'age', header: 'Age', defaultWidth: 70, type: 'number' },
{
id: 'desc',
header: 'Description',
defaultWidth: 250,
render: ({ data}) => data.firstName + ', aged: ' + data.age + '. Lives in ' + data.country
}
]
const App = () => {
const [cellStyle, setCellStyle] = useState({})
const [lastClickedCell, setLastClickedCell] = useState(null)
const [columns, setColumns] = useState(defaultColumns)
const onCellClick = useCallback((event, cellProps) => {
const { columnIndex, rowIndex } = cellProps
const applyColumnStyle = (c, index) => {
if (index === columnIndex) {
c = Object.assign({}, c, {
style: (cellProps) => {
if (cellProps.rowIndex == rowIndex) {
return { background: '#ef9a9a', color: '#2e3439' }
}
}
})
} else {
c = Object.assign({}, c, { style: null })
}
return c
}
setLastClickedCell({ columnIndex, rowIndex })
setColumns(columns.map(applyColumnStyle))
}, [])
let cellText = null
if (lastClickedCell) {
cellText = <span>Row {lastClickedCell.rowIndex}, column: {lastClickedCell.columnIndex}</span>
}
return (
<div>
<p>Click on a grid cell to see the cellStyle applied!</p>
<p>Last clicked cell: {cellText}.</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
cellStyle={cellStyle}
onCellClick={onCellClick}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
string|({ column, summary }, computedProps) => string
default: undefined
footerRow.cellClassName
is used, it will replace this prop.footerCellClassName({
row,
rowIndex,
column,
columnIndex,
summary
}, 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: (_, computedProps) => {
return <div>Selected rows: <b>{computedProps.computedSelectedCount}</b></div>
}
},
colspan: {
name: (_, computedProps) => computedProps.visibleColumns.length
}
}
]
const footerCellClassName = ({ column }, computedProps) => {
if (column.name !== 'name'){
return ''
}
if (computedProps.computedSelectedCount) {
return 'global-with-selected-rows'
}
return ''
}
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 footerCellClassName</h3>
<p>Please select some rows</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
footerCellClassName={footerCellClassName}
dataSource={cities}
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|({ column, summary }, computedProps) => Object
default: undefined
footerRow.cellStyle
is used, it will replace this prop.cellStyle({
row,
rowIndex,
column,
columnIndex,
summary
}, 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: (_, computedProps) => {
return <div>Selected rows: <b>{computedProps.computedSelectedCount}</b></div>
}
},
colspan: {
name: (_, computedProps) => computedProps.visibleColumns.length
}
}
]
const footerCellStyle = ({ column }, computedProps) => {
if (column.name !== 'name'){
return
}
const style = {
paddingTop: 20,
paddingBottom: 20
}
if (computedProps.computedSelectedCount) {
style.background = '#ff595e'
style.color = '#2e3439'
}
return style
}
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 footerCellStyle</h3>
<p>Please select some rows</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
footerCellStyle={footerCellStyle}
dataSource={cities}
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 />
string|({ column, summary }, computedProps) => string
default: undefined
cellClassName({
row,
rowIndex,
column,
columnIndex,
summary
}, computedProps)
footerCellClassName
.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>Population min: {summary.min}</div>
},
cellClassName: 'global-footer-color-blue'
},
{
render: {
population: ({ summary }) => <div>Population max: {summary.max}</div>
},
cellClassName: 'global-footer-color-blue'
},
{
render: {
population: ({ summary }) => <div>Population average: {summary.avg}</div>
}
},
{
render: {
population: ({ summary }) => <div>Countries count: {summary.count}</div>
}
},
{
render: {
population: ({ summary }) => <div>Population sum: {summary.sum}</div>
}
},
{
render: {
name: (_, computedProps) => {
return <div>Selected rows: <b>{computedProps.computedSelectedCount}</b></div>
}
},
colspan: {
name: (_, computedProps) => computedProps.visibleColumns.length
},
cellClassName: ({ column }, computedProps) => {
if (column.name !== 'name'){
return ''
}
if (computedProps.computedSelectedCount) {
return 'global-with-selected-rows'
}
return ''
}
}
]
const summaryReducer = {
initialValue: {
min: Infinity,
max: 0,
avg: 0,
count: 0,
sum: 0
},
reducer: (accumulator, item) => {
if (item.population) {
return {
min: Math.min(accumulator.min, item.population),
max: Math.max(accumulator.max, item.population),
count: accumulator.count + 1,
sum: accumulator.sum + 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 cellClassName</h3>
<p>Please select some rows</p>
<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 />
Object|({ column, summary }, computedProps) => Object
default: undefined
cellStyle({
row,
rowIndex,
column,
columnIndex,
summary
}, computedProps)
footerCellStyle
.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>Population min: {summary.min}</div>
},
cellStyle: {
color: '#7986cb'
}
},
{
render: {
population: ({ summary }) => <div>Population max: {summary.max}</div>
},
cellStyle: {
color: '#7986cb'
}
},
{
render: {
population: ({ summary }) => <div>Population average: {summary.avg}</div>
}
},
{
render: {
population: ({ summary }) => <div>Countries count: {summary.count}</div>
}
},
{
render: {
population: ({ summary }) => <div>Population sum: {summary.sum}</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 = '#ff595e'
style.color = '#2e3439'
}
return style
}
}
]
const summaryReducer = {
initialValue: {
min: Infinity,
max: 0,
avg: 0,
count: 0,
sum: 0
},
reducer: (accumulator, item) => {
if (item.population) {
return {
min: Math.min(accumulator.min, item.population),
max: Math.max(accumulator.max, item.population),
count: accumulator.count + 1,
sum: accumulator.sum + 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 cellStyle</h3>
<p>Please select some rows</p>
<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 />
String
default: undefined
groups.headerClassName
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', minWidth: 50 },
{ name: 'firstName', header: 'First Name', group: 'personalInfo', defaultFlex: 2 },
{ name: 'age', header: 'Age', group: 'personalInfo', type: 'number', minWidth: 50 },
{ name: 'email', header: 'Email', group: 'contactInfo', defaultFlex: 2 },
{ name: 'phone', header: 'Phone', group: 'contactInfo', defaultFlex: 1 },
{ name: 'city', header: 'City', group: 'location', defaultFlex: 1 },
{ name: 'streetName', header: 'Street name', group: 'street', defaultFlex: 1 },
{ name: 'streetNo', header: 'Street no', group: 'street', type: 'number', minWidth: 50 }
]
const groups = [
{ name: 'street', group: 'location', className: 'global-group-color-tomato', header: 'Street' },
{ name: 'personalInfo', header: 'Information about you', className: 'global-group-color-tomato' },
{ name: 'contactInfo', header: <span>Contact</span>, className: 'global-group-color-tomato' },
{ name: 'location', header: <span style={{ color: '#7986cb' }}>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>
String
default: undefined
groups.className
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', minWidth: 50 },
{ name: 'firstName', header: 'First Name', group: 'personalInfo', defaultFlex: 2 },
{ name: 'age', header: 'Age', group: 'personalInfo', type: 'number', minWidth: 50 },
{ name: 'email', header: 'Email', group: 'contactInfo', defaultFlex: 2 },
{ name: 'phone', header: 'Phone', group: 'contactInfo', defaultFlex: 1 },
{ name: 'city', header: 'City', group: 'location', defaultFlex: 1 },
{ name: 'streetName', header: 'Street name', group: 'street', defaultFlex: 1 },
{ name: 'streetNo', header: 'Street no', group: 'street', type: 'number', minWidth: 50 }
]
const groupClassName = 'global-group-color-tomato'
const groups = [
{ name: 'street', group: 'location', headerClassName: groupClassName, header: 'Street' },
{ name: 'personalInfo', header: 'Information about you', headerClassName: groupClassName },
{ name: 'contactInfo', header: <span>Contact</span>, headerClassName: groupClassName },
{ name: 'location', header: <span style={{ color: '#7986cb' }}>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>
string
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 50 },
{ name: 'firstName', header: 'First Name', group: 'personalInfo', defaultFlex: 2 },
{ name: 'age', header: 'Age', width: 100, group: 'personalInfo', type: 'number' },
{ name: 'email', header: 'Email', group: 'contactInfo', defaultFlex: 2 },
{ name: 'phone', header: 'Phone', group: 'contactInfo' },
{ name: 'city', header: 'City', group: 'location' },
{ name: 'streetName', header: 'Street name', minWidth: 150, group: 'street', defaultFlex: 1 },
{ name: 'streetNo', header: 'Street no', group: 'street', type: 'number' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Personal info', headerProps: { className: 'global-row-color-tomato' } },
{ name: 'contactInfo', header: 'Contact info', headerProps: { className: 'global-row-color-blue' } },
{ name: 'location', header: 'Location', headerProps: { className: 'global-row-color-red' } },
]
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: 550 }
export default () => <div>
<h3>DataGrid with custom className on group header</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
/>
</div>
Object
default: undefined
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 50 },
{ name: 'firstName', header: 'First Name', group: 'personalInfo', defaultFlex: 2 },
{ name: 'age', header: 'Age', width: 100, group: 'personalInfo', type: 'number' },
{ name: 'email', header: 'Email', group: 'contactInfo', defaultFlex: 2 },
{ name: 'phone', header: 'Phone', group: 'contactInfo' },
{ name: 'city', header: 'City', group: 'location' },
{ name: 'streetName', header: 'Street name', minWidth: 150, group: 'street', defaultFlex: 1 },
{ name: 'streetNo', header: 'Street no', group: 'street', type: 'number' }
]
const groups = [
{ name: 'street', group: 'location', header: 'Street' },
{ name: 'personalInfo', header: 'Personal info', headerProps: { style: { color: '#ef9a9a' } } },
{ name: 'contactInfo', header: 'Contact info', headerProps: { style: { color: '#7986cb' } } },
{ name: 'location', header: 'Location', headerProps: { style: { color: '#ff595e' } } },
]
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: 550 }
export default () => <div>
<h3>DataGrid with custom style on group header</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columnMinWidth={100}
columns={columns}
groups={groups}
dataSource={dataSource}
/>
</div>
Object
default: undefined
groups.style
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', minWidth: 50 },
{ name: 'firstName', header: 'First Name', group: 'personalInfo', defaultFlex: 2 },
{ name: 'age', header: 'Age', group: 'personalInfo', type: 'number', minWidth: 50 },
{ name: 'email', header: 'Email', group: 'contactInfo', defaultFlex: 2 },
{ name: 'phone', header: 'Phone', group: 'contactInfo', defaultFlex: 1 },
{ name: 'city', header: 'City', group: 'location', defaultFlex: 1 },
{ name: 'streetName', header: 'Street name', group: 'street', defaultFlex: 1 },
{ name: 'streetNo', header: 'Street no', group: 'street', type: 'number', minWidth: 50 }
]
const groupStyle = {
color: '#7986cb',
fontStyle: 'italic'
}
const groups = [
{ name: 'street', group: 'location', headerStyle: groupStyle, header: 'Street' },
{ name: 'personalInfo', header: 'Information about you', headerStyle: groupStyle },
{ name: 'contactInfo', header: <span>Contact</span>, headerStyle: groupStyle },
{ name: 'location', header: <span style={{ color: '#ff595e' }}>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>
Object
default: undefined
groups.headerStyle
import React from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', minWidth: 50 },
{ name: 'firstName', header: 'First Name', group: 'personalInfo', defaultFlex: 2 },
{ name: 'age', header: 'Age', group: 'personalInfo', type: 'number', minWidth: 50 },
{ name: 'email', header: 'Email', group: 'contactInfo', defaultFlex: 2 },
{ name: 'phone', header: 'Phone', group: 'contactInfo', defaultFlex: 1 },
{ name: 'city', header: 'City', group: 'location', defaultFlex: 1 },
{ name: 'streetName', header: 'Street name', group: 'street', defaultFlex: 1 },
{ name: 'streetNo', header: 'Street no', group: 'street', type: 'number', minWidth: 50 }
]
const groupStyle = {
color: '#ef9a9a',
fontStyle: 'italic'
}
const groups = [
{ name: 'street', group: 'location', style: groupStyle, header: 'Street' },
{ name: 'personalInfo', header: 'Information about you', style: groupStyle },
{ name: 'contactInfo', header: <span>Contact</span>, style: groupStyle },
{ name: 'location', header: <span style={{ color: '#7986cb' }}>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>
Number
default: undefined
headerProps
.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, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
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}
headerHeight={100}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
string|({ column, summary }, computedProps) => string
default: undefined
lockedRow.cellClassName
is used, it will replace this prop.lockedRowCellClassName({
row,
rowIndex,
column,
columnIndex,
summary
}, 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 lockedRows = [
{
position: 'start',
render: {
name: (_, computedProps) => {
return <div>Selected rows: <b>{computedProps.computedSelectedCount}</b></div>
}
},
colspan: {
name: (_, computedProps) => computedProps.visibleColumns.length
}
}
]
const lockedRowCellClassName = ({ column }, computedProps) => {
if (column.name !== 'name'){
return ''
}
if (computedProps.computedSelectedCount) {
return 'global-with-selected-rows'
}
return ''
}
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>Locked rows with custom lockedRowCellClassName</h3>
<p>Please select some rows</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
lockedRowCellClassName={lockedRowCellClassName}
dataSource={cities}
lockedRows={lockedRows}
/>
</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|({ column, summary }, computedProps) => Object
default: undefined
lockedRow.cellStyle
is used, it will replace this prop.cellStyle({
row,
rowIndex,
column,
columnIndex,
summary
}, 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 lockedRows = [
{
position: 'start',
render: {
name: (_, computedProps) => {
return <div>Selected rows: <b>{computedProps.computedSelectedCount}</b></div>
}
},
colspan: {
name: (_, computedProps) => computedProps.visibleColumns.length
}
}
]
const lockedRowCellStyle = ({ column }, computedProps) => {
if (column.name !== 'name'){
return
}
const style = {
paddingTop: 20,
paddingBottom: 20
}
if (computedProps.computedSelectedCount) {
style.background = '#ff595e'
style.color = '#2e3439'
}
return style
}
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>Locked row with custom lockedRowCellStyle</h3>
<p>Please select some rows</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
lockedRowCellStyle={lockedRowCellStyle}
dataSource={cities}
lockedRows={lockedRows}
/>
</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 />
string|({ column, summary }, computedProps) => string
default: undefined
cellClassName({
row,
rowIndex,
column,
columnIndex,
summary
}, computedProps)
lockedRowCellClassName
.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 lockedRows = [
{
position: 'start',
render: {
population: ({ summary }) => <div>Population min: {summary.min}</div>
},
cellClassName: 'global-footer-color-blue'
},
{
position: 'start',
render: {
population: ({ summary }) => <div>Population max: {summary.max}</div>
},
cellClassName: 'global-footer-color-blue'
},
{
position: 'start',
render: {
population: ({ summary }) => <div>Population average: {summary.avg}</div>
}
},
{
position: 'end',
render: {
population: ({ summary }) => <div>Countries count: {summary.count}</div>
}
},
{
position: 'end',
render: {
population: ({ summary }) => <div>Population sum: {summary.sum}</div>
}
},
{
position: 'end',
render: {
name: (_, computedProps) => {
return <div>Selected rows: <b>{computedProps.computedSelectedCount}</b></div>
}
},
colspan: {
name: (_, computedProps) => computedProps.visibleColumns.length
},
cellClassName: ({ column }, computedProps) => {
if (column.name !== 'name'){
return ''
}
if (computedProps.computedSelectedCount) {
return 'global-with-selected-rows'
}
return ''
}
}
]
const summaryReducer = {
initialValue: {
min: Infinity,
max: 0,
avg: 0,
count: 0,
sum: 0
},
reducer: (accumulator, item) => {
if (item.population) {
return {
min: Math.min(accumulator.min, item.population),
max: Math.max(accumulator.max, item.population),
count: accumulator.count + 1,
sum: accumulator.sum + 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>Locked rows with custom cellClassName</h3>
<p>Please select some rows</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
dataSource={cities}
summaryReducer={summaryReducer}
lockedRows={lockedRows}
/>
</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|({ column, summary }, computedProps) => Object
default: undefined
cellStyle({
row,
rowIndex,
column,
columnIndex,
summary
}, computedProps)
lockedRowCellStyle
.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 lockedRows = [
{
position: 'start',
render: {
population: ({ summary }) => <div>Population min: {summary.min}</div>
},
cellStyle: {
color: '#7986cb'
}
},
{
position: 'start',
render: {
population: ({ summary }) => <div>Population max: {summary.max}</div>
},
cellStyle: {
color: '#7986cb'
}
},
{
position: 'start',
render: {
population: ({ summary }) => <div>Population average: {summary.avg}</div>
}
},
{
position: 'end',
render: {
population: ({ summary }) => <div>Countries count: {summary.count}</div>
}
},
{
render: {
population: ({ summary }) => <div>Population sum: {summary.sum}</div>
}
},
{
position: 'end',
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 = '#ff595e'
style.color = '#2e3439'
}
return style
}
}
]
const summaryReducer = {
initialValue: {
min: Infinity,
max: 0,
avg: 0,
count: 0,
sum: 0
},
reducer: (accumulator, item) => {
if (item.population) {
return {
min: Math.min(accumulator.min, item.population),
max: Math.max(accumulator.max, item.population),
count: accumulator.count + 1,
sum: accumulator.sum + 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>Locked rows with custom cellStyle</h3>
<p>Please select some rows</p>
<ReactDataGrid
idProperty="id"
style={gridStyle}
checkboxColumn
defaultGroupBy={['country']}
columns={columns}
dataSource={cities}
summaryReducer={summaryReducer}
lockedRows={lockedRows}
/>
</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 />
String|Fn({ data, props, className })
default: undefined
<ReactDataGrid />
rows. It can be a string or a function. In case it's specified as a function, it's called like rowClassName({ data, props, className })
. The returned value is appended to the already existing className
value of the row.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 rowClassName = ({ data }) => {
const colorMap = {
ca: 'red',
uk: 'blue'
}
return 'global-row-color-' + colorMap[data.country]
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
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}
rowClassName={rowClassName}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Object|Function(defaultStyle, rowDetails)
default: undefined
renderRowDetails
prop.renderRowDetails
render prop. This function can either modify the style object it receives (in this case, it has to return undefined
) or it can return a new style object.rowDetailsWidth
.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 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 rowDetailsStyle = (style, { data }) => {
// you have access to data, etc - see renderRowDetails param
style.background = 'rgba(121,134,203,0.2)'
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
return (
<ReactDataGrid
idProperty="id"
defaultExpandedRows={defaultExpandedRows}
renderRowDetails={renderRowDetails}
rowDetailsStyle={rowDetailsStyle}
style={gridStyle}
rowExpandHeight={400}
columns={columns}
dataSource={people}
/>
);
}
export default () => <App />
String
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 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}
rowFocusClassName="global-row-background-tomato"
/>
<TextInput style={{ marginTop: 20, padding: 5, width: 250 }} type="text" defaultValue="Hit shift+tab to navigate to grid" />
</div>
);
}
export default () => <App />
Object
default: undefined
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: 250 }
const rowReorderArrowStyle={
background: 'green',
height: 8,
borderRadius: 1,
};
const columns = [
{ name: 'id', header: 'Id', defaultWidth: 60 },
{ name: 'name', header: 'Name', defaultWidth: 120 },
{
name: 'country',
header: 'Country',
defaultWidth: 120,
render: ({ value }) => (flags[value] ? flags[value] : value),
},
{ name: 'age', header: 'Age', type: 'number', defaultWidth: 120 },
];
const App = () => {
return (
<div>
<h3>Grid with custom row reorder drop position arrow</h3>
<ReactDataGrid
idProperty="id"
style={gridStyle}
rowReorderColumn
columns={columns}
dataSource={[].concat(people)}
rowReorderArrowStyle={rowReorderArrowStyle}
/>
</div>
);
}
export default () => <App />
Object|Fn({ data, props, style })
default: undefined
<ReactDataGrid />
rows. In case it's specified as a function, it's called like rowStyle({ data, props, style })
. The returned object is merged on the already existing row style object.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 rowStyle = ({ data }) => {
const colorMap = {
ca: '#7986cb',
uk: '#ef9a9a'
}
return {
color: colorMap[data.country]
}
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
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}
rowStyle={rowStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool|String
default: true
showCellBorders=true
showCellBorders="horizontal"
showCellBorders="vertical"
showCellBorders=false
showCellBorders.
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', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [verticalBorders, setVerticalBorders] = useState(true)
const [horizontalBorders, setHorizontalBorders] = useState(true)
let showCellBorders = false
if (verticalBorders) {
showCellBorders = 'vertical'
}
if (horizontalBorders) {
showCellBorders = 'horizontal'
}
if (horizontalBorders && verticalBorders) {
showCellBorders = true
}
return (
<div>
<div style={{ marginBottom: 20 }}>
<CheckBox
checked={verticalBorders}
onChange={setVerticalBorders}
>
Show vertical borders
</CheckBox>
</div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={horizontalBorders}
onChange={setHorizontalBorders}
>
Show horizontal borders
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showCellBorders={showCellBorders}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: false
<ReactDataGrid />
should fill the remaining vertical space (if any) available in its viewport with empty rows, when the current dataset does not have enough rows to fill the <ReactDataGrid />
height.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', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const dataSource = people.slice(0, 4)
const App = () => {
const [showEmptyRows, setShowEmptyRows] = useState(true)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={showEmptyRows}
onChange={setShowEmptyRows}
>
Show empty rows.
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
columns={columns}
showEmptyRows={showEmptyRows}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Bool
default: true
true
, applies some additional styling to rows on mouseover, to give nice feedback to the user.showEmptyRows
and showZebraRows
.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', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [showHoverRows, setShowHoverRows] = useState(true)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={showHoverRows}
onChange={setShowHoverRows}
>
Show hover effect for rows
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showHoverRows={showHoverRows}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Bool
default: true
InovuaReactDataGrid__row--odd
className applied.InovuaReactDataGrid__row--even
className applied. When showZebraRows=false
, all the <ReactDataGrid />
rows have InovuaReactDataGrid__row--even
applied.showEmptyRows
.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', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [showZebraRows, setShowZebraRows] = useState(true)
return (
<div>
<div style={{marginBottom: 20}}>
<CheckBox
checked={showZebraRows}
onChange={setShowZebraRows}
>
Show zebra rows
</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
showZebraRows={showZebraRows}
columns={columns}
dataSource={people}
/>
</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'
import flags from './flags'
const gridStyle = {
minHeight: 400,
border: '1px solid #7986cb',
boxShadow: '0 0 8px 2px rgba(121, 134,203, 0.5)'
}
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
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}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
String
default: "default-light"
"default-light"
, however, the docs use "default-dark"
."amber-light"
"amber-dark"
"blue-light"
"blue-dark"
"default-light"
"default-dark"
"green-light"
"green-dark"
"pink-light"
"pink-dark"
@inovua/reactdatagrid-community/theme/<THEME_NAME>.css
or @inovua/reactdatagrid-enterprise/theme/<THEME_NAME>.css
. Also make sure you import @inovua/reactdatagrid-enterprise/base.css
(or @inovua/reactdatagrid-community/base.css
). The base.css
file is included with @inovua/reactdatagrid-enterprise/index.css
, which contains @inovua/reactdatagrid-enterprise/base.css
AND the default theme, @inovua/reactdatagrid-enterprise/theme/default-light.css
.<ReactDataGrid />
. import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import ComboBox from '@inovua/reactdatagrid-community/packages/ComboBox'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const themeDataSource = [
{ id: 'default-dark', label: 'Dark theme' },
{ id: 'default-light', label: 'Light theme' }
]
const App = () => {
const [theme, setTheme] = useState('default-dark')
return (
<div>
<div style={{ marginBottom: 20 }}>
Theme:{' '}
<ComboBox
style={{ width: 150}}
inlineFlex
collapseOnSelect
clearIcon={false}
searchable={false}
changeValueOnNavigation
dataSource={themeDataSource}
value={theme}
onChange={setTheme}
/>
</div>
<ReactDataGrid
idProperty="id"
style={gridStyle}
theme={theme}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
.focus
for an example.Fn({columnId, rowIndex})
undefined
onEditCancel
.Fn()
undefined
<ReactDataGrid />
.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 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, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number', filterEditor: NumberFilter }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={()=> {
gridRef.current.clearAllFilters()
}}>
Clear all filters
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
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(columnIdOrIndex)
undefined
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 filterValue = [
{ name: 'name', operator: 'contains', type: 'string', value: 'o' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={()=> {
gridRef.current.clearColumnFilter('name')
}}>
Clear name filter
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
defaultFilterValue={filterValue}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
.onGroupCollapseChange
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: 600 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [groupBy, setGroupBy] = useState(['country', 'city'])
const [collapsedGroups, setCollapsedGroups] = useState({ 'uk/London': true, 'usa': true })
return (
<div>
<p>
Collapsed groups: {JSON.stringify(Object.keys(collapsedGroups))}.
</p>
<div style={{marginBottom: 20}}>
<Button onClick={() => gridRef.current.collapseAllGroups()}>
Collapse all
</Button>
</div>
<div style={{marginBottom: 20}}>
<Button onClick={() => gridRef.current.expandAllGroups()}>
Expand all
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
collapsedGroups={collapsedGroups}
onGroupCollapseChange={setCollapsedGroups}
defaultGroupBy={groupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
(the <ReactDataGrid />
needs to be expandable, i.e., to have one of the following: enableRowExpand
, expandedRows
, defaultExpandedRows
, renderRowDetails
).expandAllRows
.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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
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={() => {
gridRef.current.expandAllRows()
}} style={{ marginRight: 10 }}>
Expand all
</Button>
<Button onClick={() => {
gridRef.current.collapseAllRows()
}}>
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
onReady={setGridRef}
idProperty="id"
expandedRows={expandedRows}
collapsedRows={collapsedRows}
onExpandedRowsChange={onExpandedRowsChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
.onExpandedNodesChange
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600 }
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: 160 }
];
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [expandedNodes, setExpandedNodes] = useState({ 1: true, 2: true, '3/1': true });
const onExpandedNodesChange = useCallback(({ expandedNodes }) => {
setExpandedNodes(expandedNodes)
}, [])
return (
<div>
<h3>Collapse all tree nodes</h3>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => gridRef.current.collapseAllTreeNodes()}>
Collapse all
</Button>
<Button style={{ marginLeft: 20 }} onClick={() => gridRef.current.expandAllTreeNodes()}>
Expand all
</Button>
</div>
<p>
Expanded nodes: {expandedNodes == null ? 'none' : JSON.stringify(expandedNodes, null, 2)}.
</p>
<ReactDataGrid
treeColumn="name"
handle={setGridRef}
expandedNodes={expandedNodes}
onExpandedNodesChange={onExpandedNodesChange}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn({columnId, rowIndex, value})
undefined
onEditComplete
.Fn()
undefined
import React, { useCallback } 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,
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 renderClipboardContextMenu = (
menuProps,
{ computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copyActiveRowToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteActiveRowFromClipboard()
},
];
};
const App = () => {
const onCopyActiveRowChange = useCallback(row => {
console.log(row);
}, []);
const onPasteActiveRowChange = useCallback(row => {
console.log(row);
}, []);
return (
<div>
<h3>Select a row and then copy/paste from custom context menu</h3>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard
onCopyActiveRowChange={onCopyActiveRowChange}
onPasteActiveRowChange={onPasteActiveRowChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn()
undefined
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: 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 renderClipboardContextMenu = (
menuProps,
{ computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copySelectedCellsToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteSelectedCellsFromClipboard()
},
];
};
const App = () => {
const [cellSelection, setCellSelection] = useState({
'2,name': true,
'2,city': true,
'3,name': true,
'3,city': true,
});
const onCopySelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
const onPasteSelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
return (
<div>
<h3>Copy/paste from custom context menu the selected cells</h3>
<ReactDataGrid
idProperty="id"
theme="default-dark"
cellSelection={cellSelection}
onCellSelectionChange={setCellSelection}
enableClipboard
onCopySelectedCellsChange={onCopySelectedCellsChange}
onPasteSelectedCellsChange={onPasteSelectedCellsChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn()
undefined
true
.import React, { useCallback, 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 renderClipboardContextMenu = (
menuProps, { computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copySelectedRowsToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteSelectedRowsFromClipboard()
},
];
};
const App = () => {
const [checkboxColumn, setCheckboxColumn] = useState(true);
const onCopySelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
const onPasteSelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
return (
<div>
<h3>Select some rows and then copy/paste from custom context menu</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={checkboxColumn} onChange={setCheckboxColumn}>Checkbox column</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard
onCopySelectedRowsChange={onCopySelectedRowsChange}
onPasteSelectedRowsChange={onPasteSelectedRowsChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
checkboxColumn={checkboxColumn}
/>
</div>
);
};
export default () => <App />;
Fn()
undefined
<ReactDataGrid />
.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: 400, marginTop: 10 }
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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', groupBy: false, defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', groupBy: false, defaultFlex: 1 }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [unselected, setUnselected] = useState(null)
const [selected, setSelected] = useState({ 1: true, 3: true })
const dataSource = useCallback(loadData, [])
const onSelectionChange = useCallback(({ selected, unselected }) => {
setSelected(selected)
setUnselected(unselected)
}, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => gridRef.current.selectAll()}>
Select all
</Button>
<Button style={{ marginLeft: 8 }} onClick={() => gridRef.current.deselectAll()}>
Deselect all
</Button>
</div>
<div style={{marginBottom: 20}}>
Unselected rows: {unselected && Object.keys(unselected).length ? JSON.stringify(Object.keys(unselected)) : (selected === true ? 'none' : 'too many')}.
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
checkboxColumn
columns={columns}
checkboxOnlyRowSelect={true}
pagination
selected={selected}
unselected={unselected}
onSelectionChange={onSelectionChange}
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(editProps: Object)
undefined
import React, { useState, useCallback, useRef } 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: 160 },
];
const defaultExpandedNodes = {
1: true,
2: true,
'3/1': true,
};
const App = () => {
const [dataSource, setDataSource] = useState(treeData);
const gridRef = useRef(null);
const onEditComplete = useCallback(
editProps => {
const editedTreeData = gridRef.current.editedTreeData(editProps);
setDataSource(editedTreeData || []);
},
[dataSource]
);
return (
<div>
<h3>Basic TreeGrid</h3>
<ReactDataGrid
treeColumn="name"
handle={(ref: any) => (gridRef.current = ref ? ref.current : null)}
defaultExpandedNodes={defaultExpandedNodes}
style={gridStyle}
columns={columns}
dataSource={dataSource}
editable
onEditComplete={onEditComplete}
/>
</div>
);
};
export default () => <App />;
Fn()
undefined
<ReactDataGrid />
.onGroupCollapseChange
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: 600 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [groupBy, setGroupBy] = useState(['country', 'city'])
const [collapsedGroups, setCollapsedGroups] = useState({ 'uk/London': true, 'usa': true })
return (
<div>
<p>
Collapsed groups: {JSON.stringify(Object.keys(collapsedGroups))}.
</p>
<div style={{marginBottom: 20}}>
<Button onClick={() => gridRef.current.collapseAllGroups() }>
Collapse all
</Button>
</div>
<div style={{marginBottom: 20}}>
<Button onClick={() => gridRef.current.expandAllGroups() }>
Expand all
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
collapsedGroups={collapsedGroups}
onGroupCollapseChange={setCollapsedGroups}
defaultGroupBy={groupBy}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
(the <ReactDataGrid />
needs to be expandable, i.e., to have one of the following: enableRowExpand
, expandedRows
, defaultExpandedRows
, renderRowDetails
).<ReactDataGrid />
has all rows expanded, when expandedRows=true
.collapsedRows
.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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
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={() => {
gridRef.current.expandAllRows()
}} style={{ marginRight: 10 }}>
Expand all
</Button>
<Button onClick={() => {
gridRef.current.collapseAllRows()
}}>
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
onReady={setGridRef}
idProperty="id"
expandedRows={expandedRows}
collapsedRows={collapsedRows}
onExpandedRowsChange={onExpandedRowsChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
.onExpandedNodesChange
import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import '@inovua/reactdatagrid-enterprise/index.css'
const gridStyle = { minHeight: 600 }
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: 160 }
];
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [expandedNodes, setExpandedNodes] = useState({ 1: true, 2: true, '3/1': true });
const onExpandedNodesChange = useCallback(({ expandedNodes }) => {
setExpandedNodes(expandedNodes)
}, [])
return (
<div>
<h3>Expand all tree nodes</h3>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => gridRef.current.collapseAllTreeNodes()}>
Collapse all
</Button>
<Button style={{ marginLeft: 20 }} onClick={() => gridRef.current.expandAllTreeNodes()}>
Expand all
</Button>
</div>
<p>
Expanded nodes: {expandedNodes == null ? 'none' : JSON.stringify(expandedNodes, null, 2)}.
</p>
<ReactDataGrid
treeColumn="name"
handle={setGridRef}
expandedNodes={expandedNodes}
onExpandedNodesChange={onExpandedNodesChange}
style={gridStyle}
columns={columns}
dataSource={treeData}
/>
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
.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'
const gridStyle = { marginTop: 10, minHeight: 300 }
const dataSource = [
{ 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 }
]
const columns = [
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'age', header: 'Age', minWidth: 120 }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [focused, setFocused] = useState(false)
const onFocus = useCallback((event) => {
setFocused(true)
}, [])
const onBlur = useCallback((event) => {
setFocused(false)
}, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => gridRef.current.focus()}>Focus grid</Button>
</div>
<div style={{marginBottom: 20}}>
The grid is {focused ? 'focused' : 'blurred'}.
</div>
<ReactDataGrid
onReady={setGridRef}
enableKeyboardNavigation
style={gridStyle}
idProperty="id"
onFocus={onFocus}
onBlur={onBlur}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(idNameOrIndex)
Object
<ReactDataGrid />
columns), or a column identifier - a column.id
or a column.name
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 550 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeCell, setActiveCell] = useState([5, 2]) // [row, column]
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => {
const column = gridRef.current.getColumnBy(activeCell[1])
inovua.notification.first.addNotification({content: 'Column: ' + column.name})
}}>
Get column of current active cell
</Button>
<NotificationBoard id="first" />
</div>
<ReactDataGrid
idProperty="id"
activeCell={activeCell}
onActiveCellChange={setActiveCell}
style={gridStyle}
columns={columns}
dataSource={people}
onReady={setGridRef}
/>
</div>
);
}
export default () => <App />
Fn(index)
Number
dataSource
.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState(1)
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => {
inovua.notification.first.addNotification({ content: 'Name at index 2:' + gridRef.current.getItemAt(2).name })
}}>
Show name of item at index 2
</Button>
<NotificationBoard id="first" />
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(fn)
Number
dataSource
that satisfies the given function. Returns -1
if no matching item found.dataSource
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState(1)
const getMaryIndex = useCallback(() => {
return gridRef.current.getItemIndexBy((item) => item.name === 'Mary')
}, [gridRef])
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => {
inovua.notification.first.addNotification({ content: 'Index for Mary:' + getMaryIndex() })
}}>
Show index of "Mary"
</Button>
<NotificationBoard id="first" />
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(index)
String|Number
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 NumericInput from '@inovua/reactdatagrid-community/packages/NumericInput'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const initialIndex = 1;
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState(initialIndex);
const [index, setIndex] = useState(initialIndex)
return (
<div>
<div style={{ marginBottom: 20 }}>
<NumericInput value={index} onChange={setIndex} />
<Button style={{ marginLeft: 20 }} onClick={() => {
gridRef.current.setActiveIndex(index);
}}>Set active index</Button>
</div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => {
inovua.notification.first.addNotification({ content: 'Active row id:' + gridRef.current.getRowId(activeIndex) })
}}>
Show id of the active row
</Button>
<NotificationBoard id="first" />
</div>
<p>You have to programmatically set the active index because it will become -1 at blur.</p>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
activeIndex={activeIndex}
onActiveIndexChange={setActiveIndex}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn()
Bool
<ReactDataGrid />
is currently showing a load mask or not. See setLoading
for an example of the setLoading
method.Fn(indexOrData)
undefined
true
if the row at the specified index is expanded. Instead of the index, you can also pass the data object corresponding to the row you want to check.isRowExpandedById
.import React, { useState, useCallback, useRef } 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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState()
const [activeRowId, setActiveRowId] = useState()
const [activeRowExpanded, setActiveRowExpanded] = useState()
const propsRef = useRef(null);
propsRef.current = gridRef && gridRef.current;
const onActiveIndexChange = useCallback((index) => {
const item = propsRef.current.getItemAt(index);
const rowId = propsRef.current.getItemId(item);
setActiveIndex(index)
setActiveRowId(rowId)
setActiveRowExpanded(propsRef.current.isRowExpanded(item))
}, [])
const onExpandedRowsChange = useCallback(({ expandedRows }) => {
if (expandedRows) {
setActiveRowExpanded(!!expandedRows[activeRowId])
}
}, [activeRowId])
return (
<div>
{activeIndex == null ? null : <p>
Active row: {activeIndex}. The row is {activeRowExpanded ? 'expanded': 'collapsed'}.
</p>}
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
activeIndex={activeIndex}
onActiveIndexChange={onActiveIndexChange}
onExpandedRowsChange={onExpandedRowsChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(rowId)
undefined
true
if the row with the specified id is expandedisRowExpanded
.import React, { useState, useCallback, useRef } 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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState()
const [activeRowId, setActiveRowId] = useState()
const [activeRowExpanded, setActiveRowExpanded] = useState()
const propsRef = useRef(null);
propsRef.current = gridRef && gridRef.current;
const onActiveIndexChange = useCallback((index) => {
const rowId = propsRef.current.getItemId(propsRef.current.getItemAt(index))
setActiveIndex(index)
setActiveRowId(rowId)
setActiveRowExpanded(propsRef.current.isRowExpandedById(rowId))
}, [])
const onExpandedRowsChange = useCallback(({ expandedRows }) => {
const newActiveRow = expandedRows ? !!expandedRows[activeRowId] : -1;
setActiveRowExpanded(newActiveRow)
}, [activeRowId])
return (
<div>
{activeIndex == null ? null : <p>
Active row: {activeIndex}. The row is {activeRowExpanded ? 'expanded': 'collapsed'}.
</p>}
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
activeIndex={activeIndex}
onActiveIndexChange={onActiveIndexChange}
onExpandedRowsChange={onExpandedRowsChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(index: number) => boolean
undefined
true
if the row at the specified index is fully visible (is completely in the grid viewport), false
otherwise.import React, { useState } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 350 }
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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
return (
<div>
<p>
<Button onClick={()=> {
const visible = gridRef.current.isRowFullyVisible(1)
inovua.notification.first.addNotification({
title: 'Row 1 is ' + (visible ? 'fully visible': 'not fully visible')
})
}}>Row 1 fully visible?</Button>
</p>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
dataSource={people}
activeIndex={1}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
/>
<NotificationBoard id="first" />
</div>
);
}
export default () => <App />
Fn()
undefined
import React, { useCallback } 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,
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 renderClipboardContextMenu = (
menuProps,
{ computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copyActiveRowToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteActiveRowFromClipboard()
},
];
};
const App = () => {
const onCopyActiveRowChange = useCallback(row => {
console.log(row);
}, []);
const onPasteActiveRowChange = useCallback(row => {
console.log(row);
}, []);
return (
<div>
<h3>Select a row and then copy/paste from custom context menu</h3>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard
onCopyActiveRowChange={onCopyActiveRowChange}
onPasteActiveRowChange={onPasteActiveRowChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn()
undefined
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: 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 renderClipboardContextMenu = (
menuProps,
{ computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copySelectedCellsToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteSelectedCellsFromClipboard()
},
];
};
const App = () => {
const [cellSelection, setCellSelection] = useState({
'2,name': true,
'2,city': true,
'3,name': true,
'3,city': true,
});
const onCopySelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
const onPasteSelectedCellsChange = useCallback(cells => {
console.log(cells);
}, []);
return (
<div>
<h3>Copy/paste from custom context menu the selected cells</h3>
<ReactDataGrid
idProperty="id"
theme="default-dark"
cellSelection={cellSelection}
onCellSelectionChange={setCellSelection}
enableClipboard
onCopySelectedCellsChange={onCopySelectedCellsChange}
onPasteSelectedCellsChange={onPasteSelectedCellsChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
};
export default () => <App />;
Fn()
undefined
true
.import React, { useCallback, 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 renderClipboardContextMenu = (
menuProps, { computedProps }
) => {
if (!computedProps) {
return;
}
menuProps.autoDismiss = true;
menuProps.items = [
{
label: 'Copy to clipboard',
onClick: () => computedProps.copySelectedRowsToClipboard()
},
{
label: 'Paste from clipboard',
onClick: () => computedProps.pasteSelectedRowsFromClipboard()
},
];
};
const App = () => {
const [checkboxColumn, setCheckboxColumn] = useState(true);
const onCopySelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
const onPasteSelectedRowsChange = useCallback(rows => {
console.log(rows);
}, []);
return (
<div>
<h3>Select some rows and then copy/paste from custom context menu</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={checkboxColumn} onChange={setCheckboxColumn}>Checkbox column</CheckBox>
</div>
<ReactDataGrid
idProperty="id"
theme="default-dark"
enableClipboard
onCopySelectedRowsChange={onCopySelectedRowsChange}
onPasteSelectedRowsChange={onPasteSelectedRowsChange}
renderRowContextMenu={renderClipboardContextMenu}
style={gridStyle}
columns={columns}
dataSource={people}
checkboxColumn={checkboxColumn}
/>
</div>
);
};
export default () => <App />;
Fn(Number)
undefined
<ReactDataGrid />
horizontally.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumericInput from '@inovua/reactdatagrid-community/packages/NumericInput'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { minHeight: 400, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultWidth: 400 },
{ name: 'country', header: 'County', defaultWidth: 400,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultWidth: 400 },
{ name: 'age', header: 'Age', defaultWidth: 400, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [value, setValue] = useState(300)
const scrollToLeft = useCallback(() => {
gridRef.current.setScrollLeft(value)
}, [gridRef, value])
const readScrollValue = useCallback(() => {
inovua.notification.first.addNotification({
title: 'Scroll left (getter)',
content: 'Current scrolled value is: ' + gridRef.current.getScrollLeft() + ' px.'
})
}, [gridRef, value])
return (
<div>
<div>
Set how much to scroll:{' '}
<NumericInput
style={{ width: 80 }}
minValue={1}
value={value}
step={10}
onChange={setValue}
/>{' '}
<Button
style={{ height: 30, borderRadius: 3 }}
onClick={scrollToLeft}
>
Scroll left
</Button>{' '}
</div>
<p>
When you press the getter button bellow, a notification will appear to show the scrolled value.
</p>
<div style={{marginBottom: 20}}>
Get how much is scrolled:{' '}
<Button
style={{ height: 30, borderRadius: 3 }}
onClick={readScrollValue}
>
Get scroll left number
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
sortable={false}
dataSource={people}
/>
<NotificationBoard id="first" />
</div>
);
}
export default () => <App />
Fn(index, {direction, force, duration, offset}, callback)
undefined
index
. All parameters but the index
are optional. When scrolling, it brings the specified column into view, if not already visible.grid.scrollToColumn(5)
to scroll to the sixth column (zero-based numbering).scrollToIndex
.direction
(either 'left'
or 'right'
, (the default) , to bring the column to the left or right of the viewport), a duration for smooth scrolling (defaults to 100
milliseconds ) and force
if you want to force the scrolling to happen even if the column is already visible in the viewport (defaults to false
). Optionally, pass a callback - especially useful for being notified when smooth scrolling is finished.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: 400, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, type: 'number', defaultWidth: 80 },
{ name: 'name', header: 'Name', defaultWidth: 200 },
{ name: 'city', header: 'City', defaultWidth: 200 },
{ name: 'country', header: 'Country', defaultFlex: 1, minWidth: 100,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'email', header: 'Email', defaultWidth: 200 },
{ name: 'age', header: 'Age', defaultWidth: 200, type: 'number' },
{ id: 'column_6', header: 'Col 6', defaultWidth: 200, render: () => 'column 6' },
{ id: 'column_7', header: 'Col 7', defaultWidth: 200, render: () => 'column 7' },
{ id: 'column_8', header: 'Col 8', defaultWidth: 200, render: () => 'column 8' },
{ id: 'column_9', header: 'Col 9', defaultWidth: 200, render: () => 'column 9' },
{ id: 'column_10', header: 'Col 10', defaultWidth: 200, render: () => 'column 10' },
{ id: 'column_11', header: 'Col 11', defaultWidth: 200, render: () => 'column 11' },
{ id: 'column_12', header: 'Col 12', defaultWidth: 200, render: () => 'column 12' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const scrollTo = useCallback((index) => {
return () => {
gridRef.current.scrollToColumn(10, { duration: 300 })
}
}, [gridRef])
return (
<div>
<div style={{marginBottom: 20}}>
<Button onClick={scrollTo(10)}>
Scroll to column 10 (duration: 300ms)
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
sortable={false}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(id, {direction, force, duration, offset}, callback)
undefined
id
. All parameters but the id
are optional.grid.scrollToId('f56')
to scroll to the row with 'f56'
scrollToIndex
.direction
(either 'top'
or 'bottom'
, to bring the row to the top or bottom of the viewport), a duration for smooth scrolling (defaults to 100
milliseconds ) and force
if you want to force the scrolling to happen even if the row is already visible in the viewport (defaults to false
). Optionally, pass a callback - especially useful for being notified when smooth scrolling is finished.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: 400, marginTop: 10 }
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 columns = [
{ name: 'id', header: 'Id', defaultVisible: true, groupBy: false, type: 'number', defaultWidth: 60 },
{ name: 'firstName', header: 'First Name', groupBy: false, defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{
name: 'permissionToCall',
header: 'Permission to call',
flex: 1,
render: ({data}) => data.permissionToCall ? 'Yes' : 'No',
renderGroupTitle: value => value === true || value === 'true' ? 'Calls allowed' : 'No calls allowed'
}
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const dataSource = useCallback(loadData, [])
const scrollTo = useCallback((id) => {
return () => {
gridRef.current.scrollToId(id, { duration: 300 })
}
}, [gridRef])
return (
<div>
<div style={{marginBottom: 20}}>
<Button onClick={scrollTo(70)}>
Scroll to id: 70 (duration: 300ms)
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
sortable={false}
dataSource={dataSource}
defaultLimit={100}
/>
</div>
);
}
export default () => <App />
Fn(index, {direction, force, duration, offset}, callback)
undefined
scrollToId
except that you pass an index instead of an id.grid.scrollToIndex(56)
to scroll to the row at index 56
.direction
(either 'top'
or 'bottom'
, to bring the row to the top or bottom of the viewport), a duration for smooth scrolling (defaults to 100
milliseconds ) and force
if you want to force the scrolling to happen even if the row is already visible in the viewport (defaults to false
). Optionally, pass a callback - especially useful for being notified when smooth scrolling is finished.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: 400, marginTop: 10 }
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 columns = [
{ name: 'id', hedaer: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', groupBy: false, defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', groupBy: false, defaultFlex: 1 }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const dataSource = useCallback(loadData, [])
const scrollTo = useCallback((index) => {
return () => {
gridRef.current.scrollToIndex(index, { duration: 300 })
}
}, [gridRef])
return (
<div>
<div style={{marginBottom: 20}}>
<Button
onClick={scrollTo(70)}
>
Scroll to index: 70 (duration: 300ms)
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
sortable={false}
dataSource={dataSource}
defaultLimit={100}
/>
</div>
);
}
export default () => <App />
Fn(Number)
undefined
<ReactDataGrid />
vertically.<ReactDataGrid />
.import React, { useState, useCallback } from 'react'
import ReactDataGrid from '@inovua/reactdatagrid-enterprise'
import '@inovua/reactdatagrid-enterprise/index.css'
import NumericInput from '@inovua/reactdatagrid-community/packages/NumericInput'
import Button from '@inovua/reactdatagrid-community/packages/Button'
import NotificationBoard from '@inovua/react-ui-toolkit/Notification'
import '@inovua/react-ui-toolkit/Notification/index.css'
import people from './people'
import flags from './flags'
const gridStyle = { height: 300, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [value, setValue] = useState(150)
const scrollToTop = useCallback(() => {
gridRef.current.scrollTop = value
}, [gridRef, value])
const readScrollValue = useCallback(() => {
inovua.notification.first.addNotification({
title: 'Scroll top (getter)',
content: 'Current scrolled value is: ' + gridRef.current.scrollTop + ' px.'
})
}, [gridRef, value])
return (
<div>
<div style={{ marginBottom: 20 }}>
Set how much to scroll:{' '}
<NumericInput
style={{ width: 80 }}
minValue={1}
step={10}
value={value}
onChange={setValue}
/>{' '}
<Button
style={{ height: 30, borderRadius: 3 }}
onClick={() => scrollToTop()}
>
Scroll top (setter)
</Button>{' '}
</div>
<p>
When you press the getter button bellow, a notificatin will appear to show the scrolled value.
</p>
<div style={{marginBottom: 20}}>
Get how much is scrolled:{' '}
<Button
style={{ height: 30, borderRadius: 3 }}
onClick={() => readScrollValue()}
>
Scroll top (getter)
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
sortable={false}
dataSource={people}
/>
<NotificationBoard id="first" />
</div>
);
}
export default () => <App />
Fn()
undefined
<ReactDataGrid />
.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: 400, marginTop: 10 }
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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', groupBy: false, defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', groupBy: false, defaultFlex: 1 }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [unselected, setUnselected] = useState(null)
const [selected, setSelected] = useState({ 1: true, 3: true })
const dataSource = useCallback(loadData, [])
const onSelectionChange = useCallback(({ selected, unselected }) => {
setSelected(selected)
setUnselected(unselected)
}, [])
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => gridRef.current.selectAll()}>
Select all
</Button>
<Button style={{ marginLeft: 8 }} onClick={() => gridRef.current.deselectAll()}>
Deselect all
</Button>
</div>
<div style={{marginBottom: 20}}>
Unselected rows: {unselected && Object.keys(unselected).length ? JSON.stringify(Object.keys(unselected)) : (selected === true ? 'none' : 'too many')}.
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
checkboxColumn
columns={columns}
checkboxOnlyRowSelect={true}
pagination
selected={selected}
unselected={unselected}
onSelectionChange={onSelectionChange}
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(columnIdOrIndex, value)
undefined
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 filterValue = [
{ name: 'name', operator: 'startsWith', type: 'string', value: '' },
{ name: 'age', operator: 'gte', type: 'number', value: 21 }
]
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={()=> {
gridRef.current.setColumnFilterValue('name', 'B')
}}>
Filter by names starting with 'B'
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
defaultFilterValue={filterValue}
editable
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(columnId: String, skipHeader: Boolean)
undefined
columnId: String
, which is the id of the column to be resizedskipHeader: Boolean
, which it is a flag. If skipHeader
is true
the algorithm will not include header width in computation, if it is false
, will do so.setColumnSizeAuto
to work, enableColumnAutosize should be true
and the column should be resizable.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';
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);
return (
<div>
<h3>Grid with 'name' column to be autosized</h3>
<div style={{ marginBottom: 20 }}>
<Button
onClick={() => {
if (gridRef && gridRef.current.setColumnSizeAuto) {
gridRef.current.setColumnSizeAuto('name');
}
}}
>
Set 'name' column size auto
</Button>
</div>
<ReactDataGrid
idProperty="id"
handle={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
enableColumnAutosize
/>
</div>
);
};
export default () => <App />;
Fn()
undefined
setColumnSizesToFit
to work, enableColumnAutosize should be true
and the column should be resizable.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';
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);
return (
<div>
<h3>Grid with column sizes to fit</h3>
<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
/>
</div>
);
};
export default () => <App />;
Fn({ columnIds: String[], skipHeader: Boolean, skipSortTool: Boolean })
undefined
columnIds: String[]
, which is an array of strings with all the column ids that are to be resizedskipHeader: Boolean
, which it is a flag. If skipHeader
is true
the algorithm will not include header width in computation, if it is false
, will do so.skipSortTool: Boolean
, which if is true
it will skip the sort tool dimensions when calculating the width of the cells.setColumnsSizesAuto
to work, enableColumnAutosize should be true
and the column should be resizable.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';
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 [skipSortTool, setSkipSortTool] = useState(false);
const setColumnsSizesAuto = useCallback(
(skipHeader, skipSortTool) => {
if (gridRef && gridRef.current.setColumnsSizesAuto) {
gridRef.current.setColumnsSizesAuto({
skipHeader,
skipSortTool
});
}
},
[gridRef]
);
return (
<div>
<h3>Grid with auto size</h3>
<div style={{ marginBottom: 20 }}>
<CheckBox checked={skipSortTool} onChange={setSkipSortTool}>
skipSortTool
</CheckBox>
</div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => setColumnsSizesAuto(false, skipSortTool)}>
Set column sizes auto
</Button>
</div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => setColumnsSizesAuto(true, skipSortTool)}>
Set column sizes auto (skipHeader)
</Button>
</div>
<ReactDataGrid
idProperty="id"
handle={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
enableColumnAutosize
/>
</div>
);
};
export default () => <App />;
Fn(index, item: Object, config: { replace: Bool })
undefined
dataSource
. The second param is the item
that will be merged onto the current item at the specified index
. If config.replace
is true, it will replace the specified items altogether (note that replacing the items, with a different one, that has another id value can have undesired effects).clearDataSourceCacheOnChange
to clear any cached values (as a result to calls to this method) when the dataSource
changes.idProperty
) for an item - since this can have undesired effects.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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => {
gridRef.current.setItemAt(2, { name: 'Danny' })
}}>
Set name of item at index 2 to be "Danny"
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(index, propertyName: String, value: Any)
undefined
dataSource
.idProperty
) for an item - since this can have undesired effects.clearDataSourceCacheOnChange
to clear any cached values (as a result to calls to this method) when the dataSource
changes.treeColumn
), you can use clearNodeCacheOnDataSourceChange
to clear any cached values (as a result to calls to this method) when the dataSource
changes.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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState(1)
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => {
gridRef.current.setItemPropertyAt(2, 'name', 'Danny')
}}>
Set name of item at index 2 to be "Danny"
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(items: Array, config: { replace: Bool })
undefined
dataSource
. If config.replace
is true, it will replace the specified item altogether (note that replacing the item, with a different one, that has another id value can have undesired effects).clearDataSourceCacheOnChange
to clear any cached values (as a result to calls to this method) when the dataSource
changes.idProperty
) for an item - since this can have undesired effects.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'
const gridStyle = { minHeight: 300 }
const colsString = 'abcdefghij'
const buildColumns = cols => {
return cols.split('').map(letter => {
return {
defaultWidth: 120,
header: letter.toUpperCase(),
name: letter
}
})
}
const buildDataSource = (records, cols) => {
const data = []
for (let i = 0; i < records; i++) {
const result = {
id: i
}
cols.split('').map(letter => {
result[letter] = letter.toUpperCase() + ' ' + (i + 1)
})
data.push(result)
}
return data
}
const getRandomInt = max => {
return Math.floor(Math.random() * max)
}
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [columns, setColumns] = useState(buildColumns(colsString))
const [dataSource, setDataSource] = useState(buildDataSource(100, colsString))
const setItemsAt = () => {
const startIndex = 0
const endIndex = 100
const sliceData = dataSource.slice(startIndex, endIndex)
const items = sliceData.map((_, index) => {
const row = {
id: index
}
colsString.split('').map(letter => {
const randomNumber = getRandomInt(endIndex)
let color = '#9ba7b4'
if (randomNumber > (2/3) * endIndex) color = '#8bb58d'
if (randomNumber < endIndex / 3) color = '#e6a0a0'
const property = letter
const value = (
<span>
{letter.toUpperCase() + ' ' + (index + 1) + ' - '}
<span style={{ color }}>{randomNumber}</span>
</span>
)
row[property] = value
})
return row
})
gridRef.current.setItemsAt(items, {
replace: false
})
}
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={setItemsAt}>
Set value for all items
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(loading: Bool)
undefined
<ReactDataGrid />
show a loading mask.loading
prop is used, calling this method will only trigger onLoadingChange
, and you have to update the loading
prop yourself.setLoading
, onLoadingChange
is called whether you're using controlled loading
or the uncontrolled defaultLoading
, or no loading prop at all. In case of uncontrolled or unspecified loading prop, the load mask is shown/hidden depending on the parameter you call setLoading
with.dataSource
, the dataSource
will trigger onLoadingChange
when it starts loading and when it resolves, so you generally don't need to use setLoading
yourself.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'
const gridStyle = { marginTop: 10, minHeight: 400 }
const dataSource = [
{ 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 }
]
const columns = [
{ name: 'name',header: 'Name', defaultFlex: 1 },
{ name: 'age', header: 'Age', minWidth: 120 }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [isLoadingKey, setIsLoadingKey] = useState(false)
const isLoading = gridRef ? gridRef.current.isLoading() : false
return (
<div>
<div key={isLoadingKey} style={{ marginBottom: 20 }}>
Is loading: {isLoading ? 'true' : 'false'}
</div>
<div style={{ marginBottom: 20 }}>
<Button onClick={() => {
gridRef.current.setLoading(true)
setTimeout(() => setIsLoadingKey(true), 0)
}}>
Set loading to true
</Button>
<Button style={{ marginLeft: 8 }} onClick={() => {
gridRef.current.setLoading(false)
setTimeout(() => setIsLoadingKey(false), 0)
}}>
Set loading to false
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
style={gridStyle}
idProperty="id"
columns={columns}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn(dataOrIndex, expanded)
undefined
setRowExpandedById
.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 NumericInput from '@inovua/reactdatagrid-community/packages/NumericInput'
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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState();
const [index, setIndex] = useState();
return (
<div>
<div style={{ marginBottom: 20 }}>
<NumericInput value={index} onChange={setIndex} />
<Button
style={{ marginLeft: 20 }}
onClick={() => {
gridRef.current.setActiveIndex(index);
}}
>
Set active index
</Button>
</div>
<div style={{ marginBottom: 20}}>
<Button
style={{ marginRight: 20}}
disabled={activeIndex === undefined}
onClick={() => gridRef.current.setRowExpandedAt(activeIndex, true)}
>
Expand active row
</Button>
<Button
style={{ marginRight: 20}}
disabled={activeIndex === undefined}
onClick={() => gridRef.current.setRowExpandedAt(activeIndex, false)}
>
Collapse active row
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
onActiveIndexChange={setActiveIndex}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(rowId, expanded)
undefined
setRowExpanded
.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 NumericInput from '@inovua/reactdatagrid-community/packages/NumericInput'
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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null);
const [activeIndex, setActiveIndex] = useState();
const [index, setIndex] = useState();
const onActiveIndexChange = useCallback((index) => {
setActiveIndex(index)
}, [])
const toggleExpandedIndex = useCallback((expand) => {
const id = gridRef.current.getItemId(gridRef.current.getItemAt(activeIndex));
gridRef.current.setRowExpandedById(id, expand)
}, [gridRef, activeIndex])
return (
<div>
<div style={{ marginBottom: 20 }}>
<NumericInput
style={{ width: 100 }}
value={index}
onChange={setIndex}
/>
<Button
style={{ marginLeft: 20 }}
onClick={() => {
gridRef.current.setActiveIndex(index);
}}
>
Set active index
</Button>
</div>
<div style={{ marginBottom: 20}}>
<Button
style={{ marginRight: 20}}
disabled={activeIndex === undefined}
onClick={() => toggleExpandedIndex(true)}
>
Expand active row
</Button>
<Button
style={{ marginRight: 20}}
disabled={activeIndex === undefined}
onClick={() => toggleExpandedIndex(false)}
>
Collapse active row
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
activeIndex={activeIndex}
onActiveIndexChange={onActiveIndexChange}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(index: Number, selected: Bool)
undefined
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: 300 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [activeIndex, setActiveIndex] = useState(1)
return (
<div>
<div style={{marginBottom: 20}}>
<Button onClick={() => {
const index = activeIndex
const selected = gridRef.current.isRowSelected(index)
gridRef.current.setRowSelected(index, !selected)
}}>
Toggle active row selection
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
checkboxColumn
checkboxOnlyRowSelect
activeIndex={activeIndex}
onActiveIndexChange={setActiveIndex}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(scrollPos, {orientation, duration}, callback)
undefined
scrollPos
on the axis defined by orientation
(either "horizontal"
or "vertical"
are accepted values). So grid.smoothScrollTo(120, { orientation: 'horizontal'})
sets scrollLeft
to 120
. duration
defaults to 100
milliseconds.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: 400, marginTop: 10 }
const columns = [
{ name: 'id', header: 'Id', defaultVisible: false, groupBy: false, type: 'number', defaultWidth: 80 },
{ name: 'firstName', header: 'First Name', groupBy: false, defaultFlex: 1 },
{ name: 'lastName', header: 'Last Name', defaultFlex: 1 },
{ name: 'email', header: 'Email', groupBy: false, defaultFlex: 1 }
]
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 [gridRef, setGridRef] = useState(null)
const dataSource = useCallback(loadData, [])
return (
<div>
<div style={{marginBottom: 20}}>
<Button
disabled={Array.isArray(dataSource)}
onClick={() => {
gridRef.current.smoothScrollTo(500, { orientation: 'vertical', duration: 500 })
}}
>
Smooth scroll vertically to 500px (duration: 500ms)
</Button>
</div>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
style={gridStyle}
columns={columns}
sortable={false}
dataSource={dataSource}
/>
</div>
);
}
export default () => <App />
Fn({columnId, rowIndex, value})
undefined
<ReactDataGrid />
cell will be used.<ReactDataGrid />
will scroll to show the editing cell in the viewport.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 columns = [
{ name: 'id', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null)
const [dataSource, setDataSource] = useState(people)
const onEditComplete = useCallback(({ value, columnId, rowId }) => {
const data = [...dataSource];
data[rowId][columnId] = value;
setDataSource(data)
}, [dataSource])
return (
<div>
<div style={{ marginBottom: 20 }}>
<Button onClick={()=> {
gridRef.current.startEdit({ rowIndex: 2, columnId: 'name' })
}}>
Start edit row 2, column name
</Button>
</div>
<ReactDataGrid
idProperty="id"
onReady={setGridRef}
style={gridStyle}
onEditComplete={onEditComplete}
editable
columns={columns}
dataSource={dataSource}
/>
</div>
)
}
export default () => <App />
Fn(dataOrIndex)
undefined
toggleRowExpandById
.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 NumericInput from '@inovua/reactdatagrid-community/packages/NumericInput'
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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null);
const [activeIndex, setActiveIndex] = useState();
const [index, setIndex] = useState();
return (
<div>
<div style={{ marginBottom: 20 }}>
<NumericInput
style={{ width: 100 }}
value={index}
onChange={setIndex}
/>
<Button
style={{ marginLeft: 20 }}
onClick={() => {
gridRef.current.setActiveIndex(index);
}}
>
Set active index
</Button>
</div>
<Button
style={{ marginBottom: 20}}
disabled={activeIndex === undefined}
onClick={() => gridRef.current.toggleRowExpand(activeIndex)}
>
Toggle expand for active row
</Button>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
activeIndex={activeIndex}
onActiveIndexChange={setActiveIndex}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />
Fn(rowId)
undefined
toggleRowExpand
.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 NumericInput from '@inovua/reactdatagrid-community/packages/NumericInput'
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', header: 'Id', defaultVisible: false, defaultWidth: 80, type: 'number' },
{ name: 'name', header: 'Name', defaultFlex: 1 },
{ name: 'country', header: 'County', defaultFlex: 1,
render: ({ value }) => flags[value] ? flags[value] : value
},
{ name: 'city', header: 'City', defaultFlex: 1 },
{ name: 'age', header: 'Age', defaultFlex: 1, type: 'number' }
]
const App = () => {
const [gridRef, setGridRef] = useState(null);
const [activeIndex, setActiveIndex] = useState();
const [index, setIndex] = useState();
return (
<div>
<div style={{ marginBottom: 20 }}>
<NumericInput
style={{ width: 100 }}
value={index}
onChange={setIndex}
/>
<Button
style={{ marginLeft: 20 }}
onClick={() => {
gridRef.current.setActiveIndex(index);
}}
>
Set active index
</Button>
</div>
<Button
style={{ marginBottom: 20 }}
disabled={activeIndex === undefined}
onClick={() => {
const id = gridRef.current.getItemId(
gridRef.current.getItemAt(activeIndex)
);
gridRef.current.toggleRowExpandById(id);
}}
>
Toggle expand for active row
</Button>
<ReactDataGrid
onReady={setGridRef}
idProperty="id"
activeIndex={activeIndex}
onActiveIndexChange={setActiveIndex}
style={gridStyle}
rowExpandHeight={400}
renderRowDetails={renderRowDetails}
columns={columns}
dataSource={people}
/>
</div>
);
}
export default () => <App />