Reputation: 18451
I´m trying to build a JSON configurable data table using the Facebook´s fixed-data-table. I´ve come to my first code as:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Icon } from 'semantic-ui-react';
import { Table, Column, Cell } from 'fixed-data-table';
const DateCell = ({rowIndex, data, col, ...props}) => (
<Cell {...props}>
{data.getObjectAt(rowIndex)[col].toLocaleString()}
</Cell>
);
const LinkCell = ({rowIndex, data, col, ...props}) => (
<Cell {...props}>
<a href="#">{data.getObjectAt(rowIndex)[col]}</a>
</Cell>
);
const TextCell = ({rowIndex, data, col, ...props}) => (
<Cell {...props}>
{data.getObjectAt(rowIndex)[col]}
</Cell>
);
const NumericCell = ({rowIndex, data, col, ...props}) => (
<Cell {...props}>
{data.getObjectAt(rowIndex)[col]}
</Cell>
);
const BooleanCell = ({rowIndex, data, col, ...props}) => (
<Cell {...props}>
{data.getObjectAt(rowIndex)[col] ? <Icon name='checkmark' color='green' /> : <Icon name='remove' color='red' />}
</Cell>
);
class DataTable extends Component {
state = {
schema: this.props.schema,
data: this.props.data,
}
getCells = (schema, data) => {
let columns = [];
schema.columns.map((column, index) => {
let cell = (<TextCell></TextCell>);
let key = column.field + index;
if (column.type === 'string') {
cell = (<TextCell
data={this.state.data}
col={column.field}
/>);
}
if (column.type === 'integer') {
cell = (<NumericCell
data={this.state.data}
col={column.field}
/>);
}
if (column.type === 'boolean') {
cell = (<BooleanCell
data={this.state.data}
col={column.field}
/>);
}
let col = (<Column
header={column.title}
cell={cell}
width={100}
/>);
columns.push(col);
return;
});
return columns;
}
render() {
let schema = {
"columns": [
{
"title": "Name",
"field": "name",
"type": "string",
},
{
"title": "EIN",
"field": "ein",
"type": "string",
},
{
"title": "Active",
"field": "isactive",
"type": "boolean",
}
],
"edit": true,
"delete": true,
"sort": true
};
let data = [
{
name: 'Test1',
ein: '1234',
isactive: true
},
{
name: 'Test2',
ein: '123',
isactive: true
},
{
name: 'Test3',
ein: '12345',
isactive: true
},
];
let columns = this.getCells(schema, data);
return (
<Table
rowHeight={50}
schemaHeight={50}
maxHeight={100}
width={1000}
height={500}
rowsCount={data.length}
{...this.props}>
{columns}
</Table>
);
}
}
export default DataTable;
When running I´m getting the following error:
TypeError: data.getObjectAt is not a function
TextCell
D:\\WORKSPACE\test\src\components\shared\DataTable.js:42
39 |
40 | const TextCell = ({rowIndex, data, col, ...props}) => (
41 | <Cell {...props}>
**> 42 | {data.getObjectAt(rowIndex)[col]}**
43 | </Cell>
44 | );
45 |
I´ve tried different JSON structures with no luck. The data and schema are loaded accordingly.
Upvotes: 2
Views: 517
Reputation: 1379
This literally takes some time to wrap ones mind around initially.
I will describe it using references to code in 'fixed-data-table-2'.
The data list when used in the table is wrapped in an object that consist of the data list and a data list filter array. Your list data will only show up if you have wrapped it as a DataListWrapper object along with a filter array where every entry of the filter array is a boolean specifying if the corresponding list row will be visible (true) or hidden (false).
See the class BuildObjectDataListStore. There is a method 'getObjectAt' in there which when called retrieves list row columns based on the input variable name. For example
var {my_id} = list.getObjectAt(44);
means that if the list row at index 44 contains a column named 'my_id' then the value of that column will end up in your my_id variable. This works only with 'underscore' as delimiter in column names, so any lists made up of columns such as "my-id" must be converted to "my_id" before use in 'fixed-data-table'. There exists a neat conversion table procedure in BuildObjectDataListStore for that.
Here is how you wrap a plain list array 'myList' into an object that fixed-data-table' can render:
this.dataList = new BuildObjectDataListStore(myList);
Then this object is wrapped into an object along with a filter array:
this.filteredDataList = new DataListWrapper(this.filter, this.dataList);
And there you have it; DataListWrapper is a recognized list format that 'fixed-data-table' can render.
Nowadays people use 'fixed-data-table-2' which enjoys continued support by Schrödinger, Inc. The earlier 'fixed-data-table' is abandoned as a public component.
Evolving from the foundations of fixed-data-table, the power of fixed-data-table-2 is at least twofold;
So for some applications this list component can be spot on. A drawback can be the initial learning curve of the mentioned wrapping principles and column renderer methods.
Upvotes: 2