Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, {Component, PropTypes} from 'react';
- import Head from './TableComponents/Head';
- import Pagination from './TableComponents/Pagination';
- import Row from './TableComponents/Row';
- import SearchComponent from './TableComponents/SearchComponent';
- export default class SimpleTable extends Component {
- constructor(props){
- super(props);
- this.state = {
- children: this._setChildren(),
- // just loaded, not set
- current_sort: undefined,
- // the array to tabulate
- data: props.data,
- // ascending at load
- descending: false,
- // is there pagination?
- pagination: props.pagination,
- // we just loaded the page so it's 1
- pagination_current_page: props.current_page || 1,
- // number of row to show (only matters if pagination.) Defaults to 25.
- pagination_items: props.pagination_items || 25,
- // the index of the first item to show (pagination only)
- pagination_range_low: 0,
- // the last index to show based on pagination preferences
- pagination_range_high: props.pagination_items ? props.pagination_items - 1 : 25,
- // value for the placeholder
- placeholder: props.placeholder || '',
- presearch_data: undefined,
- // the schema to read from
- schema: props.schema,
- // will there be a search function
- search: false,
- total_length: props.data.length
- }
- }
- componentWillReceiveProps(nextProps){
- const {data, presearch_data} = this.state;
- nextProps.data !== data
- ? this._changeCurrentPage(1)
- : null
- this.setState({
- children: this._setChildren(),
- data: nextProps.data,
- pagination: nextProps.pagination,
- pagination_items: nextProps.pagination_items || 25,
- // if presearch_data hasn't been populated, populate. Else, do not touch.
- presearch_data: !presearch_data || presearch_data.length === 0 || (data !== nextProps.data) ? nextProps.data : presearch_data,
- schema: nextProps.schema,
- search: nextProps.search,
- total_length: nextProps.data.length
- })
- }
- // 'no' is the page number that was sent from pagination
- _changeCurrentPage(no){
- // how many to show at a time
- const {pagination_items} = this.state;
- // first to show based on which page. subtract one because indices start at zero
- const pagination_range_low = pagination_items * (no - 1);
- // show x number past the first one
- const pagination_range_high = (pagination_range_low + pagination_items - 1 );
- this.setState({
- pagination_current_page: no,
- pagination_range_low,
- pagination_range_high
- })
- }
- _setChildren(){
- // React returns one child as an obj, multiple as an array. It always needs to be an array
- const {children} = this.props;
- if (children && !Array.isArray(children)) {
- return [children]
- } else {
- return children
- }
- }
- _setSort(key){
- let data = this.state.data;
- //if we're already sorting by this key and user clicked that header cell again, we're changing the sort order
- const descending = this.state.sort_by === key && !this.state.descending;
- // sort by the key. if the values a number, do nothing. If it's a string, equalize with lowercase
- const new_data = data.sort(function (a, b) {
- var key_a = isNaN(a[key]) ? a[key].toLowerCase() : a[key];
- var key_b = isNaN(b[key]) ? b[key].toLowerCase() : b[key];
- if (descending){
- if (key_a < key_b) return -1;
- if (key_a > key_b) return 1;
- return 0;
- } else {
- if (key_a > key_b) return -1;
- if (key_a < key_b) return 1;
- return 0;
- }
- });
- //data equals the sorted data, sort-by key and order
- this.setState({
- data: new_data,
- sort_by: key,
- descending: descending,
- });
- }
- _updateData(data){
- const {pagination_items} = this.state;
- this.setState({
- data,
- pagination_current_page: 1,
- pagination_range_low: 0,
- // the last index to show based on pagination preferences
- pagination_range_high: pagination_items ? pagination_items - 1 : 25,
- total_length: data.length,
- })
- }
- render(){
- const {data, pagination, search} = this.state;
- return(
- <div className="simple-table">
- {search && this._renderSearch()}
- <table>
- {this._renderCols()}
- {this._renderHead()}
- {this._renderRows()}
- </table>
- {
- pagination && data.length > 0
- && this._renderPagination()
- }
- </div>
- )
- }
- _renderCols(){
- const {schema} = this.state;
- // set a class in the schema if you need to do something fancy, otherwise set the width if it's provided
- return (
- <colgroup>
- {
- schema.map(item =>{
- const colclass = item.class || '';
- const colwidth = item.width ? {width: `${item.width}%`} : {};
- return <col className={colclass} style={colwidth}></col>
- })
- }
- </colgroup>
- )
- }
- _renderHead(){
- // needs to know whether we're sorting descending, the schema, the sort function for click event, and which row
- //we're sorting by
- const {descending, schema, sort_by} = this.state;
- return (
- <Head
- descending={descending}
- schema={schema}
- set_sort={this._setSort.bind(this)}
- sort_by={sort_by}
- />
- )
- }
- _renderPagination(){
- // these are discussed in the constructor
- const {
- pagination_current_page,
- pagination_items,
- pagination_range_low,
- pagination_range_high,
- total_length
- } = this.state;
- return (
- <Pagination
- current = {pagination_current_page}
- items = {pagination_items}
- range_low = {pagination_range_low}
- range_high = {pagination_range_high}
- SetPage = {this._changeCurrentPage.bind(this)}
- total_length = {total_length}
- />
- )
- }
- _renderRows(){
- const {children, data, pagination, pagination_range_low, pagination_range_high, schema} = this.state;
- // if the row falls between the index ranges that we're showing, render it.
- return (
- <tbody>
- {
- data.map((row,idx) => {
- if ( (pagination && idx >= pagination_range_low && idx <= pagination_range_high) || !pagination ) {
- return <Row
- {...this.props}
- children={children}
- index={idx}
- row_data={row}
- schema={schema}
- />
- }
- })
- }
- </tbody>
- )
- }
- _renderSearch(){
- const {data, placeholder, presearch_data, schema} = this.state;
- return (
- <SearchComponent placeholder={placeholder} data={data} presearch_data={presearch_data} schema={schema} updateData={this._updateData.bind(this)} />
- )
- }
- }
- SimpleTable.propTypes = {
- current_sort: PropTypes.string,
- data: PropTypes.array,
- descending: PropTypes.bool,
- pagination: PropTypes.bool,
- pagination_current_page: PropTypes.number,
- pagination_items: PropTypes.number,
- pagination_range_low: PropTypes.number,
- pagination_range_high: PropTypes.number,
- placeholder: PropTypes.string,
- presearch_data: PropTypes.array,
- schema: PropTypes.array,
- search: PropTypes.bool,
- total_length: PropTypes.number
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement