Skip to content

Instantly share code, notes, and snippets.

@genomics-geek
Forked from cschmidli/DataTable.ts
Created August 18, 2017 13:39
Show Gist options
  • Select an option

  • Save genomics-geek/4d90c307b930865a0d1b8f09a1761daa to your computer and use it in GitHub Desktop.

Select an option

Save genomics-geek/4d90c307b930865a0d1b8f09a1761daa to your computer and use it in GitHub Desktop.
Semantic UI Data Table Component
import * as React from 'react';
import * as hash from 'object-hash';
import {
TableProps,
Table,
TableHeaderCell,
TableRow,
TableHeader,
Menu,
Icon,
MenuItem
} from 'semantic-ui-react';
interface DataTableState {
currentPage: number;
rowsPerPage: number;
numberOfPages: number;
columns: string[];
}
interface DataTableProps extends TableProps {
data: any[];
rowsPerPage?: number;
tableProps?: TableProps;
header?: boolean;
columnHeader?:string[];
}
export default class DataTable extends React.Component<DataTableProps, DataTableState> {
constructor(props: DataTableProps) {
super(props);
const rowsPerPage = props.rowsPerPage || 5;
const numberOfPages = Math.ceil(props.data.length / rowsPerPage)
const columns = props.columnHeader || Object.keys(props.data[0] || [])
this.state = {
currentPage: 1,
rowsPerPage: rowsPerPage,
numberOfPages: numberOfPages,
columns: columns
}
}
handleClick = (e: React.MouseEvent<HTMLElement>) => {
this.setState({
currentPage: parseInt(e.currentTarget.dataset["page"])
})
}
handleIconClick = (e:React.MouseEvent<HTMLElement>) => {
let direction = e.currentTarget.dataset["direction"]
let change = 0
if (direction === "LEFT" && this.state.currentPage > 1) {
change = -1
} else if (direction === "RIGHT" && this.state.currentPage < this.state.numberOfPages) {
change = 1
}
if (change !== 0) {
this.setState({
currentPage: this.state.currentPage += change
})
}
}
render() {
const {data} = this.props;
const {currentPage, rowsPerPage, numberOfPages, columns} = this.state;
//slice current data set (more filters could be added, and also sorting)
const currentData = data.slice((currentPage - 1) * rowsPerPage, currentPage * rowsPerPage);
//define start page
let startPage;
if (numberOfPages <= 3 || this.state.currentPage === 1) {
startPage = 1
} else if (this.state.currentPage === numberOfPages) {
startPage = this.state.currentPage - 2;
} else {
startPage = this.state.currentPage - 1;
}
let pageRange: number[] = Array.from(new Array(Math.min(3, numberOfPages)), (x, i) => i + startPage)
return (
<div>
<Table {...this.props.tableProps}>
{this.props.header &&
<TableHeader>
<TableRow>
{columns.map(key =>
<TableHeaderCell key={key}>{key}</TableHeaderCell>
)}
</TableRow>
</TableHeader>
}
<Table.Body>
{currentData.map(row =>
<TableRow key={hash(row)}>
{columns.map((key) =>
<Table.Cell key={hash({ ...row, key })}>{row[key]}</Table.Cell>
)}
</TableRow>
)}
</Table.Body>
<Table.Footer>
<TableRow>
<Table.HeaderCell colSpan='3'>
<Menu floated='right' pagination>
<MenuItem
data-direction="LEFT"
onClick={this.handleIconClick}
as='a'
icon>
<Icon name='left chevron' />
</MenuItem>
{pageRange[0] !== 1 &&
<MenuItem
key={"First"}
content={`First`}
data-page={1}
onClick={this.handleClick}
as='a' />
}
{pageRange.map(pageIndex =>
<MenuItem
key={pageIndex}
content={`${pageIndex}`}
data-page={pageIndex}
onClick={this.handleClick}
active={pageIndex === this.state.currentPage}
as='a' />
)}
{pageRange[pageRange.length-1] !== numberOfPages &&
<MenuItem
key={"Last"}
content={`Last`}
data-page={numberOfPages}
onClick={this.handleClick}
as='a' />
}
<MenuItem
data-direction="RIGHT"
onClick={this.handleIconClick}
as='a'
icon>
<Icon name='right chevron' />
</MenuItem>
</Menu>
</Table.HeaderCell>
</TableRow>
</Table.Footer>
</Table>
</div>
);
}
}
interface dataType {
value1: number,
value2: number
}
let data: dataType[] = []
for (var index = 0; index < 1000; index++) {
data.push({
value1: Math.random(),
value2: Math.random()
})
}
<DataTable
data={data}
tableProps={{
compact: true,
basic: "very",
striped: true,
size: "small"
}}
header
rowsPerPage={20}
columnHeader={["value1", "value2"]}
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment