mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-06-28 13:10:03 +00:00
implement sort context
This commit is contained in:
88
packages/react-bootstrap-table2/src/contexts/sort-context.js
vendored
Normal file
88
packages/react-bootstrap-table2/src/contexts/sort-context.js
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Const from '../const';
|
||||
import { sort, nextOrder } from '../store/sort';
|
||||
import remoteResolver from '../props-resolver/remote-resolver';
|
||||
|
||||
export default () => {
|
||||
const SortContext = React.createContext();
|
||||
|
||||
class SortProvider extends remoteResolver(React.Component) {
|
||||
static propTypes = {
|
||||
columns: PropTypes.array.isRequired,
|
||||
defaultSorted: PropTypes.arrayOf(PropTypes.shape({
|
||||
dataField: PropTypes.string.isRequired,
|
||||
order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired
|
||||
})),
|
||||
defaultSortDirection: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC])
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
let sortOrder;
|
||||
let sortColumn;
|
||||
const { columns, defaultSorted, defaultSortDirection } = props;
|
||||
|
||||
if (defaultSorted && defaultSorted.length > 0) {
|
||||
const sortField = defaultSorted[0].dataField;
|
||||
sortOrder = defaultSorted[0].order || defaultSortDirection;
|
||||
const sortColumns = columns.filter(col => col.dataField === sortField);
|
||||
if (sortColumns.length > 0) {
|
||||
sortColumn = sortColumns[0];
|
||||
|
||||
if (sortColumn.onSort) {
|
||||
sortColumn.onSort(sortField, sortOrder);
|
||||
}
|
||||
|
||||
if (this.isRemoteSort() || this.isRemotePagination()) {
|
||||
this.handleSortChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.state = { sortOrder, sortColumn };
|
||||
}
|
||||
|
||||
handleSort = (column) => {
|
||||
const sortOrder = nextOrder(column, this.state, this.props.defaultSortDirection);
|
||||
|
||||
if (column.onSort) {
|
||||
column.onSort(column.dataField, sortOrder);
|
||||
}
|
||||
|
||||
if (this.isRemoteSort() || this.isRemotePagination()) {
|
||||
this.handleSortChange();
|
||||
} else {
|
||||
this.setState(() => ({
|
||||
sortOrder,
|
||||
sortColumn: column
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let { data } = this.props;
|
||||
const { sortOrder, sortColumn } = this.state;
|
||||
if (!this.isRemoteSort() && !this.isRemotePagination() && sortColumn) {
|
||||
data = sort(data, sortOrder, sortColumn);
|
||||
}
|
||||
|
||||
return (
|
||||
<SortContext.Provider
|
||||
value={ {
|
||||
data,
|
||||
sortOrder,
|
||||
onSort: this.handleSort,
|
||||
sortField: sortColumn ? sortColumn.dataField : null
|
||||
} }
|
||||
>
|
||||
{ this.props.children }
|
||||
</SortContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
return {
|
||||
Provider: SortProvider,
|
||||
Consumer: SortContext.Consumer
|
||||
};
|
||||
};
|
||||
@@ -1,81 +0,0 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import remoteResolver from '../props-resolver/remote-resolver';
|
||||
|
||||
export default Base =>
|
||||
class SortWrapper extends remoteResolver(Component) {
|
||||
static propTypes = {
|
||||
store: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleSort = this.handleSort.bind(this);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { columns, defaultSorted, defaultSortDirection, store } = this.props;
|
||||
// defaultSorted is an array, it's ready to use as multi / single sort
|
||||
// when we start to support multi sort, please update following code to use array.forEach
|
||||
if (defaultSorted && defaultSorted.length > 0) {
|
||||
const dataField = defaultSorted[0].dataField;
|
||||
const order = defaultSorted[0].order;
|
||||
const column = columns.filter(col => col.dataField === dataField);
|
||||
if (column.length > 0) {
|
||||
store.setSort(column[0], order, defaultSortDirection);
|
||||
|
||||
if (column[0].onSort) {
|
||||
column[0].onSort(store.sortField, store.sortOrder);
|
||||
}
|
||||
|
||||
if (this.isRemoteSort() || this.isRemotePagination()) {
|
||||
this.handleSortChange();
|
||||
} else {
|
||||
store.sortBy(column[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (!this.isRemoteSort() && !this.isRemotePagination()) {
|
||||
let sortedColumn;
|
||||
for (let i = 0; i < nextProps.columns.length; i += 1) {
|
||||
if (nextProps.columns[i].dataField === nextProps.store.sortField) {
|
||||
sortedColumn = nextProps.columns[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sortedColumn && sortedColumn.sort) {
|
||||
nextProps.store.sortBy(sortedColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleSort(column) {
|
||||
const { store } = this.props;
|
||||
store.setSort(column, undefined, this.props.defaultSortDirection);
|
||||
|
||||
if (column.onSort) {
|
||||
column.onSort(store.sortField, store.sortOrder);
|
||||
}
|
||||
|
||||
if (this.isRemoteSort() || this.isRemotePagination()) {
|
||||
this.handleSortChange();
|
||||
} else {
|
||||
store.sortBy(column);
|
||||
this.forceUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Base
|
||||
{ ...this.props }
|
||||
onSort={ this.handleSort }
|
||||
data={ this.props.store.data }
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -14,17 +14,17 @@ function comparator(a, b) {
|
||||
return result;
|
||||
}
|
||||
|
||||
export const sort = ({ data, sortOrder, sortField }) => (sortFunc) => {
|
||||
export const sort = (data, sortOrder, { dataField, sortFunc }) => {
|
||||
const _data = [...data];
|
||||
_data.sort((a, b) => {
|
||||
let result;
|
||||
let valueA = _.get(a, sortField);
|
||||
let valueB = _.get(b, sortField);
|
||||
let valueA = _.get(a, dataField);
|
||||
let valueB = _.get(b, dataField);
|
||||
valueA = _.isDefined(valueA) ? valueA : '';
|
||||
valueB = _.isDefined(valueB) ? valueB : '';
|
||||
|
||||
if (sortFunc) {
|
||||
result = sortFunc(valueA, valueB, sortOrder, sortField);
|
||||
result = sortFunc(valueA, valueB, sortOrder, dataField);
|
||||
} else {
|
||||
if (sortOrder === Const.SORT_DESC) {
|
||||
result = comparator(valueA, valueB);
|
||||
@@ -37,11 +37,11 @@ export const sort = ({ data, sortOrder, sortField }) => (sortFunc) => {
|
||||
return _data;
|
||||
};
|
||||
|
||||
export const nextOrder = store => (field, order, defaultOrder = Const.SORT_DESC) => {
|
||||
if (order) return order;
|
||||
|
||||
if (field !== store.sortField) {
|
||||
return defaultOrder;
|
||||
}
|
||||
return store.sortOrder === Const.SORT_DESC ? Const.SORT_ASC : Const.SORT_DESC;
|
||||
export const nextOrder = (
|
||||
currentSortColumn,
|
||||
{ sortOrder, sortColumn },
|
||||
defaultOrder = Const.SORT_DESC
|
||||
) => {
|
||||
if (!sortColumn || currentSortColumn.dataField !== sortColumn.dataField) return defaultOrder;
|
||||
return sortOrder === Const.SORT_DESC ? Const.SORT_ASC : Const.SORT_DESC;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user