Add support for sorting to both tables

This commit is contained in:
Luka Murn 2017-08-21 15:36:22 +02:00
parent abcd74e681
commit f4f0cd234f
3 changed files with 142 additions and 47 deletions

View file

@ -11,6 +11,53 @@ class DataGrid extends Component {
this.transformColumns();
this.setupDefaultProps();
// Store the original rows array, and make a copy that
// can be used for modifying eg.filtering, sorting
this.state = {
originalRows: this.props.data,
rows: this.props.data.slice(0)
};
}
setupDefaultProps() {
// Setup the default props if they're not provided
if ('rowGetter' in this.props) {
this._rowGetter = this.props.rowGetter;
} else {
this._rowGetter = ((i) => this.state.rows[i]);
}
this._rowGetter = this._rowGetter.bind(this);
if ('rowsCount' in this.props) {
this._rowsCount = this.props.rowsCount;
} else {
this._rowsCount = this.props.data.length;
}
if ('onGridSort' in this.props) {
this._onGridSort = this.props.onGridSort;
} else {
this._onGridSort = ((sortColumn, sortDirection) => {
const comparer = (a, b) => {
if (sortDirection === 'ASC') {
return (a[sortColumn] > b[sortColumn]) ? 1 : -1;
} else if (sortDirection === 'DESC') {
return (a[sortColumn] < b[sortColumn]) ? 1 : -1;
}
return 0;
};
let rows;
if (sortDirection === 'NONE') {
rows = this.state.originalRows.slice(0);
} else {
rows = this.state.rows.sort(comparer);
}
this.setState({ rows });
});
}
this._onGridSort = this._onGridSort.bind(this);
}
transformColumns() {
@ -18,41 +65,21 @@ class DataGrid extends Component {
// ReactDataGrid-compatible representation
this._columns =
this.props.columns
.sort((a, b) => b.position - a.position)
.filter((col) => col.visible)
.map((col) => {
return {
key: col.textId,
name: col.name,
locked: col.locked
};
});
}
setupDefaultProps() {
// Setup the default props if they're not provided
const self = this;
if ('rowGetter' in this.props) {
this._rowGetter = this.props.rowGetter;
} else {
this._rowGetter = function(i) {
return this.props.data[i];
}.bind(this);
}
if ('rowsCount' in this.props) {
this._rowsCount = this.props.rowsCount;
} else {
this._rowsCount = this.props.data.length;
}
.sort((a, b) => a.position - b.position)
.filter((col) => (!('visible' in col) || col.visible))
.map((col) => ({
key: col.textId,
name: col.name,
locked: col.locked,
sortable: col.sortable
}));
}
cleanProps() {
// Remove additional props from the props value
const cleanProps = {...this.props};
delete cleanProps.columns;
delete cleanProps.rowGetter;
delete cleanProps.rowsCount;
const {
columns, rowGetter, rowsCount, ...cleanProps
} = this.props;
return cleanProps;
}
@ -62,6 +89,7 @@ class DataGrid extends Component {
columns={this._columns}
rowGetter={this._rowGetter}
rowsCount={this._rowsCount}
onGridSort={this._onGridSort}
{...this.cleanProps()}
/>
);
@ -69,6 +97,22 @@ class DataGrid extends Component {
}
DataGrid.propTypes = {
columns: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
isKey: PropTypes.bool.isRequired,
textId: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
position: PropTypes.number.isRequired,
visible: PropTypes.bool,
sortable: PropTypes.bool,
locked: PropTypes.bool
})
).isRequired,
data: PropTypes.arrayOf(PropTypes.object).isRequired,
rowGetter: PropTypes.func,
rowsCount: PropTypes.number,
onGridSort: PropTypes.func
};
export default DataGrid;

View file

@ -3,6 +3,15 @@ import PropTypes from "prop-types";
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
class DataTable extends Component {
static cleanColumnAttributes(col) {
// Remove additional attributes from the columns
const {
id, isKey, textId, name, position, visible,
sortable, locked, ...cleanCol
} = col;
return cleanCol;
}
constructor(props) {
super(props);
this.cleanProps = this.cleanProps.bind(this);
@ -11,25 +20,25 @@ class DataTable extends Component {
cleanProps() {
// Remove additional props from the props value
const cleanProps = {...this.props};
delete cleanProps.columns;
const {columns, ...cleanProps} = this.props;
return cleanProps;
}
displayHeader() {
const orderedCols = [...this.props.columns].sort((a, b) => b.position - a.position);
return orderedCols.map((col) => {
return (
<TableHeaderColumn
key={col.id}
dataField={col.textId}
isKey={col.isKey}
hidden={!col.visible}
>
{col.name}
</TableHeaderColumn>
);
});
const orderedCols = [...this.props.columns].sort((a, b) => a.position - b.position);
return orderedCols.map((col) =>
<TableHeaderColumn
key={col.id}
dataField={col.textId}
isKey={col.isKey}
hidden={('visible' in col) && !col.visible}
dataSort={col.sortable}
{...DataTable.cleanColumnAttributes(col)}
>
{col.name}
</TableHeaderColumn>
);
}
render() {
@ -53,7 +62,8 @@ DataTable.propTypes = {
sortable: PropTypes.bool,
locked: PropTypes.bool
})
).isRequired
).isRequired,
data: PropTypes.arrayOf(PropTypes.object).isRequired
};
export default DataTable;

View file

@ -7,3 +7,44 @@ body {
font-family: "Open Sans",Arial,Helvetica,sans-serif;
font-size: 13px;
}
.react-bs-table {
thead {
background-color: #909088;
> tr > th,
>tr > td {
padding: 6px;
padding-right: 30px;
}
> tr > th {
border-bottom: 2px solid #ddd;
border-bottom-width: 0;
border-left: 2px solid #fcfcfc;
color: #fff;
font-weight: normal;
vertical-align: bottom;
&:first-child {
border-left: none;
}
}
}
td, th {
box-sizing: content-box;
}
td {
overflow-wrap: break-word;
text-overflow: ellipsis;
word-break: break-word;
}
.sorting_desc,
.sorting_asc {
background-color: #37a0d9;
}
}