Compare commits

...

9 Commits

Author SHA1 Message Date
AllenFang
7d7688582b Publish
- react-bootstrap-table2-filter@0.3.1
2018-07-30 23:27:23 +08:00
Allen
e26065b116 Merge pull request #440 from react-bootstrap-table/develop
20180730 release
2018-07-30 23:16:26 +08:00
Benny Johnson
6522f6d964 Commented out a check which caused the date filter to not update the (#425)
table when the date or date comparator were cleared

Modified applyFilter in date.js so that it doesn't try to parse an
Invalid Date. It was parsing an empty string, which caused it to pass
through an invalid date to onFilter, and this wasn't being checked for
properly by the onFilter function. It now checks for the empty string
and passes in null, which is what the onFilter function was actually
checking for
2018-07-25 11:20:35 +08:00
Allen
ecaf439e66 Merge pull request #420 from nthgol/patch-1
import numberFilter in numberFilter example
2018-07-19 10:15:57 +08:00
Nathan
90d03676ad import numberFilter in numberFilter example 2018-07-16 18:06:51 -04:00
AllenFang
2585a62697 Publish
- react-bootstrap-table2-example@0.1.11
 - react-bootstrap-table2-paginator@0.1.6
 - react-bootstrap-table-next@0.1.15
2018-07-15 16:08:59 +08:00
Allen
6afe58a081 Merge pull request #415 from react-bootstrap-table/develop
20180715 release
2018-07-15 16:02:47 +08:00
Allen
6f5bd1a13d fix #394 (#414) 2018-07-15 14:43:29 +08:00
Allen
85a9ab72af fix #402 (#412) 2018-07-15 14:18:21 +08:00
17 changed files with 180 additions and 40 deletions

View File

@@ -18,6 +18,7 @@
* [id](#id)
* [classes](#classes)
* [wrapperClasses](#wrapperClasses)
* [headerClasses](#headerClasses)
* [cellEdit](#cellEdit)
* [selectRow](#selectRow)
* [rowStyle](#rowStyle)
@@ -111,6 +112,10 @@ Customize class on `table` element.
### <a name='wrapperClasses'>wrapperClasses - [String]</a>
Customize class on the outer element which wrap up the `table` element.
### <a name='headerClasses'>headerClasses - [String]</a>
Customize class on the header row(`tr`).
### <a name='cellEdit'>cellEdit - [Object]</a>
Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail.

View File

@@ -0,0 +1,52 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator();
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price'
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price'
}];
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
headerClasses="header-class"
/>
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
headerClasses="header-class"
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-example",
"version": "0.1.10",
"version": "0.1.11",
"description": "",
"main": "index.js",
"private": true,

View File

@@ -33,6 +33,7 @@ import HeaderColumnEventTable from 'examples/header-columns/column-event-table';
import HeaderColumnClassTable from 'examples/header-columns/column-class-table';
import HeaderColumnStyleTable from 'examples/header-columns/column-style-table';
import HeaderColumnAttrsTable from 'examples/header-columns/column-attrs-table';
import HeaderClassTable from 'examples/header-columns/header-class-table';
// column filter
import TextFilter from 'examples/column-filter/text-filter';
@@ -165,7 +166,8 @@ storiesOf('Work on Header Columns', module)
.add('Column Event', () => <HeaderColumnEventTable />)
.add('Customize Column Class', () => <HeaderColumnClassTable />)
.add('Customize Column Style', () => <HeaderColumnStyleTable />)
.add('Customize Column HTML attribute', () => <HeaderColumnAttrsTable />);
.add('Customize Column HTML attribute', () => <HeaderColumnAttrsTable />)
.add('Header Class', () => <HeaderClassTable />);
storiesOf('Column Filter', module)
.add('Text Filter', () => <TextFilter />)

View File

@@ -9,4 +9,8 @@
.demo-row-odd {
background-color: $green-lighten-4;
}
.header-class {
background-color: $green-lighten-4;
}

View File

@@ -131,7 +131,7 @@ const columns = [..., {
Numner filter is same as other filter, you can custom the number filter via `numberFilter` factory function:
```js
import filterFactory, { selectFilter, Comparator } from 'react-bootstrap-table2-filter';
import filterFactory, { selectFilter, Comparator, numberFilter } from 'react-bootstrap-table2-filter';
// omit...
const numberFilter = numberFilter({
@@ -240,4 +240,4 @@ Following properties is valid in `FILTER_TYPES`:
* TEXT
* SELECT
* NUMBER
* DATE
* DATE

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-filter",
"version": "0.3.0",
"version": "0.3.1",
"description": "it's a column filter addon for react-bootstrap-table2",
"main": "./lib/index.js",
"repository": {

View File

@@ -93,12 +93,16 @@ class DateFilter extends Component {
}
applyFilter(value, comparator) {
if (!comparator || !value) {
return;
}
// if (!comparator || !value) {
// return;
// }
const { column, onFilter, delay } = this.props;
const execute = () => {
const date = typeof value !== 'object' ? new Date(value) : value;
// Incoming value should always be a string, and the defaultDate
// above is implemented as an empty string, so we can just check for that.
// instead of parsing an invalid Date. The filter function will interpret
// null as an empty date field
const date = value === '' ? null : new Date(value);
onFilter(column, FILTER_TYPE.DATE)({ date, comparator });
};
if (delay) {

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-paginator",
"version": "0.1.5",
"version": "0.1.6",
"description": "it's the pagination addon for react-bootstrap-table2",
"main": "./lib/index.js",
"repository": {

View File

@@ -1,12 +1,39 @@
/* eslint no-param-reassign: 0 */
const getNormalizedPage = (
page,
pageStartIndex
) => {
const offset = Math.abs(1 - pageStartIndex);
return page + offset;
};
const endIndex = (
page,
sizePerPage,
pageStartIndex
) => (getNormalizedPage(page, pageStartIndex) * sizePerPage) - 1;
const startIndex = (
end,
sizePerPage,
) => end - (sizePerPage - 1);
export const alignPage = (store, pageStartIndex, sizePerPage) => {
const end = endIndex(store.page, sizePerPage, pageStartIndex);
const dataSize = store.data.length;
if (end - 1 > dataSize) {
return pageStartIndex;
}
return store.page;
};
export const getByCurrPage = (store, pageStartIndex) => {
const dataSize = store.data.length;
if (!dataSize) return [];
const getNormalizedPage = () => {
const offset = Math.abs(1 - pageStartIndex);
return store.page + offset;
};
const end = (getNormalizedPage() * store.sizePerPage) - 1;
const start = end - (store.sizePerPage - 1);
const end = endIndex(store.page, store.sizePerPage, pageStartIndex);
const start = startIndex(end, store.sizePerPage);
const result = [];
for (let i = start; i <= end; i += 1) {

View File

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import Const from './const';
import Pagination from './pagination';
import { getByCurrPage } from './page';
import { getByCurrPage, alignPage } from './page';
export default (Base, {
remoteResolver
@@ -49,17 +49,21 @@ export default (Base, {
componentWillReceiveProps(nextProps) {
let needNewState = false;
let { currPage, currSizePerPage } = this.state;
const { page, sizePerPage, pageStartIndex, onPageChange } = nextProps.pagination.options;
const { page, sizePerPage, onPageChange } = nextProps.pagination.options;
const pageStartIndex = typeof nextProps.pagination.options.pageStartIndex !== 'undefined' ?
nextProps.pagination.options.pageStartIndex : Const.PAGE_START_INDEX;
if (typeof page !== 'undefined' && currPage !== page) { // user defined page
currPage = page;
needNewState = true;
} else if (nextProps.isDataChanged) {
currPage = alignPage(this.props.store, pageStartIndex, currSizePerPage);
needNewState = true;
}
if (typeof currPage === 'undefined') {
currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX;
currPage = pageStartIndex;
}
if (typeof sizePerPage !== 'undefined') {

View File

@@ -1,5 +1,5 @@
import Store from 'react-bootstrap-table-next/src/store';
import { getByCurrPage } from '../src/page';
import { getByCurrPage, alignPage } from '../src/page';
describe('Page Functions', () => {
let data;
@@ -48,4 +48,40 @@ describe('Page Functions', () => {
});
});
});
describe('alignPage', () => {
const pageStartIndex = 1;
const sizePerPage = 10;
describe('if the length of store.data is less than the end page index', () => {
beforeEach(() => {
data = [];
for (let i = 0; i < 15; i += 1) {
data.push({ id: i, name: `test_name${i}` });
}
store = new Store('id');
store.data = data;
store.page = 2;
});
it('should return pageStartIndex argument', () => {
expect(alignPage(store, pageStartIndex, sizePerPage)).toEqual(pageStartIndex);
});
});
describe('if the length of store.data is large than the end page index', () => {
beforeEach(() => {
data = [];
for (let i = 0; i < 30; i += 1) {
data.push({ id: i, name: `test_name${i}` });
}
store = new Store('id');
store.data = data;
store.page = 2;
});
it('should return current page', () => {
expect(alignPage(store, pageStartIndex, sizePerPage)).toEqual(store.page);
});
});
});
});

View File

@@ -176,23 +176,6 @@ describe('Wrapper', () => {
expect(props.store.page).toEqual(instance.state.currPage);
});
});
describe('when nextProps.isDataChanged is true, currPage is undefined and options.pageStartIndex exists', () => {
beforeEach(() => {
nextProps.isDataChanged = true;
nextProps.pagination.options.pageStartIndex = 0;
instance.state.currPage = undefined;
instance.componentWillReceiveProps(nextProps);
});
it('should setting currPage state correctly', () => {
expect(instance.state.currPage).toBe(nextProps.pagination.options.pageStartIndex);
});
it('should saving store.page correctly', () => {
expect(props.store.page).toEqual(instance.state.currPage);
});
});
});
});

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table-next",
"version": "0.1.14",
"version": "0.1.15",
"description": "Next generation of react-bootstrap-table",
"main": "./lib/index.js",
"repository": {

View File

@@ -86,6 +86,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
{ tableCaption }
<Header
columns={ columns }
className={ this.props.headerClasses }
sortField={ store.sortField }
sortOrder={ store.sortOrder }
onSort={ this.props.onSort }
@@ -155,6 +156,7 @@ BootstrapTable.propTypes = {
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
rowEvents: PropTypes.object,
rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
headerClasses: PropTypes.string,
defaultSorted: PropTypes.arrayOf(PropTypes.shape({
dataField: PropTypes.string.isRequired,
order: PropTypes.oneOf([Const.SORT_DESC, Const.SORT_ASC]).isRequired

View File

@@ -10,6 +10,7 @@ const Header = (props) => {
const { ROW_SELECT_DISABLED } = Const;
const {
className,
columns,
onSort,
onFilter,
@@ -21,7 +22,7 @@ const Header = (props) => {
return (
<thead>
<tr>
<tr className={ className }>
{
(selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn)
? <SelectionHeaderCell { ...selectRow } /> : null
@@ -60,7 +61,8 @@ Header.propTypes = {
sortField: PropTypes.string,
sortOrder: PropTypes.string,
selectRow: PropTypes.object,
onExternalFilter: PropTypes.func
onExternalFilter: PropTypes.func,
className: PropTypes.string
};
export default Header;

View File

@@ -29,6 +29,25 @@ describe('Header', () => {
});
});
describe('className prop is exists', () => {
const className = 'test-class';
beforeEach(() => {
wrapper = shallow(
<Header
{ ...mockHeaderResolvedProps }
columns={ columns }
className={ className }
/>
);
});
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find(`.${className}`).length).toBe(1);
});
});
describe('header with columns enable sort', () => {
const sortField = columns[1].dataField;