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
  • Save genomics-geek/4d90c307b930865a0d1b8f09a1761daa to your computer and use it in GitHub Desktop.
Save genomics-geek/4d90c307b930865a0d1b8f09a1761daa to your computer and use it in GitHub Desktop.

Revisions

  1. @cschmidli cschmidli revised this gist Jan 7, 2017. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions DataTable.ts
    Original file line number Diff line number Diff line change
    @@ -47,13 +47,13 @@ export default class DataTable extends React.Component<DataTableProps, DataTable
    }
    }

    handleClick = (e: React.MouseEvent<HTMLElement>) => {
    handlePageClick = (e: React.MouseEvent<HTMLElement>) => {
    this.setState({
    currentPage: parseInt(e.currentTarget.dataset["page"])
    })
    }

    handleIconClick = (e:React.MouseEvent<HTMLElement>) => {
    handleDirectionClick = (e:React.MouseEvent<HTMLElement>) => {
    let direction = e.currentTarget.dataset["direction"]

    let change = 0
    @@ -123,29 +123,29 @@ export default class DataTable extends React.Component<DataTableProps, DataTable
    <MenuItem
    icon="angle double left"
    data-page={1}
    onClick={this.handleClick}
    onClick={this.handlePageClick}
    />
    <MenuItem
    data-direction="LEFT"
    onClick={this.handleIconClick}
    onClick={this.handleDirectionClick}
    icon="angle left"/>
    {pageRange.map(pageIndex =>
    <MenuItem
    key={pageIndex}
    content={`${pageIndex}`}
    data-page={pageIndex}
    onClick={this.handleClick}
    onClick={this.handlePageClick}
    active={pageIndex === this.state.currentPage}
    as='a' />
    )}
    <MenuItem
    data-direction="RIGHT"
    onClick={this.handleIconClick}
    onClick={this.handleDirectionClick}
    icon="angle right"/>
    <MenuItem
    icon="angle double right"
    data-page={numberOfPages}
    onClick={this.handleClick}
    onClick={this.handlePageClick}
    />
    </Menu>
    </TableHeaderCell>
  2. @cschmidli cschmidli revised this gist Jan 7, 2017. 1 changed file with 26 additions and 33 deletions.
    59 changes: 26 additions & 33 deletions DataTable.ts
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,10 @@ import * as React from 'react';
    import * as hash from 'object-hash';
    import {
    TableProps,
    Table,
    Table,
    TableBody,
    TableCell,
    TableFooter,
    TableHeaderCell,
    TableRow,
    TableHeader,
    @@ -12,7 +15,6 @@ import {
    MenuItem
    } from 'semantic-ui-react';


    interface DataTableState {
    currentPage: number;
    rowsPerPage: number;
    @@ -102,34 +104,31 @@ export default class DataTable extends React.Component<DataTableProps, DataTable
    </TableRow>
    </TableHeader>
    }
    <Table.Body>
    <TableBody>
    {currentData.map(row =>
    <TableRow key={hash(row)}>
    {columns.map((key) =>
    <Table.Cell key={hash({ ...row, key })}>{row[key]}</Table.Cell>
    <TableCell
    key={hash({ ...row, key })}
    content={row[key]}
    />
    )}
    </TableRow>
    )}
    </Table.Body>
    <Table.Footer>
    </TableBody>
    <TableFooter>
    <TableRow>
    <Table.HeaderCell colSpan='3'>
    <TableHeaderCell {...{colSpan:3}}>
    <Menu floated='right' pagination>
    <MenuItem
    icon="angle double left"
    data-page={1}
    onClick={this.handleClick}
    />
    <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' />
    }
    icon="angle left"/>
    {pageRange.map(pageIndex =>
    <MenuItem
    key={pageIndex}
    @@ -139,25 +138,19 @@ export default class DataTable extends React.Component<DataTableProps, DataTable
    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>
    icon="angle right"/>
    <MenuItem
    icon="angle double right"
    data-page={numberOfPages}
    onClick={this.handleClick}
    />
    </Menu>
    </Table.HeaderCell>
    </TableHeaderCell>
    </TableRow>
    </Table.Footer>
    </TableFooter>
    </Table>
    </div>
    );
  3. @cschmidli cschmidli revised this gist Jan 7, 2017. 1 changed file with 57 additions and 19 deletions.
    76 changes: 57 additions & 19 deletions ExampleUsage.ts
    Original file line number Diff line number Diff line change
    @@ -1,25 +1,63 @@
    import * as React from 'react';

    import { Grid, Container, GridColumn } from 'semantic-ui-react';
    import DataTable from '../components/DataTable';


    interface PaginationExampleState {
    data: dataType[]
    }

    interface dataType {
    value1: number,
    value2: number
    }

    let data: dataType[] = []
    for (var index = 0; index < 1000; index++) {
    data.push({
    value1: Math.random(),
    value2: Math.random()
    })
    }
    export default class PaginationExample extends React.Component<any, PaginationExampleState> {


    constructor(props) {
    super(props);

    let data: dataType[] = []
    for (var index = 0; index < 1000; index++) {
    data.push({
    value1: Math.random(),
    value2: Math.random()
    })
    }

    this.state = {
    data: data
    }
    }

    <DataTable
    data={data}
    tableProps={{
    compact: true,
    basic: "very",
    striped: true,
    size: "small"
    }}
    header
    rowsPerPage={20}
    columnHeader={["value1", "value2"]}
    />
    render() {
    return (
    <div>
    <Container>
    <Grid>
    <Grid.Row>
    <GridColumn
    width="6"
    >
    <DataTable
    data={this.state.data}
    tableProps={{
    compact: true,
    basic: "very",
    striped: true,
    size: "small"
    }}
    header
    rowsPerPage={20}
    columnHeader={["value1", "value2"]}
    />
    </GridColumn>
    </Grid.Row>
    </Grid>
    </Container>
    </div>
    )
    }
    }
  4. @cschmidli cschmidli created this gist Jan 7, 2017.
    165 changes: 165 additions & 0 deletions DataTable.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,165 @@

    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>
    );
    }
    }
    25 changes: 25 additions & 0 deletions ExampleUsage.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    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"]}
    />