Compare commits

...

73 Commits

Author SHA1 Message Date
AllenFang
88234fead0 Publish
- react-bootstrap-table2-editor@0.1.1
 - react-bootstrap-table2-example@0.1.1
 - react-bootstrap-table2-filter@0.1.2
 - react-bootstrap-table2-overlay@0.1.1
 - react-bootstrap-table2-paginator@0.1.1
 - react-bootstrap-table-next@0.1.2
2018-02-01 23:17:40 +08:00
Allen
dea780519f Merge pull request #188 from react-bootstrap-table/develop
2018/02/02 release
2018-02-01 23:07:20 +08:00
AllenFang
38bb2290dc README 2018-01-31 23:50:02 +08:00
AllenFang
8bfbc14bd9 fix #185 2018-01-31 00:01:04 +08:00
Allen
ee4eb8f2c6 Merge pull request #183 from react-bootstrap-table/feat/select-filter
Select filter
2018-01-30 23:53:50 +08:00
AllenFang
8fa6389c81 patch docs 2018-01-30 23:39:18 +08:00
AllenFang
9a354444d0 fix bug for wrap not existing method 2018-01-30 23:25:58 +08:00
AllenFang
2533a63430 patch test for select component 2018-01-30 23:20:47 +08:00
AllenFang
81e0080aa6 add styles for filter modules 2018-01-30 23:20:47 +08:00
AllenFang
094a0682f1 add select filter stories 2018-01-30 23:20:47 +08:00
AllenFang
3f2c6201d9 implement select filter 2018-01-30 23:20:47 +08:00
AllenFang
280c423298 fix #180 2018-01-28 22:09:00 +08:00
AllenFang
fc813e80b6 fix #172 2018-01-28 21:57:30 +08:00
AllenFang
4bb2ae2ba0 fix typo 2018-01-28 21:53:33 +08:00
AllenFang
09fadeb02b CONTRIBUTING.md 2018-01-22 23:09:07 +08:00
AllenFang
283179ebe1 Merge branch 'master' of https://github.com/react-bootstrap-table/react-bootstrap-table2 2018-01-22 00:31:21 +08:00
AllenFang
e83dd1bf07 v0.1.1 2018-01-22 00:30:26 +08:00
Chun-MingChen
760011ac03 update README and migration.md 2018-01-22 00:24:32 +08:00
AllenFang
067a94bea7 v0.1.0 2018-01-22 00:17:24 +08:00
AllenFang
d8ecc6277b README 2018-01-22 00:11:01 +08:00
AllenFang
216befae4b typo 2018-01-22 00:10:30 +08:00
Allen
3c9cd22d42 merge 0.1.0 code base
Develop -> Master (Not Version Bump)
2018-01-22 00:04:09 +08:00
AllenFang
d84b614599 tweak README.md 2018-01-21 23:31:42 +08:00
AllenFang
85f1eba7cb tweak stories 2018-01-21 17:12:07 +08:00
AllenFang
045ca4adb0 fix bug when remote pagination have same filter conds but change pages will cause data doesnt reflect 2018-01-21 17:12:07 +08:00
AllenFang
2263282629 tweak storybook webpack 2018-01-21 16:10:55 +08:00
AllenFang
a2d082babf due to container will always set source data via store.setAllData so that handle the filtered data in the filter wrapper 2018-01-21 15:44:11 +08:00
AllenFang
79d5a51a39 tweak package.json 2018-01-21 14:31:01 +08:00
AllenFang
51e0cc9129 README.md 2018-01-21 14:31:01 +08:00
AllenFang
659f2e2636 upgrade lerna 2018-01-21 14:10:57 +08:00
AllenFang
a556bd23ef Publish
- react-bootstrap-table2-editor@0.0.3
 - react-bootstrap-table2-example@0.0.3
 - react-bootstrap-table2-filter@0.0.3
 - react-bootstrap-table2-overlay@0.0.3
 - react-bootstrap-table2-paginator@0.0.3
 - react-bootstrap-table-next@0.0.3
2018-01-21 13:59:30 +08:00
AllenFang
b2e6bf93fb tweak pagination factory name 2018-01-20 17:53:58 +08:00
AllenFang
5f7c55aad4 drop start scripts 2018-01-20 15:27:08 +08:00
AllenFang
b4f7028b8b no publish 2018-01-20 15:27:08 +08:00
AllenFang
50a5bd3694 refine file name 2018-01-20 15:27:08 +08:00
AllenFang
9b3abac56d react-bootstrap-table2 -> react-bootstrap-table-next 2018-01-20 14:55:58 +08:00
AllenFang
1ef006e4c2 add README.md 2018-01-20 14:44:59 +08:00
AllenFang
42339b76aa tweak package.json 2018-01-20 13:34:27 +08:00
AllenFang
0d3b76b6a3 README.md 2018-01-20 11:21:11 +08:00
Allen
28240391bb Merge pull request #167 from react-bootstrap-table/Chun-MingChen-prod-setup
Production build
2018-01-18 23:17:37 +08:00
AllenFang
1cedea567c remove lerna-changelog 2018-01-18 22:56:18 +08:00
AllenFang
a9dd05d7cc fix entry point changed 2018-01-18 22:53:51 +08:00
AllenFang
41d76a08ce gulp build for style, scripts and umd 2018-01-18 21:49:33 +08:00
AllenFang
5d0b0af97a build sass 2018-01-16 22:54:02 +08:00
AllenFang
4bd73056d0 babel build 2018-01-16 00:04:14 +08:00
AllenFang
ec705f2651 umd build 2018-01-14 23:43:21 +08:00
AllenFang
3a8390c49e react-bootstrap-table2-example depend other packages via webpack resolver instead of node modules 2018-01-14 18:29:27 +08:00
AllenFang
afc742c205 no babel-cli build per repo 2018-01-14 15:56:39 +08:00
AllenFang
be4211b3c9 no publish to gh-pages 2018-01-14 15:53:27 +08:00
AllenFang
6c0fc4ffb4 Merge branch 'prod-setup' of https://github.com/Chun-MingChen/react-bootstrap-table2 into Chun-MingChen-prod-setup 2018-01-14 15:41:46 +08:00
Allen
55fe0075b1 Merge pull request #165 from react-bootstrap-table/enhance/cell-edit-as-package
react-bootstrap-table2-editor
2018-01-07 14:18:59 +08:00
AllenFang
618346b845 patch docs for cell edit 2018-01-07 14:07:17 +08:00
AllenFang
e46d83762d fix EditingCell liftcycle bug 2018-01-07 14:02:50 +08:00
AllenFang
9428f2d9b7 refine cell edit tests 2018-01-07 11:20:49 +08:00
AllenFang
21344ec4b3 refine cell edit stories 2018-01-07 11:20:49 +08:00
AllenFang
39be018327 move cell edit logic to react-bootstrap-table2-editor 2018-01-07 11:20:32 +08:00
Chun-MingChen
3649f83eaf select lerna-changelog to generate change log 2018-01-07 01:46:52 +08:00
Chun-MingChen
a37ef6883d compile with babel 2018-01-07 01:46:52 +08:00
Chun-MingChen
383cfbab57 add package babel-cli 2018-01-07 01:29:13 +08:00
Chun-MingChen
cb1041b9d7 auto release for storybook
* deploy subdirectory of storybook-static to branch gh-pages
2018-01-07 01:29:13 +08:00
Chun-MingChen
6e4ca34626 add dependency git-directory-deploy
* Deploy a subdirectory from a git repo to a different branch.
2018-01-06 19:43:28 +08:00
Chun-MingChen
19cca1215f add dependency rimraf
* clean built files for gh_pages
2018-01-06 19:43:03 +08:00
Allen
6913434714 fix #161
Refine cell edit remote mode
2018-01-06 13:48:07 +08:00
AllenFang
d5f7ae5edb refined docs for remote cell edit 2018-01-04 23:45:40 +08:00
AllenFang
beafef9661 patch tests for refining remote cell edit 2018-01-04 23:45:40 +08:00
AllenFang
a50a12426a refine remote cell edit 2018-01-04 23:42:17 +08:00
Allen
fcf7800f96 fix #152
implement remote sorting
2017-12-28 17:58:18 +08:00
AllenFang
01337f50a7 implement remote sorting 2017-12-27 23:31:16 +08:00
Allen
bdfc4ebcad Merge pull request #158 from react-bootstrap-table/enhance/refactoring
Refarcotring Wrapper
2017-12-25 17:46:23 +08:00
AllenFang
fb81595f73 refactoring wrapper mechanism 2017-12-25 17:32:14 +08:00
AllenFang
3bfeec7946 fix bug for onTableChange argument change 2017-12-25 17:32:14 +08:00
AllenFang
4c89f91a83 implement remote resolver 2017-12-25 17:32:14 +08:00
ChunMing, Chen
badce54b95 Set theme jekyll-theme-cayman 2017-08-19 23:01:09 +08:00
164 changed files with 6723 additions and 3202 deletions

7
.gitignore vendored
View File

@@ -15,3 +15,10 @@ lerna-debug.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# gh-pages
storybook-static
# build
lib
dist

7
.npmignore Normal file
View File

@@ -0,0 +1,7 @@
node_modules
.DS_Store
*~
*.sublime-project
*.sublime-workspace
*.idea
*.iml

View File

@@ -12,6 +12,7 @@ Additionally, asking questions and requesting new features are welcomed via [iss
# Pull Requests
Check [here](./docs/development.md) for getting started with development.
* PR base is `develop` branch
* We recommend filing an [issue](https://github.com/react-bootstrap-table/react-bootstrap-table2/issues) before you implement any new features.
* Please ensure that all the test suites have passed before submitting a PR. Besides, always test the actual business logic.
* If your PR is trying to fix a bug, please describe the details as much as you could and tag the bug number with hashtag.

View File

@@ -1,25 +1,41 @@
# react-bootstrap-table2
Rebuilt [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-table)
## The problems/features I want to solve
* Performance
* Fully compatiable with bootstrap 3 and 4(`react-bootstrap-table@4.0.0` already done)
* Clean Code and Testing
* Decrease the size of bundled file
* **Split module/functionality from core module, make core module more lightweight**
* Use [`storybook`](https://github.com/storybooks/storybook) to build examples
* Support the aggregation(summary) view
* Support the table footer
* Support column/row span on header and body
* Support sticky header
* Support table section([react-bootstrap-table#721](https://github.com/AllenFang/react-bootstrap-table/pull/721))
* Handle events well
* Fix unalign issues
* Make **stateless** table more easy to use(`react-bootstrap-table` alread have `remote` mode but have some bugs)
* Customizable table
* Support the nested data([react-bootstrap-table#50](https://github.com/AllenFang/react-bootstrap-table/issues/50◊))
* Consider to support column resize
* Consider to make animation on `react-bootstrap-table2` more easy
> `react-bootstrap-table2`'s npm module name is [**`react-bootstrap-table-next`**](https://www.npmjs.com/package/react-bootstrap-table-next) due to some guys already used it
## The feature may lost on react-bootstrap-table
* Have a great chance that I don't support the vertical scrollbar on table
`react-bootstrap-table2` separate some functionalities from core modules to other modules like following:
* [`react-bootstrap-table-next`](https://www.npmjs.com/package/react-bootstrap-table-next)
* [`react-bootstrap-table2-filter`](https://www.npmjs.com/package/react-bootstrap-table2-filter)
* [`react-bootstrap-table2-editor`](https://www.npmjs.com/package/react-bootstrap-table2-editor)
* [`react-bootstrap-table2-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator)
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
This can help your application with less bundled size and also help us have clean design to avoid handling to much logic in kernal module(SRP).
## Migration
If you are the user from legacy [`react-bootstrap-table`](https://github.com/AllenFang/react-bootstrap-table/), please have a look on [this](./docs/migration.md).
## Usage
See [getting started](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/getting-started.html).
## Online Demo
See `react-bootstrap-table2` [storybook](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html).
## Roadmap
See [release plans](https://react-bootstrap-table.github.io/react-bootstrap-table2/blog/2018/01/24/release-plan.html).
## Development
Please check [development guide](./docs/development.md).
## How should I run storybook example in my local?
```sh
$ git clone https://github.com/react-bootstrap-table/react-bootstrap-table2.git
$ cd react-bootstrap-table2
$ yarn install
$ yarn storybook
$ Go to localhost:6006
```
**Storybook examples: [`packages/react-bootstrap-table2-example/examples`](https://github.com/react-bootstrap-table/react-bootstrap-table2/tree/master/packages/react-bootstrap-table2-example/examples)**

1
_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-cayman

View File

@@ -40,7 +40,13 @@ This is a chance that you can connect to your remote server or database to manip
For flexibility reason, you can control what functionality should be handled on remote via a object return:
```js
remote={ { filter: true } }
remote={ {
filter: true,
pagination: true,
filter: true,
sort: true,
cellEdit: true
} }
```
In above case, only column filter will be handled on remote.
@@ -53,20 +59,20 @@ A special case for remote pagination:
remote={ { pagination: true, filter: false, sort: false } }
```
In pagination case, even you only specified the paignation need to handle as remote, `react-bootstrap-table2` will handle all the table changes(`filter`, `sort` etc) as remote mode, because `react-bootstrap-table` only know the data of current page, but filtering, searching or sort need to work on overall datas.
There is a apecial case for remote pagination, even you only specified the paignation need to handle as remote, `react-bootstrap-table2` will handle all the table changes(filter, sort etc) as remote mode, because `react-bootstrap-table2` only know the data of current page, but filtering, searching or sort need to work on overall datas.
### <a name='loading'>loading - [Bool]</a>
Telling if table is loading or not, for example: waiting data loading, filtering etc. It's **only** valid when [`remote`](#remote) is enabled.
When `loading` is `true`, `react-bootstrap-table` will attend to render a overlay on table via [`overlay`](#overlay) prop, if [`overlay`](#overlay) prop is not given, `react-bootstrap-table` will ignore the overlay rendering.
When `loading` is `true`, `react-bootstrap-table2` will attend to render a overlay on table via [`overlay`](#overlay) prop, if [`overlay`](#overlay) prop is not given, `react-bootstrap-table2` will ignore the overlay rendering.
### <a name='overlay'>overlay - [Function]</a>
`overlay` accept a factory funtion which should returning a higher order component. By default, `react-bootstrap-table-overlay` can be a good option for you:
`overlay` accept a factory funtion which should returning a higher order component. By default, `react-bootstrap-table2-overlay` can be a good option for you:
```sh
$ npm install react-bootstrap-table-overlay
$ npm install react-bootstrap-table2-overlay
```
```js
import overlayFactory from 'react-bootstrap-table-overlay';
import overlayFactory from 'react-bootstrap-table2-overlay';
<BootstrapTable
data={ data }
@@ -249,13 +255,23 @@ There's only two arguments will be passed to `onTableChange`: `type` and `newSta
* `filter`
* `pagination`
* `sort`
* `cellEdit`
Following is a shape of `newState`
```js
{
page, // newest page
sizePerPage, //newest sizePerPage
filters // an object which have current filter status per column
sizePerPage, // newest sizePerPage
sortField, // newest sort field
sortOrder, // newest sort order
filters, // an object which have current filter status per column
data, // when you enable remote sort, you may need to base on data to sort if data is filtered/searched
cellEdit: { // You can only see this prop when type is cellEdit
rowId,
dataField,
newValue
}
}
```

View File

@@ -1,3 +1,10 @@
# Cell Editing
Before start to use cell edit, please remember to install `react-bootstrap-table2-editor`
```sh
$ npm install react-bootstrap-table2-editor --save
```
# Properties on cellEdit prop
* [mode (**required**)](#mode)
* [blurToSave](#blurToSave)
@@ -5,8 +12,6 @@
* [timeToCloseMessage](#timeToCloseMessage)
* [beforeSaveCell](#beforeSaveCell)
* [afterSaveCell](#afterSaveCell)
* [onUpdate](#onUpdate)
* [editing](#editing)
* [errorMessage](#errorMessage)
* [onErrorMessageDisappear](#onErrorMessageDisappear)
@@ -21,9 +26,7 @@ Following is the shape of `cellEdit` object:
mode: 'click',
blurToSave: true,
timeToCloseMessage: 2500,
editing: false|true,
errorMessage: '',
onUpdate: (rowId, dataField, newValue) => { ... },
beforeSaveCell: (oldValue, newValue, row, column) => { ... },
afterSaveCell: (oldValue, newValue, row, column) => { ... },
onErrorMessageDisappear: () => { ... },
@@ -63,74 +66,9 @@ const cellEdit = {
};
```
### <a name='onUpdate'>cellEdit.onUpdate - [Function]</a>
If you want to control the cell updating process by yourself, for example, connect with `Redux` or saving data to backend database, `cellEdit.onUpdate` is a great chance you can work on it.
Firsylt, `react-bootstrap-table2` allow `cellEdit.onUpdate` to return a promise:
```js
const cellEdit = {
// omit...
onUpdate: (rowId, dataField, newValue) => {
return apiCall().then(response => {
console.log('update cell to backend successfully');
// Actually, you dont do any thing here, we will update the new value when resolve your promise
})
.catch(err => throw new Error(err.message));
}
};
```
If your promise is resolved successfully, `react-bootstrap-table2` will default help you to update the new cell value.
If your promise is resolved failure, you can throw an `Error` instance, `react-bootstrap-table2` will show up the error message (Same behavior like [`column.validator`](./columns.md#validator)).
In some case, backend will return a new value to client side and you want to apply this new value instead of the value that user input. In this situation, you can return an object which contain a `value` property:
```js
const cellEdit = {
// omit...
onUpdate: (rowId, dataField, newValue) => {
return apiCall().then(response => {
return { value: response.value }; // response.value is from your backend api
})
.catch(err => throw new Error(err.message));
}
};
```
If your application integgrate with `Redux`, you may need to dispatch an action in `cellEdit.onUpdate` callback. In this circumstances, you need to return `false` explicity which `react-bootstrap-table2` will stop any operation internally and wait rerender by your application.
In a simple redux application, you probably need to handle those props by your application:
* [`cellEdit.editing`](#editing): Is cell still on editing or not? This value should always be `true` when saving cell failure.
* [`cellEdit.errorMessage`](#errorMessage): Error message when save the cell failure.
* [`cellEdit.onErrorMessageDisappear`](#onErrorMessageDisappear): This callback will be called when error message alert closed automatically.
* `cellEdit.onUpdate`
```js
const cellEdit = {
editing: this.props.editing,
errorMessage: this.props.errorMessage,
onErrorMessageDisappear: () => {
// cleanErrorMessage is an action creator
this.props.dispatch(cleanErrorMessage());
},
onUpdate: (rowId, dataField, newValue) => {
// updateCell is an action creator
this.props.dispatch(updateCell(rowId, dataField, newValue)));
return false; // Have to return false here
}
};
```
Please check [this](https://github.com/react-bootstrap-table/react-bootstrap-table2/blob/develop/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-redux-table.js) exmaple to learn how use `cellEdit` with a redux application
### <a name='editing'>cellEdit.editing - [Bool]</a>
This only used when you want to control cell saving externally, `cellEdit.editing` will be a flag to tell `react-bootstrap-table2` whether currecnt editing cell is still editing or not. Because, it's possible that some error happen when you saving cell, in this situation, you need to configre this value as `false` to keep the cell as edtiable and show up an error message.
### <a name='errorMessage'>cellEdit.errorMessage - [String]</a>
Same as [`cellEdit.editing`](#editing). This prop is not often used. Only used when you keep the error message in your application state.
This prop is not often used. Only used when you want to keep the error message in your application state and also handle the cell editing on remote mode.
### <a name='onErrorMessageDisappear'>cellEdit.onErrorMessageDisappear - [Function]</a>
This callback function will be called when error message discard.
This callback function will be called when error message discard so that you can sync the newest error message to your state if you have.

View File

@@ -73,7 +73,7 @@ dataField: 'address.city'
```
## <a name='text'>column.text (**required**) - [String]</a>
`text` will be apply as the column text in header column, if your header is not only text and you want to customize your header column, please check [`column.headerFormatter`](#headerFormatter)
`text` will be the column text in header column by default, if your header is not only text or you want to customize the header column, please check [`column.headerFormatter`](#headerFormatter)
## <a name='hidden'>column.hidden - [Bool]</a>
`hidden` allow you to hide column when `true` given.
@@ -89,9 +89,9 @@ dataField: 'address.city'
## <a name='headerFormatter'>column.headerFormatter - [Function]</a>
`headerFormatter` allow you to customize the header column and only accept a callback function which take three arguments and a JSX/String are expected for return.
* `column`: column object itself
* `colIndex`
* `components`: it's an object which contain all of other react element, like sort caret or filter etc.
* `column`: current column object itself
* `colIndex`: index of current column
* `components`: an object which contain all of other react element, like sort caret or filter etc.
The third argument: `components` have following specified properties:
```js
@@ -131,7 +131,7 @@ It's availabe to have custom class on table column:
classes: 'id-custom-cell'
}
```
In addition, `classes` also accept a callback function which have more power to custom the css class on each columns. This callback function take `4` arguments and a `string` is expect to return:
In addition, `classes` also accept a callback function which have more power to custom the css class on each columns. This callback function take **4** arguments and a `String` is expected to return::
```js
@@ -148,7 +148,7 @@ In addition, `classes` also accept a callback function which have more power to
**Return value**
A new `String` will be the result of element class.
A new `String` will be the result as element class.
## <a name='headerClasses'>column.headerClasses - [String | Function]</a>
It's similar to [`column.classes`](#classes), `headerClasses` is availabe to have customized class on table header column:
@@ -185,7 +185,7 @@ It's availabe to have custom style on table column:
}
```
In addition, similar to [`column.classes`](#classes), `style` also accept a callback function which have more power to customize the `inline style` on each columns. This callback function takes `4` arguments and an `Object` is expect to return:
In addition, similar to [`column.classes`](#classes), `style` also accept a callback function which have more power to customize the `inline style` on each columns. This callback function takes **4** arguments and an `Object` is expect to return:
```js
@@ -215,7 +215,7 @@ It's availabe to have customized inline-style on table header column:
}
```
Moreover, it also accept a callback function which takes 2 arguments and an `Object` is expect to return:
Moreover, it also accept a callback function which takes **2** arguments and an `Object` is expect to return:
```js
{
@@ -233,7 +233,7 @@ A new `Object` will be the result of element headerStyle.
## <a name='title'>column.title - [Bool | Function]</a>
`react-bootstrap-table2` is disable [`HTML title`](https://www.w3schools.com/tags/tag_title.asp) as default. You can assign `title` as `true` to enable the HTML title on table column and take `cell content` as default value. Additionally, you could customize title via a callback. It takes `4` arguments and a `String` is expect to return:
`react-bootstrap-table2` is disable [`HTML title`](https://www.w3schools.com/tags/tag_title.asp) as default. You can assign `title` as `true` to enable the HTML title on table column and take `cell content` as default value. Additionally, you could customize title via a callback. It takes **4** arguments and a `String` is expect to return:
```js
@@ -282,7 +282,7 @@ A new `String` will be the result of element headerTitle.
## <a name='align'>column.align - [String | Function]</a>
You can configure the [CSS text-align](https://www.w3schools.com/cssref/pr_text_text-align.asp) for table column by `align` property.
Besides, `align` also accept a callback function for dynamically setting text align. It takes `4` arguments and a `String` is expect to return:
Besides, `align` also accept a callback function for dynamically setting text align. It takes **4** arguments and a `String` is expect to return:
```js
{
@@ -385,14 +385,14 @@ Not only `Object`, `callback function` is also acceptable. It takes `4` argument
A new `Object` will be the result of element HTML attributes.
#### * Caution
> Caution:
If `column.classes`, `column.style`, `column.title`, `column.hidden` or `column.align` was given at the same time, property `attrs` has lower priorty and it will be overwrited.
> If `column.classes`, `column.style`, `column.title`, `column.hidden` or `column.align` was given at the same time, property `attrs` has lower priorty and it will be overwrited.
```js
{
// omit...
title: true, // it will be chosen.
title: true, // get higher priority
attrs: { title: 'test' }
}
```
@@ -409,7 +409,7 @@ If `column.classes`, `column.style`, `column.title`, `column.hidden` or `column.
}
```
Additionally, customize the header attributes by a `2-arguments` callback function:
Additionally, customize the header attributes by a **2** arguments callback function:
```js
{
@@ -542,6 +542,7 @@ Or take a callback function
Configure `column.filter` will able to setup a column level filter on the header column. Currently, `react-bootstrap-table2` support following filters:
* Text(`textFilter`)
* Select(`selectFilter`)
We have a quick example to show you how to use `column.filter`:
@@ -556,4 +557,25 @@ import { textFilter } from 'react-bootstrap-table2-filter';
}
```
For some reason of simple customization, `react-bootstrap-table2` allow you to pass some props to filter factory function. Please check [here](https://github.com/react-bootstrap-table/react-bootstrap-table2/tree/master/packages/react-bootstrap-table2-filter/README.md) for more detail tutorial.
For some reason of simple customization, `react-bootstrap-table2` allow you to pass some props to filter factory function. Please check [here](https://github.com/react-bootstrap-table/react-bootstrap-table2/tree/master/packages/react-bootstrap-table2-filter/README.md) for more detail tutorial.
## <a name='filterValue'>column.filterValue - [Function]</a>
Sometimes, if the cell/column value that you don't want to filter on them, you can define `filterValue` to return a actual value you wanna be filterd:
**Parameters**
* `cell`: The value of current cell.
* `row`: The value of current row.
**Return value**
A final `String` value you want to be filtered.
```js
// omit...
{
dataField: 'price',
text: 'Product Price',
filter: textFilter(),
filterValue: (cell, row) => owners[cell]
}
```

View File

@@ -9,7 +9,7 @@ $ lerna bootstrap # ./node_modules/.bin/lerna bootstrap
```
### Development
```bash
$ npm start
$ npm run storybook
```
### Launch StoryBook

117
docs/migration.md Normal file
View File

@@ -0,0 +1,117 @@
# Migration Guide
* Please see the [CHANGELOG](https://react-bootstrap-table.github.io/react-bootstrap-table2/blog/2018/01/24/new-version-0.1.0.html) for `react-bootstrap-table2` first drop.
* Please see the [Roadmap](https://react-bootstrap-table.github.io/react-bootstrap-table2/blog/2018/01/24/release-plan.html) for `react-bootstrap-table2` in 2018/Q1.
* Feel free to see the [offical docs](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/about.html), we list all the basic usage here!!
## Preface
Currently, **I still can't implement all the mainly features in legacy `react-bootstrap-table`**, so please watch our github repo or [blog](https://react-bootstrap-table.github.io/react-bootstrap-table2/blog/) to make sure the legacy features you wanted are already implemented on `react-bootstrap-table2`. Anyway, ask me by open issue is ok.
-----
`react-bootstrap-table2` separate some functionalities from core modules to other modules like following:
* [`react-bootstrap-table-next`](https://www.npmjs.com/package/react-bootstrap-table-next)
* Core table module, include sorting and row selection
* [`react-bootstrap-table2-filter`](https://www.npmjs.com/package/react-bootstrap-table2-filter)
* Column filter Addons
* [`react-bootstrap-table2-editor`](https://www.npmjs.com/package/react-bootstrap-table2-editor)
* Cell Editing Addons
* [`react-bootstrap-table2-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator)
* Pagination Addons
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
* Overlay/Loading Addons
This can help your application with less bundled size and also help `react-bootstrap-table2` have clean design to avoid handling to much logic in kernal module(SRP). Hence, which means you probably need to install above addons when you need specific features.
## Core Table Migration
There is a big chagne is that there's no `TableHeaderColumn` in the `react-bootstrap-table2`, instead you are supposed to be define the `columns` prop on `BootstrapTable`:
```js
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 } />
```
The `text` property is just same as the children for the `TableHeaderColumn`, if you want to custom the header, there's a new property is: [`headerFormatter`](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columnheaderformatter-function).
* [`BootstrapTable` Definitation](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html)
* [Column Definitation](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html)
## Table Sort
Please see [Work with table sort](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-sort.html).
- [x] Basic sorting
- [x] Custom sort function
- [x] Default Sort
- [x] Remote mode
- [x] Custom the sorting header
- [ ] Custom the sort caret
- [ ] Sort management
- [ ] Multi sort
Due to no `TableHeaderColumn` so that no `dataSort` here, please add [`sort`](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columnsort-bool) property on column definitation.
## Row Selection
Please see [Work with selection](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-row-select.html).
Please see [available selectRow configurations](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/row-select-props.html).
No huge change for row selection, but can not custom the selection column currently. Coming soon!!!
## Column Filter
Please see [Work with column filter](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-filter.html).
Please see [available filter configuration](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/filter-props.html).
- [x] Text Filter
- [x] Custom Text Filter
- [x] Remote Filter
- [ ] Custom Filter Component
- [ ] Regex Filter
- [x] Select Filter
- [x] Custom Select Filter
- [ ] Number Filter
- [ ] Date Filter
- [ ] Array Filter
- [ ] Programmatically Filter
Remember to install [`react-bootstrap-table2-filter`](https://www.npmjs.com/package/react-bootstrap-table2-filter) firstly.
Due to no `TableHeaderColumn` so that no `filter` here, please add [`filter`](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columnfilter-object) property on column definitation and [`filter`](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html#filter-object) prop on `BootstrapTable`.
## Cell Edit
Please see [Work with cell edit](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-celledit.html).
Please see [available cell edit configurations](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/cell-edit-props.html).
Remember to install [`react-bootstrap-table2-editor`](https://www.npmjs.com/package/react-bootstrap-table2-editor) firstly.
No big changes for cell editing, [`validator`](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columnvalidator-function) will not support the async call(Promise).
## Pagination
Please see [Work with pagination](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-pagination.html).
Please see [available pagination configurations](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/pagination-props.html).
Remember to install [`react-bootstrap-table2-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator) firstly.
No big changes for pagination, but still can't custom the pagination list, button and sizePerPage dropdown.
## Remote
> It's totally different in `react-bootstrap-table2`. Please [see](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-remote.html).

View File

@@ -2,13 +2,10 @@
# Row selection
`react-bootstrap-table2` supports the row selection feature. By passing prop `selectRow` to enable row selection. When you enable this feature, `react-bootstrap-table2` will append a new selection column at first.
## Available properties
The following are available properties in `selectRow`:
#### Required
## Required
* [mode (**required**)](#mode)
## Optional
* [style](#style)
* [classes)](#classes)
* [bgColor](#bgColor)
@@ -19,15 +16,13 @@ The following are available properties in `selectRow`:
* [onSelectAll](#onSelectAll)
* [hideSelectColumn](#hideSelectColumn)
#### Optional
## <a name="mode">selectRow.mode - [String]</a>
### <a name="mode">selectRow.mode - [String]</a>
Specifying the selection way for `single(radio)` or `multiple(checkbox)`. If `radio` was assigned, there will be a radio button in the selection column; otherwise, the `checkbox` instead.
#### values
* `radio`
* `checkbox`
* **radio**
* **checkbox**
#### examples
@@ -35,6 +30,7 @@ Specifying the selection way for `single(radio)` or `multiple(checkbox)`. If `ra
const selectRow = {
mode: 'radio' // single row selection
};
<BootstrapTable
keyField='id'
data={ products }
@@ -56,7 +52,7 @@ const selectRow = {
/>
```
## <a name='style'>selectRow.style - [Object | Function]</a>
### <a name='style'>selectRow.style - [Object | Function]</a>
`selectRow.style` allow you to have custom style on selected rows:
```js
@@ -75,7 +71,7 @@ const selectRow = {
};
```
## <a name='classes'>selectRow.classes - [String | Function]</a>
### <a name='classes'>selectRow.classes - [String | Function]</a>
`selectRow.classes` allow you to add css class on selected rows:
```js
@@ -94,7 +90,7 @@ const selectRow = {
};
```
## <a name='bgColor'>selectRow.bgColor - [String | Function]</a>
### <a name='bgColor'>selectRow.bgColor - [String | Function]</a>
The backgroud color when row is selected
```js
@@ -115,7 +111,7 @@ const selectRow = {
};
```
## <a name='nonSelectable'>selectRow.nonSelectable - [Array]</a>
### <a name='nonSelectable'>selectRow.nonSelectable - [Array]</a>
This prop allow you to restrict some rows which can not be selected by user. `selectRow.nonSelectable` accept an rowkeys array.
```js
@@ -125,8 +121,8 @@ const selectRow = {
};
```
## <a name='clickToSelect'>selectRow.clickToSelect - [Bool]</a>
Able to select row when clicking on row.
### <a name='clickToSelect'>selectRow.clickToSelect - [Bool]</a>
Allow user to select row by clicking on the row.
```js
const selectRow = {
@@ -135,10 +131,10 @@ const selectRow = {
};
```
> Note: if you also enable [cellEdit](./cell-edit.md), the `selectRow.clickToSelect` will deactivate the functionality of cell editing
> Note: When you also enable [cellEdit](./cell-edit.md), the `selectRow.clickToSelect` will deactivate the functionality of cell editing
> If you want to click on row to select row and edit cell simultaneously, you are suppose to enable [`selectRow.clickToEdit`](#clickToEdit)
## <a name='clickToEdit'>selectRow.clickToEdit - [Bool]</a>
### <a name='clickToEdit'>selectRow.clickToEdit - [Bool]</a>
Able to click to edit cell and select row
```js
@@ -149,7 +145,7 @@ const selectRow = {
};
```
## <a name='onSelect'>selectRow.onSelect - [Function]</a>
### <a name='onSelect'>selectRow.onSelect - [Function]</a>
This callback function will be called when a row is select/unselect and pass following three arguments:
`row`, `isSelect` and `rowIndex`.
@@ -162,7 +158,7 @@ const selectRow = {
};
```
## <a name='onSelectAll'>selectRow.onSelectAll - [Function]</a>
### <a name='onSelectAll'>selectRow.onSelectAll - [Function]</a>
This callback function will be called when select/unselect all and it only work when you configure [`selectRow.mode`](#mode) as `checkbox`.
```js
@@ -174,7 +170,7 @@ const selectRow = {
};
```
## <a name='hideSelectColumn'>selectRow.hideSelectColumn - [Bool]</a>
### <a name='hideSelectColumn'>selectRow.hideSelectColumn - [Bool]</a>
Default is `false`, if you don't want to have a selection column, give this prop as `true`
```js

85
gulpfile.babel.js Normal file
View File

@@ -0,0 +1,85 @@
import gulp from 'gulp';
import babel from 'gulp-babel';
import sass from 'gulp-sass';
import cleanCSS from 'gulp-clean-css';
import cleanDir from 'gulp-clean';
import rename from 'gulp-rename';
import shell from 'gulp-shell';
const LIB = 'lib';
const DIST = 'dist';
const TEST = 'test';
const PKG_PATH = './packages';
const NODE_MODULES = 'node_modules';
const JS_PKGS = [
'react-bootstrap-table2',
'react-bootstrap-table2-editor',
'react-bootstrap-table2-filter',
'react-bootstrap-table2-overlay',
'react-bootstrap-table2-paginator'
].reduce((pkg, curr) => `${curr}|${pkg}`, '');
const JS_SKIPS = `+(${TEST}|${LIB}|${DIST}|${NODE_MODULES})`;
const STYLE_PKGS = [
'react-bootstrap-table2',
'react-bootstrap-table2-filter',
'react-bootstrap-table2-paginator'
].reduce((pkg, curr) => `${curr}|${pkg}`, '');
const STYLE_SKIPS = `+(${NODE_MODULES})`;
function clean() {
return gulp
.src(`./packages/+(${JS_PKGS})/+(${LIB}|${DIST})`, { allowEmpty: true })
.pipe(cleanDir());
}
function scripts() {
return gulp
.src([
`./packages/+(${JS_PKGS})/**/*.js`,
`!packages/+(${JS_PKGS})/${JS_SKIPS}/**/*.js`
])
.pipe(babel())
.pipe(rename((path) => {
if (path.dirname.indexOf('src') > -1) {
path.dirname = path.dirname.replace('src', `${LIB}/src`);
} else {
path.dirname += `/${LIB}`;
}
}))
.pipe(gulp.dest(PKG_PATH));
}
function styles() {
return gulp
.src([
`./packages/+(${STYLE_PKGS})/style/**/*.scss`,
`!packages/+(${STYLE_PKGS})/${STYLE_SKIPS}/**/*.scss`
])
.pipe(sass().on('error', sass.logError))
.pipe(rename((path) => {
path.dirname = path.dirname.replace('style', DIST);
}))
.pipe(gulp.dest(PKG_PATH))
.pipe(cleanCSS({ compatibility: 'ie8' }))
.pipe(rename((path) => {
path.extname = '.min.css';
}))
.pipe(gulp.dest(PKG_PATH));
}
function umd() {
return gulp.src('./webpack.prod.config.babel.js')
.pipe(shell(['webpack --config <%= file.path %>']));
}
const buildJS = gulp.parallel(umd, scripts);
const buildCSS = styles;
const build = gulp.series(clean, gulp.parallel(buildJS, buildCSS));
gulp.task('prod', build);
gulp.task('default', build);

View File

@@ -3,5 +3,5 @@
"packages": [
"packages/*"
],
"version": "0.0.0"
"version": "independent"
}

View File

@@ -1,29 +1,45 @@
{
"name": "react-bootstrap-table2",
"version": "0.0.1",
"private": true,
"description": "Rebuilt for react-bootstrap-table",
"main": "index.js",
"scripts": {
"postinstall": "lerna bootstrap",
"start": "node -r babel-register ./node_modules/.bin/webpack-dev-server --config webpack.config.babel.js",
"build": "./node_modules/.bin/gulp prod",
"lint": "eslint ./packages --ext .js --ext .jsx --ignore-path .gitignore",
"pretest": "yarn lint --cache",
"test": "jest",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch",
"storybook": "cd ./packages/react-bootstrap-table2-example && yarn storybook"
"storybook": "cd ./packages/react-bootstrap-table2-example && yarn storybook",
"gh-pages:clean": "cd ./packages/react-bootstrap-table2-example && yarn gh-pages:clean",
"gh-pages:build": "cd ./packages/react-bootstrap-table2-example && yarn gh-pages:build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/react-bootstrap-table/react-bootstrap-table2.git"
},
"author": "",
"license": "ISC",
"author": "AllenFang",
"contributors": [
{
"name": "Allen Fang",
"email": "ayu780129@hotmail.com",
"url": "https://github.com/AllenFang"
},
{
"name": "Chun-MingChen",
"email": "nick830314@gmail.com",
"url": "https://github.com/Chun-MingChen"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/react-bootstrap-table/react-bootstrap-table2/issues"
},
"homepage": "https://github.com/react-bootstrap-table/react-bootstrap-table2#readme",
"devDependencies": {
"babel-cli": "6.26.0",
"babel-core": "6.25.0",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
@@ -41,11 +57,18 @@
"eslint-plugin-import": "2.7.0",
"eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.2.1",
"gulp": "4.0.0",
"gulp-babel": "7.0.0",
"gulp-clean": "0.4.0",
"gulp-clean-css": "3.9.2",
"gulp-rename": "^1.2.2",
"gulp-sass": "3.1.0",
"gulp-shell": "0.6.5",
"html-webpack-plugin": "2.30.1",
"jest": "20.0.4",
"jsdom": "11.2.0",
"jsdom-global": "3.0.2",
"lerna": "2.0.0",
"lerna": "2.8.0",
"node-sass": "4.5.3",
"react-test-renderer": "16.0.0",
"sass-loader": "6.0.6",
@@ -60,11 +83,6 @@
"react": "16.0.0",
"react-dom": "16.0.0"
},
"peerDependencies": {
"prop-types": "^15.0.0",
"react": "^16.0.0",
"react-dom": "^16.0.0"
},
"jest": {
"collectCoverageFrom": [
"packages/**/*.js"

View File

@@ -0,0 +1,61 @@
# react-bootstrap-table2-editor
`react-bootstrap-table2` separate the cell edit code base to [`react-bootstrap-table2-editor`](https://github.com/react-bootstrap-table/react-bootstrap-table2/tree/develop/packages/react-bootstrap-table2-editor), so there's a little bit different when you use cell edit than `react-bootstrap-table`. In the following, we are going to show you how to enable the cell edit
**[Live Demo For Cell Edit](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Cell%20Editing)**
**[API&Props Definitation](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/cell-edit-props.html)**
-----
## Install
```sh
$ npm install react-bootstrap-table2-editor --save
```
## How
We have [two ways](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/cell-edit-props.html#celleditmode-string) to trigger a editable cell as editing cell:
* click
* dbclick
That's look into how we enable the cell edit on tabe:
```js
import cellEditFactory from 'react-bootstrap-table2-editor';
// omit
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
```
How user save their new editings? We offer two ways:
* Press ENTER(**default**)
* Blur from current editing cell(Need to enable the [cellEdit.blurToSave](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/cell-edit-props.html#celleditblurtosave-bool))
## Editable Cell
`react-bootstrap-table2` support you to configure the cell editable on three level:
* Row Level ([cellEdit.nonEditableRows](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/cell-edit-props.html#celleditnoneditablerows-function))
* Column Level (Configure [column.editable](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditable-bool-function) as bool value)
* Cell Level (Configure [column.editable](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditable-bool-function) as a callback function)
## Customize Style/Class
Currently, we only support the editing cell style/class customization, in the future, we will offer more customizations.
### Editing Cell
* Customize the editing cell style via [column.editCellStyle](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditcellstyle-object-function)
* Customize the editing cell classname via [column.editCellClasses](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditcellclasses-string-function)
## Validation
[`column.validator`](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columnvalidator-function) will help you to work on it!

View File

@@ -0,0 +1,16 @@
import wrapperFactory from './src/wrapper';
import editingCellFactory from './src/editing-cell';
import {
CLICK_TO_CELL_EDIT,
DBCLICK_TO_CELL_EDIT,
DELAY_FOR_DBCLICK
} from './src/const';
export default (options = {}) => ({
wrapperFactory,
editingCellFactory,
CLICK_TO_CELL_EDIT,
DBCLICK_TO_CELL_EDIT,
DELAY_FOR_DBCLICK,
options
});

View File

@@ -0,0 +1,47 @@
{
"name": "react-bootstrap-table2-editor",
"version": "0.1.1",
"description": "it's the editor addon for react-bootstrap-table2",
"main": "./lib/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/react-bootstrap-table/react-bootstrap-table2.git"
},
"keywords": [
"react",
"bootstrap",
"table",
"grid",
"react-bootstrap-table-addons",
"react-component"
],
"files": [
"lib/",
"dist/"
],
"tags": [
"react"
],
"author": "AllenFang",
"contributors": [
{
"name": "Allen Fang",
"email": "ayu780129@hotmail.com",
"url": "https://github.com/AllenFang"
},
{
"name": "Chun-MingChen",
"email": "nick830314@gmail.com",
"url": "https://github.com/Chun-MingChen"
}
],
"peerDependencies": {
"prop-types": "^15.0.0",
"react": "^16.0.0",
"react-dom": "^16.0.0"
}
}

View File

@@ -0,0 +1,4 @@
export const TIME_TO_CLOSE_MESSAGE = 3000;
export const DELAY_FOR_DBCLICK = 200;
export const CLICK_TO_CELL_EDIT = 'click';
export const DBCLICK_TO_CELL_EDIT = 'dbclick';

View File

@@ -0,0 +1,153 @@
/* eslint react/prop-types: 0 */
/* eslint no-return-assign: 0 */
/* eslint class-methods-use-this: 0 */
/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
import React, { Component } from 'react';
import cs from 'classnames';
import PropTypes from 'prop-types';
import TextEditor from './text-editor';
import EditorIndicator from './editor-indicator';
import { TIME_TO_CLOSE_MESSAGE } from './const';
export default _ =>
class EditingCell extends Component {
static propTypes = {
row: PropTypes.object.isRequired,
column: PropTypes.object.isRequired,
onUpdate: PropTypes.func.isRequired,
onEscape: PropTypes.func.isRequired,
timeToCloseMessage: PropTypes.number,
className: PropTypes.string,
style: PropTypes.object
}
static defaultProps = {
timeToCloseMessage: TIME_TO_CLOSE_MESSAGE,
className: null,
style: {}
}
constructor(props) {
super(props);
this.indicatorTimer = null;
this.clearTimer = this.clearTimer.bind(this);
this.handleBlur = this.handleBlur.bind(this);
this.handleClick = this.handleClick.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.beforeComplete = this.beforeComplete.bind(this);
this.state = {
invalidMessage: null
};
}
componentWillReceiveProps({ message }) {
if (_.isDefined(message)) {
this.createTimer();
this.setState(() => ({
invalidMessage: message
}));
}
}
componentWillUnmount() {
this.clearTimer();
}
clearTimer() {
if (this.indicatorTimer) {
clearTimeout(this.indicatorTimer);
}
}
createTimer() {
this.clearTimer();
const { timeToCloseMessage, onErrorMessageDisappear } = this.props;
this.indicatorTimer = _.sleep(() => {
this.setState(() => ({
invalidMessage: null
}));
if (_.isFunction(onErrorMessageDisappear)) onErrorMessageDisappear();
}, timeToCloseMessage);
}
beforeComplete(row, column, newValue) {
const { onUpdate } = this.props;
if (_.isFunction(column.validator)) {
const validateForm = column.validator(newValue, row, column);
if (_.isObject(validateForm) && !validateForm.valid) {
this.setState(() => ({
invalidMessage: validateForm.message
}));
this.createTimer();
return;
}
}
onUpdate(row, column, newValue);
}
handleBlur() {
const { onEscape, blurToSave, row, column } = this.props;
if (blurToSave) {
const value = this.editor.text.value;
if (!_.isDefined(value)) {
// TODO: for other custom or embed editor
}
this.beforeComplete(row, column, value);
} else {
onEscape();
}
}
handleKeyDown(e) {
const { onEscape, row, column } = this.props;
if (e.keyCode === 27) { // ESC
onEscape();
} else if (e.keyCode === 13) { // ENTER
const value = e.currentTarget.value;
if (!_.isDefined(value)) {
// TODO: for other custom or embed editor
}
this.beforeComplete(row, column, value);
}
}
handleClick(e) {
if (e.target.tagName !== 'TD') {
// To avoid the row selection event be triggered,
// When user define selectRow.clickToSelect and selectRow.clickToEdit
// We shouldn't trigger selection event even if user click on the cell editor(input)
e.stopPropagation();
}
}
render() {
const { invalidMessage } = this.state;
const { row, column, className, style } = this.props;
const { dataField } = column;
const value = _.get(row, dataField);
const editorAttrs = {
onKeyDown: this.handleKeyDown,
onBlur: this.handleBlur
};
const hasError = _.isDefined(invalidMessage);
const editorClass = hasError ? cs('animated', 'shake') : null;
return (
<td
className={ cs('react-bootstrap-table-editing-cell', className) }
style={ style }
onClick={ this.handleClick }
>
<TextEditor
ref={ node => this.editor = node }
defaultValue={ value }
className={ editorClass }
{ ...editorAttrs }
/>
{ hasError ? <EditorIndicator invalidMessage={ invalidMessage } /> : null }
</td>
);
}
};

View File

@@ -0,0 +1,135 @@
/* eslint react/prop-types: 0 */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const';
export default (
Base,
{ _, remoteResolver }
) => {
let EditingCell;
return class CellEditWrapper extends remoteResolver(Component) {
static propTypes = {
options: PropTypes.shape({
mode: PropTypes.oneOf([CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT]).isRequired,
onErrorMessageDisappear: PropTypes.func,
blurToSave: PropTypes.bool,
beforeSaveCell: PropTypes.func,
afterSaveCell: PropTypes.func,
nonEditableRows: PropTypes.func,
timeToCloseMessage: PropTypes.number,
errorMessage: PropTypes.string
})
}
constructor(props) {
super(props);
EditingCell = props.cellEdit.editingCellFactory(_);
this.startEditing = this.startEditing.bind(this);
this.escapeEditing = this.escapeEditing.bind(this);
this.completeEditing = this.completeEditing.bind(this);
this.handleCellUpdate = this.handleCellUpdate.bind(this);
this.state = {
ridx: null,
cidx: null,
message: null,
isDataChanged: false
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.cellEdit && this.isRemoteCellEdit()) {
if (nextProps.cellEdit.options.errorMessage) {
this.setState(() => ({
isDataChanged: false,
message: nextProps.cellEdit.options.errorMessage
}));
} else {
this.setState(() => ({
isDataChanged: true
}));
this.escapeEditing();
}
} else {
this.setState(() => ({
isDataChanged: false
}));
}
}
handleCellUpdate(row, column, newValue) {
const { keyField, cellEdit, store } = this.props;
const { beforeSaveCell, afterSaveCell } = cellEdit.options;
const oldValue = _.get(row, column.dataField);
const rowId = _.get(row, keyField);
if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
if (this.isRemoteCellEdit()) {
this.handleCellChange(rowId, column.dataField, newValue);
} else {
store.edit(rowId, column.dataField, newValue);
if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column);
this.completeEditing();
}
}
completeEditing() {
this.setState(() => ({
ridx: null,
cidx: null,
message: null,
isDataChanged: true
}));
}
startEditing(ridx, cidx) {
const editing = () => {
this.setState(() => ({
ridx,
cidx,
isDataChanged: false
}));
};
const { selectRow } = this.props;
if (!selectRow || (selectRow.clickToEdit || !selectRow.clickToSelect)) editing();
}
escapeEditing() {
this.setState(() => ({
ridx: null,
cidx: null
}));
}
render() {
const { isDataChanged, ...stateRest } = this.state;
const {
cellEdit: {
options: { nonEditableRows, errorMessage, ...optionsRest },
editingCellFactory,
...cellEditRest
}
} = this.props;
const newCellEdit = {
...optionsRest,
...cellEditRest,
...stateRest,
EditingCell,
nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [],
onStart: this.startEditing,
onEscape: this.escapeEditing,
onUpdate: this.handleCellUpdate
};
return (
<Base
{ ...this.props }
data={ this.props.store.data }
isDataChanged={ isDataChanged }
cellEdit={ newCellEdit }
/>
);
}
};
};

View File

@@ -1,12 +1,23 @@
/* eslint react/prop-types: 0 */
import 'jsdom-global/register';
import React from 'react';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
import { TableRowWrapper } from '../test-helpers/table-wrapper';
import EditingCell from '../../src/cell-edit/editing-cell';
import TextEditor from '../../src/cell-edit/text-editor';
import EditorIndicator from '../../src/cell-edit/editor-indicator';
import _ from 'react-bootstrap-table-next/src/utils';
import editingCellFactory from '../src/editing-cell';
import TextEditor from '../src/text-editor';
import EditorIndicator from '../src/editor-indicator';
const EditingCell = editingCellFactory(_);
const TableRowWrapper = props => (
<table>
<tbody>
<tr>{ props.children }</tr>
</tbody>
</table>
);
describe('EditingCell', () => {
let wrapper;

View File

@@ -2,7 +2,7 @@ import 'jsdom-global/register';
import React from 'react';
import { mount } from 'enzyme';
import TextEditor from '../../src/cell-edit/text-editor';
import TextEditor from '../src/text-editor';
describe('TextEditor', () => {
let wrapper;

View File

@@ -0,0 +1,330 @@
import React from 'react';
import sinon from 'sinon';
import { shallow } from 'enzyme';
import _ from 'react-bootstrap-table-next/src/utils';
import remoteResolver from 'react-bootstrap-table-next/src/props-resolver/remote-resolver';
import Store from 'react-bootstrap-table-next/src/store';
import BootstrapTable from 'react-bootstrap-table-next/src/bootstrap-table';
import cellEditFactory from '..';
import * as Const from '../src/const';
import wrapperFactory from '../src/wrapper';
describe('CellEditWrapper', () => {
let wrapper;
let instance;
const onTableChangeCB = sinon.stub();
const columns = [{
dataField: 'id',
text: 'ID'
}, {
dataField: 'name',
text: 'Name'
}];
const data = [{
id: 1,
name: 'A'
}, {
id: 2,
name: 'B'
}];
const createTableProps = (props = {}) => {
const { cellEdit, ...rest } = props;
const tableProps = {
keyField: 'id',
columns,
data,
_,
store: new Store('id'),
cellEdit: cellEditFactory(cellEdit),
onTableChange: onTableChangeCB,
...rest
};
tableProps.store.data = data;
return tableProps;
};
const CellEditWrapper = wrapperFactory(BootstrapTable, {
_,
remoteResolver
});
const createCellEditWrapper = (props, renderFragment = true) => {
wrapper = shallow(<CellEditWrapper { ...props } />);
instance = wrapper.instance();
if (renderFragment) {
const fragment = instance.render();
wrapper = shallow(<div>{ fragment }</div>);
}
};
afterEach(() => {
onTableChangeCB.reset();
});
beforeEach(() => {
const props = createTableProps({
cellEdit: { mode: Const.CLICK_TO_CELL_EDIT }
});
createCellEditWrapper(props);
});
it('should render CellEditWrapper correctly', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find(BootstrapTable)).toBeDefined();
});
it('should have correct state', () => {
expect(instance.state.ridx).toBeNull();
expect(instance.state.cidx).toBeNull();
expect(instance.state.message).toBeNull();
expect(instance.state.isDataChanged).toBeFalsy();
});
it('should inject correct props to base component', () => {
const base = wrapper.find(BootstrapTable);
expect(base.props().cellEdit).toBeDefined();
expect(base.props().cellEdit.onStart).toBeDefined();
expect(base.props().cellEdit.onEscape).toBeDefined();
expect(base.props().cellEdit.onUpdate).toBeDefined();
expect(base.props().cellEdit.EditingCell).toBeDefined();
expect(base.props().cellEdit.ridx).toBeNull();
expect(base.props().cellEdit.cidx).toBeNull();
expect(base.props().cellEdit.message).toBeNull();
expect(base.props().isDataChanged).toBe(instance.state.isDataChanged);
});
describe('when receive new cellEdit prop', () => {
const spy = jest.spyOn(CellEditWrapper.prototype, 'escapeEditing');
describe('and cellEdit is not work on remote', () => {
beforeEach(() => {
const props = createTableProps({
cellEdit: { mode: Const.CLICK_TO_CELL_EDIT }
});
createCellEditWrapper(props);
wrapper.setProps({ cellEdit: props.cellEdit });
});
it('should always setting state.isDataChanged as false', () => {
expect(instance.state.isDataChanged).toBeFalsy();
});
});
describe('and cellEdit is work on remote', () => {
let errorMessage;
let props;
beforeEach(() => {
props = createTableProps({
cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
remote: true
});
});
describe('and cellEdit.errorMessage is defined', () => {
beforeEach(() => {
createCellEditWrapper(props, false);
errorMessage = 'test';
const newCellEdit = {
...props.cellEdit,
options: { ...props.cellEdit.options, errorMessage }
};
wrapper.setProps({ cellEdit: newCellEdit });
});
it('should setting correct state', () => {
expect(instance.state.isDataChanged).toBeFalsy();
expect(instance.state.message).toEqual(errorMessage);
});
});
describe('and cellEdit.errorMessage is undefined', () => {
beforeEach(() => {
errorMessage = null;
createCellEditWrapper(props, false);
const newCellEdit = {
...props.cellEdit,
options: { ...props.cellEdit.options, errorMessage }
};
wrapper.setProps({ cellEdit: newCellEdit });
});
it('should setting correct state', () => {
expect(wrapper.state().isDataChanged).toBeTruthy();
});
it('should escape current editing', () => {
expect(spy).toHaveBeenCalled();
});
});
});
});
describe('call escapeEditing function', () => {
it('should set state correctly', () => {
instance.escapeEditing();
expect(instance.state.ridx).toBeNull();
expect(instance.state.cidx).toBeNull();
});
});
describe('call startEditing function', () => {
const ridx = 1;
const cidx = 3;
it('should set state correctly', () => {
instance.startEditing(ridx, cidx);
expect(instance.state.ridx).toEqual(ridx);
expect(instance.state.cidx).toEqual(cidx);
expect(instance.state.isDataChanged).toBeFalsy();
});
describe('if selectRow.clickToSelect is defined', () => {
beforeEach(() => {
const selectRow = { mode: 'checkbox', clickToSelect: true };
const props = createTableProps({
cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
selectRow
});
createCellEditWrapper(props);
});
it('should not set state', () => {
instance.startEditing(ridx, cidx);
expect(instance.state.ridx).toBeNull();
expect(instance.state.cidx).toBeDefined();
});
});
describe('if selectRow.clickToSelect and selectRow.clickToEdit is defined', () => {
beforeEach(() => {
const selectRow = { mode: 'checkbox', clickToSelect: true, clickToEdit: true };
const props = createTableProps({
cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
selectRow
});
createCellEditWrapper(props);
});
it('should set state correctly', () => {
instance.startEditing(ridx, cidx);
expect(instance.state.ridx).toEqual(ridx);
expect(instance.state.cidx).toEqual(cidx);
});
});
});
describe('call completeEditing function', () => {
it('should set state correctly', () => {
instance.completeEditing();
expect(instance.state.ridx).toBeNull();
expect(instance.state.cidx).toBeNull();
expect(instance.state.message).toBeNull();
expect(instance.state.isDataChanged).toBeTruthy();
});
});
describe('call handleCellUpdate function', () => {
let props;
const row = data[0];
const column = columns[1];
const newValue = 'new name';
describe('when cell edit is work on remote', () => {
const spy = jest.spyOn(CellEditWrapper.prototype, 'handleCellChange');
beforeEach(() => {
props = createTableProps({
cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
remote: true
});
createCellEditWrapper(props);
instance.handleCellUpdate(row, column, newValue);
});
it('should calling handleCellChange correctly', () => {
expect(spy).toHaveBeenCalled();
expect(spy.mock.calls).toHaveLength(1);
expect(spy.mock.calls[0]).toHaveLength(3);
expect(spy.mock.calls[0][0]).toEqual(row.id);
expect(spy.mock.calls[0][1]).toEqual(column.dataField);
expect(spy.mock.calls[0][2]).toEqual(newValue);
});
});
describe('when cell edit is not work on remote', () => {
const spyOnCompleteEditing = jest.spyOn(CellEditWrapper.prototype, 'completeEditing');
const spyOnStoreEdit = jest.spyOn(Store.prototype, 'edit');
beforeEach(() => {
props = createTableProps({
cellEdit: { mode: Const.CLICK_TO_CELL_EDIT }
});
createCellEditWrapper(props);
instance.handleCellUpdate(row, column, newValue);
});
afterEach(() => {
spyOnStoreEdit.mockReset();
spyOnCompleteEditing.mockReset();
});
it('should calling props.store.edit', () => {
expect(spyOnStoreEdit).toHaveBeenCalled();
expect(spyOnStoreEdit.mock.calls).toHaveLength(1);
expect(spyOnStoreEdit.mock.calls[0]).toHaveLength(3);
expect(spyOnStoreEdit.mock.calls[0][0]).toEqual(row.id);
expect(spyOnStoreEdit.mock.calls[0][1]).toEqual(column.dataField);
expect(spyOnStoreEdit.mock.calls[0][2]).toEqual(newValue);
});
it('should calling completeEditing function', () => {
expect(spyOnCompleteEditing).toHaveBeenCalled();
});
describe('if cellEdit.afterSaveCell prop defined', () => {
const aftereSaveCellCallBack = sinon.stub();
beforeEach(() => {
props = createTableProps({
cellEdit: {
mode: Const.CLICK_TO_CELL_EDIT,
afterSaveCell: aftereSaveCellCallBack
}
});
createCellEditWrapper(props);
instance.handleCellUpdate(row, column, newValue);
});
it('should calling cellEdit.afterSaveCell correctly', () => {
expect(aftereSaveCellCallBack.callCount).toBe(1);
expect(aftereSaveCellCallBack.calledWith(
row[column.dataField], newValue, row, column)
).toBe(true);
});
});
});
describe('if cellEdit.beforeSaveCell prop defined', () => {
const beforeSaveCellCallBack = sinon.stub();
beforeEach(() => {
props = createTableProps({
cellEdit: {
mode: Const.CLICK_TO_CELL_EDIT,
beforeSaveCell: beforeSaveCellCallBack
}
});
createCellEditWrapper(props);
instance.handleCellUpdate(row, column, newValue);
});
it('should calling cellEdit.beforeSaveCell correctly', () => {
expect(beforeSaveCellCallBack.callCount).toBe(1);
expect(beforeSaveCellCallBack.calledWith(
row[column.dataField], newValue, row, column)
).toBe(true);
});
});
});
});

View File

@@ -0,0 +1,4 @@
{
"presets": ["react", "es2015", "stage-0", ["env", {"modules": false} ]],
"plugins": ["transform-class-properties"]
}

View File

@@ -1,11 +1,13 @@
const path = require('path');
const sourcePath = path.join(__dirname, '../../react-bootstrap-table2/src');
const paginationSourcePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/src');
const overlaySourcePath = path.join(__dirname, '../../react-bootstrap-table2-overlay/src');
const filterSourcePath = path.join(__dirname, '../../react-bootstrap-table2-filter/src');
const sourcePath = path.join(__dirname, '../../react-bootstrap-table2/index.js');
const paginationSourcePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/index.js');
const overlaySourcePath = path.join(__dirname, '../../react-bootstrap-table2-overlay/index.js');
const filterSourcePath = path.join(__dirname, '../../react-bootstrap-table2-filter/index.js');
const editorSourcePath = path.join(__dirname, '../../react-bootstrap-table2-editor/index.js');
const sourceStylePath = path.join(__dirname, '../../react-bootstrap-table2/style');
const paginationStylePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/style');
const filterStylePath = path.join(__dirname, '../../react-bootstrap-table2-filter/style');
const storyPath = path.join(__dirname, '../stories');
const examplesPath = path.join(__dirname, '../examples');
const srcPath = path.join(__dirname, '../src');
@@ -15,6 +17,12 @@ const aliasPath = {
src: srcPath,
components: path.join(srcPath, 'components'),
utils: path.join(srcPath, 'utils'),
'react-bootstrap-table-next': sourcePath,
'react-bootstrap-table2-editor': editorSourcePath,
'react-bootstrap-table2-filter': filterSourcePath,
'react-bootstrap-table2-overlay': overlaySourcePath,
'react-bootstrap-table2-paginator': paginationSourcePath,
};
const loaders = [{
@@ -26,15 +34,14 @@ const loaders = [{
}, {
test: /\.js?$/,
use: ['babel-loader'],
exclude: /node_modules/,
include: [sourcePath, paginationSourcePath, overlaySourcePath, filterSourcePath, storyPath],
exclude: /node_modules/
}, {
test: /\.css$/,
use: ['style-loader', 'css-loader'],
}, {
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: [storyPath, sourceStylePath, paginationStylePath],
include: [storyPath, sourceStylePath, paginationStylePath, filterStylePath],
}, {
test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000',

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +18,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
// omit...
<BootstrapTable
keyField="id"
data={ products }

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +18,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +18,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
const columns = [{
@@ -15,9 +15,12 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
// omit...
<BootstrapTable keyField='id' data={ [] } columns={ columns } noDataIndication="Table is Empty" />
// Following is more customizable example
// Following is a more flexible example
function indication() {
// return something here

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +18,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
// omit...
<BootstrapTable
keyField="id"
data={ products }

View File

@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +19,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,26 +33,28 @@ const columns = [{
text: 'Product Price'
}];
const cellEdit = {
mode: 'click',
blurToSave: true
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true
}) }
/>
`;
const cellEdit = {
mode: 'click',
blurToSave: true
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true
}) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,7 +1,8 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -22,6 +23,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -36,24 +40,22 @@ const columns = [{
(cell > 2101 ? 'editing-price-bigger-than-2101' : 'editing-price-small-than-2101')
}];
const cellEdit = {
mode: 'click'
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
`;
const cellEdit = {
mode: 'click'
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -2,7 +2,8 @@
/* eslint no-console: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +21,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -31,28 +35,30 @@ const columns = [{
text: 'Product Price'
}];
const cellEdit = {
mode: 'click',
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({
mode: 'click',
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
}) }
/>
`;
const cellEdit = {
mode: 'click',
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({
mode: 'click',
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
}) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,7 +1,8 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -26,6 +27,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -44,24 +48,22 @@ const columns = [{
}
}];
const cellEdit = {
mode: 'click'
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
`;
const cellEdit = {
mode: 'click'
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,7 @@
import React from 'react';
/* eslint no-unused-vars: 0 */
import BootstrapTable from 'react-bootstrap-table2';
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -33,6 +34,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -59,27 +63,29 @@ const columns = [{
}
}];
const cellEdit = {
mode: 'click',
blurToSave: true
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true
}) }
/>
`;
const cellEdit = {
mode: 'click',
blurToSave: true
};
export default () => (
<div>
<h3>Product Price should bigger than $2000</h3>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true
}) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,75 +0,0 @@
/* eslint no-unused-vars: 0 */
/* eslint arrow-body-style: 0 */
import React, { Component } from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import Code from 'components/common/code-block';
import { productsGenerator, sleep } 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 = `\
class CellEditWithPromise extends Component {
handleCellEditing = (rowId, dataField, newValue) => {
return sleep(1000).then(() => {
if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) {
throw new Error('Product Price should bigger than $2000');
}
});
}
render() {
const cellEdit = {
mode: 'click',
blurToSave: true,
onUpdate: this.handleCellEditing
};
return (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<Code>{ sourceCode }</Code>
</div>
);
}
}
`;
class CellEditWithPromise extends Component {
handleCellEditing = (rowId, dataField, newValue) => {
return sleep(1000).then(() => {
if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) {
throw new Error('Product Price should bigger than $2000');
}
});
}
render() {
const cellEdit = {
mode: 'click',
blurToSave: true,
onUpdate: this.handleCellEditing
};
return (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<Code>{ sourceCode }</Code>
</div>
);
}
}
export default CellEditWithPromise;

View File

@@ -1,212 +0,0 @@
/* eslint no-unused-vars: 0 */
/* eslint react/prop-types: 0 */
/* eslint arrow-body-style: 0 */
/* eslint consistent-return: 0 */
/* eslint no-class-assign: 0 */
import React, { Component } from 'react';
import thunk from 'redux-thunk';
import { Provider, connect } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import BootstrapTable from 'react-bootstrap-table2';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price'
}];
const sourceCode = `\
/////////////////////// Action Creator ///////////////////////
const setErrorMessage = (errorMessage = null) => {
return { type: 'SET_ERR_MESSAGE', errorMessage };
};
// Async Action, using redux-thunk
const cellEditingAsync = (rowId, dataField, newValue) => {
return (dispatch) => {
setTimeout(() => {
if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) {
dispatch(setErrorMessage('Product Price should bigger than $2000'));
} else {
dispatch({ type: 'ADD_SUCCESS', rowId, dataField, newValue });
}
}, 1200);
};
};
/////////////////////// Component ///////////////////////
class CellEditWithRedux extends Component {
// dispatch a async action
handleCellEditing = (rowId, dataField, newValue) => {
this.props.dispatch(cellEditingAsync(rowId, dataField, newValue));
return false;
}
handleErrorMsgDisappear = () => {
this.props.dispatch(setErrorMessage());
}
render() {
const cellEdit = {
mode: 'click',
editing: this.props.cellEditing,
errorMessage: this.props.errorMessage,
onUpdate: this.handleCellEditing,
onErrorMessageDisappear: this.handleErrorMsgDisappear
};
return (
<div>
<BootstrapTable keyField="id" data={ this.props.data } columns={ columns } cellEdit={ cellEdit } />
<Code>{ sourceCode }</Code>
</div>
);
}
}
// connect
CellEditWithRedux = connect(state => state)(CellEditWithRedux);
/////////////////////// Reducer ///////////////////////
// initial state object and simple reducers
const initialState = {
data: productsGenerator(),
cellEditing: false,
errorMessage: null
};
const reducers = (state, action) => {
switch (action.type) {
case 'ADD_SUCCESS': {
const { rowId, dataField, newValue } = action;
const data = [...state.data];
const rowIndex = data.findIndex(r => r.id === rowId);
data[rowIndex][dataField] = newValue;
return {
data,
cellEditing: false,
errorMessage: null
};
}
case 'SET_ERR_MESSAGE': {
const { errorMessage } = action;
return {
...state,
cellEditing: true,
errorMessage
};
}
default: {
return { ...state };
}
}
};
/////////////////////// Index ///////////////////////
const store = createStore(reducers, initialState, applyMiddleware(thunk));
const Index = () => (
<Provider store={store}>
<CellEditWithRedux />
</Provider>
);
`;
const setErrorMessage = (errorMessage = null) => {
return { type: 'SET_ERR_MESSAGE', errorMessage };
};
// Async Action, using redux-thunk
const cellEditingAsync = (rowId, dataField, newValue) => {
return (dispatch) => {
setTimeout(() => {
if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) {
dispatch(setErrorMessage('Product Price should bigger than $2000'));
} else {
dispatch({ type: 'ADD_SUCCESS', rowId, dataField, newValue });
}
}, 1200);
};
};
class CellEditWithRedux extends Component {
// dispatch a async action
handleCellEditing = (rowId, dataField, newValue) => {
this.props.dispatch(cellEditingAsync(rowId, dataField, newValue));
return false;
}
handleErrorMsgDisappear = () => {
this.props.dispatch(setErrorMessage());
}
render() {
const cellEdit = {
mode: 'click',
editing: this.props.cellEditing,
errorMessage: this.props.errorMessage,
onUpdate: this.handleCellEditing,
onErrorMessageDisappear: this.handleErrorMsgDisappear
};
return (
<div>
<BootstrapTable keyField="id" data={ this.props.data } columns={ columns } cellEdit={ cellEdit } />
<Code>{ sourceCode }</Code>
</div>
);
}
}
// connect
CellEditWithRedux = connect(state => state)(CellEditWithRedux);
// initial state object and simple reducers
const initialState = {
data: productsGenerator(),
cellEditing: false,
errorMessage: null
};
const reducers = (state, action) => {
switch (action.type) {
case 'ADD_SUCCESS': {
const { rowId, dataField, newValue } = action;
const data = JSON.parse(JSON.stringify(state.data));
const rowIndex = data.findIndex(r => r.id === rowId);
data[rowIndex][dataField] = newValue;
return {
data,
cellEditing: false,
errorMessage: null
};
}
case 'SET_ERR_MESSAGE': {
const { errorMessage } = action;
return {
...state,
cellEditing: true,
errorMessage
};
}
default: {
return { ...state };
}
}
};
const store = createStore(reducers, initialState, applyMiddleware(thunk));
const Index = () => (
<Provider store={ store }>
<CellEditWithRedux />
</Provider>
);
export default Index;

View File

@@ -1,7 +1,8 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +21,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -32,24 +36,23 @@ const columns = [{
editable: (content, row, rowIndex, columnIndex) => content > 2101
}];
const cellEdit = {
mode: 'click'
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
`;
const cellEdit = {
mode: 'click'
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<h3>Only Product Price is bigger than 2101 is editable</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,8 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +20,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,24 +34,23 @@ const columns = [{
text: 'Product Price'
}];
const cellEdit = {
mode: 'click'
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
`;
const cellEdit = {
mode: 'click'
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<h3>Click to edit cell</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -19,6 +20,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -32,26 +36,29 @@ const columns = [{
text: 'Product Price'
}];
const cellEdit = {
mode: 'click',
blurToSave: true
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true
}) }
/>
`;
const cellEdit = {
mode: 'click',
blurToSave: true
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<h3>Product Name is non editable</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true
}) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +19,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,24 +33,23 @@ const columns = [{
text: 'Product Price'
}];
const cellEdit = {
mode: 'dbclick'
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({ mode: 'dbclick' }) }
/>
`;
const cellEdit = {
mode: 'dbclick'
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<h3>Double click to edit cell</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'dbclick' }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +19,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,29 +33,30 @@ const columns = [{
text: 'Product Price'
}];
const cellEdit = {
mode: 'click',
blurToSave: true,
// Product ID: 0, 3 will be non-editable
nonEditableRows: () => [0, 3]
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEdit }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true,
nonEditableRows: () => [0, 3]
}) }
/>
`;
const cellEdit = {
mode: 'click',
blurToSave: true,
nonEditableRows: () => [0, 3]
};
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
<h3>Product ID: 0, 3 is non editable</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true,
nonEditableRows: () => [0, 3]
}) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,6 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { jobsGenerator } from 'utils/common';
@@ -32,6 +32,7 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const owners = ['Allen', 'Bob', 'Cat'];

View File

@@ -0,0 +1,80 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsQualityGenerator } from 'utils/common';
const products = productsQualityGenerator(6);
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions,
withoutEmptyOption: true,
style: {
backgroundColor: 'pink'
},
className: 'test-classname',
datamycustomattr: 'datamycustomattr'
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions,
withoutEmptyOption: true,
style: {
backgroundColor: 'pink'
},
className: 'test-classname',
datamycustomattr: 'datamycustomattr'
})
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,6 @@
/* eslint no-console: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -29,6 +29,7 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const columns = [{

View File

@@ -0,0 +1,70 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsQualityGenerator } from 'utils/common';
const products = productsQualityGenerator(6);
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions,
defaultValue: 2
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions,
defaultValue: 2
})
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,69 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(6);
const selectOptions = {
'03': '03',
'04': '04',
'01': '01'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: selectFilter({
options: selectOptions,
comparator: Comparator.LIKE // default is Comparator.EQ
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
const selectOptions = {
'03': '03',
'04': '04',
'01': '01'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: selectFilter({
options: selectOptions,
comparator: Comparator.LIKE // default is Comparator.EQ
})
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
`;
export default () => (
<div>
<h3>Select Filter with LIKE Comparator</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,68 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsQualityGenerator } from 'utils/common';
const products = productsQualityGenerator(6);
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions
})
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,5 +1,5 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -22,6 +22,7 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const columns = [{

View File

@@ -1,5 +1,5 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -22,6 +22,7 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, Comparator } from 'react-bootstrap-table2-filter';
const columns = [{

View File

@@ -1,5 +1,5 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +20,7 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const columns = [{

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -24,6 +24,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -21,6 +21,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',
@@ -39,6 +41,7 @@ const columns = [{
export default () => (
<div>
<h3>Try to hover on Product Name header column</h3>
<BootstrapTable keyField="id" data={ products } columns={ columns } />
<Code>{ sourceCode }</Code>
</div>

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -24,6 +24,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -2,7 +2,7 @@
/* eslint no-alert: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -23,6 +23,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -31,6 +31,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
function priceFormatter(cell, row) {
if (row.onSale) {
return (

View File

@@ -1,7 +1,7 @@
/* eslint no-console: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -34,6 +34,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
function rankFormatter(cell, row, rowIndex, formatExtraData) {
return (
<i className={ formatExtraData[cell] } />

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +20,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -33,6 +33,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -39,6 +39,7 @@ const columns = [{
export default () => (
<div>
<h3>Try to hover on any Product Name cells</h3>
<BootstrapTable keyField="id" data={ products } columns={ columns } />
<Code>{ sourceCode }</Code>
</div>

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -32,6 +32,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'User ID'

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -21,6 +21,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -21,6 +21,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -24,6 +24,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -2,7 +2,7 @@
/* eslint no-alert: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -23,6 +23,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -2,7 +2,7 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -41,6 +41,7 @@ const defaultSorted = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
// ...
function priceFormatter(column, colIndex, { sortElement, filterElement }) {

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -26,6 +26,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
function priceFormatter(column, colIndex) {
return (
<h5><strong>$$ { column.text } $$</strong></h5>

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -32,6 +32,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -21,6 +21,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,8 +1,8 @@
/* eslint react/no-multi-comp: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,8 +20,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
// ...
const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
<div>
@@ -30,7 +30,7 @@ const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize })
keyField="id"
data={ data }
columns={ columns }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
/>
<Code>{ sourceCode }</Code>
@@ -90,7 +90,7 @@ const Table = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
keyField="id"
data={ data }
columns={ columns }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
noDataIndication={ () => <NoDataIndication /> }
/>
@@ -116,7 +116,7 @@ class EmptyTableOverlay extends React.Component {
};
}
handleTableChange = ({ page, sizePerPage }) => {
handleTableChange = (type, { page, sizePerPage }) => {
const currentIndex = (page - 1) * sizePerPage;
setTimeout(() => {
this.setState(() => ({

View File

@@ -1,8 +1,8 @@
/* eslint react/no-multi-comp: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import overlayFactory from 'react-bootstrap-table2-overlay';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -21,8 +21,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import overlayFactory from 'react-bootstrap-table2-overlay';
// ...
@@ -34,7 +34,7 @@ const RemotePagination = ({ loading, data, page, sizePerPage, onTableChange, tot
keyField="id"
data={ data }
columns={ columns }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
overlay={ overlayFactory({ spinner: true, background: 'rgba(192,192,192,0.3)' }) }
/>
@@ -99,7 +99,7 @@ const RemotePagination = ({ loading, data, page, sizePerPage, onTableChange, tot
keyField="id"
data={ data }
columns={ columns }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
overlay={ overlayFactory({ spinner: true, background: 'rgba(192,192,192,0.3)' }) }
/>
@@ -127,7 +127,7 @@ class Container extends React.Component {
};
}
handleTableChange = ({ page, sizePerPage }) => {
handleTableChange = (type, { page, sizePerPage }) => {
const currentIndex = (page - 1) * sizePerPage;
setTimeout(() => {
this.setState(() => ({

View File

@@ -1,8 +1,8 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,8 +20,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
// ...
const options = {
@@ -48,7 +48,7 @@ const options = {
}] // A numeric array is also available. the purpose of above example is custom the text
};
<BootstrapTable keyField='id' data={ products } columns={ columns } pagination={ paginator(options) } />
<BootstrapTable keyField='id' data={ products } columns={ columns } pagination={ paginationFactory(options) } />
`;
const options = {
paginationSize: 4,
@@ -76,7 +76,7 @@ const options = {
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginator(options) } />
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory(options) } />
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,8 +1,8 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,9 +20,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
// ...
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -34,12 +34,12 @@ const columns = [{
text: 'Product Price'
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } pagination={ paginator() } />
<BootstrapTable keyField='id' data={ products } columns={ columns } pagination={ paginationFactory() } />
`;
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginator() } />
<BootstrapTable keyField="id" data={ products } columns={ columns } pagination={ paginationFactory() } />
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -2,8 +2,8 @@
/* eslint no-console: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -21,9 +21,9 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
// ...
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -52,7 +52,7 @@ const options = {
keyField="id"
data={ products }
columns={ columns }
pagination={ paginator(options) }
pagination={ paginationFactory(options) }
/>
`;
@@ -75,7 +75,7 @@ export default () => (
keyField="id"
data={ products }
columns={ columns }
pagination={ paginator(options) }
pagination={ paginationFactory(options) }
/>
<Code>{ sourceCode }</Code>
</div>

View File

@@ -2,8 +2,8 @@
/* eslint no-restricted-syntax: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import filterFactory, { textFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -24,8 +24,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import filterFactory, { textFilter, Comparator } from 'react-bootstrap-table2-filter';
// ...
@@ -50,7 +50,7 @@ const RemoteAll = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
data={ data }
columns={ columns }
filter={ filterFactory() }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
/>
<Code>{ sourceCode }</Code>
@@ -130,7 +130,7 @@ const RemoteAll = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
data={ data }
columns={ columns }
filter={ filterFactory() }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
/>
<Code>{ sourceCode }</Code>

View File

@@ -0,0 +1,164 @@
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
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';
import cellEditFactory from 'react-bootstrap-table2-editor';
// ...
const RemoteCellEdit = (props) => {
const cellEdit = {
mode: 'click',
errorMessage: props.errorMessage
};
return (
<div>
<BootstrapTable
remote={ { cellEdit: true } }
keyField="id"
data={ props.data }
columns={ columns }
cellEdit={ cellEditFactory(cellEdit) }
onTableChange={ props.onTableChange }
/>
<Code>{ sourceCode }</Code>
</div>
);
};
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
data: products,
errorMessage: null
};
}
handleTableChange = (type, { data, cellEdit: { rowId, dataField, newValue } }) => {
setTimeout(() => {
if (newValue === 'test' && dataField === 'name') {
this.setState(() => ({
data,
errorMessage: 'Oops, product name shouldn't be "test"'
}));
} else {
const result = data.map((row) => {
if (row.id === rowId) {
const newRow = { ...row };
newRow[dataField] = newValue;
return newRow;
}
return row;
});
this.setState(() => ({
data: result,
errorMessage: null
}));
}
}, 2000);
}
render() {
return (
<RemoteCellEdit
data={ this.state.data }
errorMessage={ this.state.errorMessage }
onTableChange={ this.handleTableChange }
/>
);
}
}
`;
const RemoteCellEdit = (props) => {
const cellEdit = {
mode: 'click',
errorMessage: props.errorMessage
};
return (
<div>
<BootstrapTable
remote={ { cellEdit: true } }
keyField="id"
data={ props.data }
columns={ columns }
cellEdit={ cellEditFactory(cellEdit) }
onTableChange={ props.onTableChange }
/>
<Code>{ sourceCode }</Code>
</div>
);
};
RemoteCellEdit.propTypes = {
data: PropTypes.array.isRequired,
onTableChange: PropTypes.func.isRequired,
errorMessage: PropTypes.string.isRequired
};
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
data: products,
errorMessage: null
};
}
handleTableChange = (type, { data, cellEdit: { rowId, dataField, newValue } }) => {
setTimeout(() => {
if (newValue === 'test' && dataField === 'name') {
this.setState(() => ({
data,
errorMessage: 'Oops, product name shouldn\'t be "test"'
}));
} else {
const result = data.map((row) => {
if (row.id === rowId) {
const newRow = { ...row };
newRow[dataField] = newValue;
return newRow;
}
return row;
});
this.setState(() => ({
data: result,
errorMessage: null
}));
}
}, 2000);
}
render() {
return (
<RemoteCellEdit
data={ this.state.data }
errorMessage={ this.state.errorMessage }
onTableChange={ this.handleTableChange }
/>
);
}
}
export default Container;

View File

@@ -2,7 +2,7 @@
/* eslint no-restricted-syntax: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -23,6 +23,7 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const columns = [{
@@ -38,7 +39,61 @@ const columns = [{
filter: textFilter()
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
const RemoteFilter = props => (
<div>
<BootstrapTable
remote={ { filter: true } }
keyField="id"
data={ props.data }
columns={ columns }
filter={ filterFactory() }
onTableChange={ props.onTableChange }
/>
<Code>{ sourceCode }</Code>
</div>
);
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
data: products
};
}
handleTableChange = (type, { filters }) => {
setTimeout(() => {
const result = products.filter((row) => {
let valid = true;
for (const dataField in filters) {
const { filterVal, filterType, comparator } = filters[dataField];
if (filterType === 'TEXT') {
if (comparator === Comparator.LIKE) {
valid = row[dataField].toString().indexOf(filterVal) > -1;
} else {
valid = row[dataField] === filterVal;
}
}
if (!valid) break;
}
return valid;
});
this.setState(() => ({
data: result
}));
}, 2000);
}
render() {
return (
<RemoteFilter
data={ this.state.data }
onTableChange={ this.handleTableChange }
/>
);
}
}
`;
const RemoteFilter = props => (

View File

@@ -1,8 +1,8 @@
/* eslint react/no-multi-comp: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,8 +20,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table2';
import paginator from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import paginationFactory from 'react-bootstrap-table2-paginator';
// ...
const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize }) => (
<div>
@@ -30,7 +30,7 @@ const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize })
keyField="id"
data={ data }
columns={ columns }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
/>
<Code>{ sourceCode }</Code>
@@ -47,7 +47,7 @@ class Container extends React.Component {
};
}
handleTableChange = ({ page, sizePerPage }) => {
handleTableChange = (type, { page, sizePerPage }) => {
const currentIndex = (page - 1) * sizePerPage;
setTimeout(() => {
this.setState(() => ({
@@ -80,7 +80,7 @@ const RemotePagination = ({ data, page, sizePerPage, onTableChange, totalSize })
keyField="id"
data={ data }
columns={ columns }
pagination={ paginator({ page, sizePerPage, totalSize }) }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange }
/>
<Code>{ sourceCode }</Code>

View File

@@ -0,0 +1,163 @@
/* eslint no-restricted-syntax: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(5);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
sort: true
}, {
dataField: 'price',
text: 'Product Price',
sort: true
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: textFilter()
}];
const RemoteSort = props => (
<div>
<BootstrapTable
remote={ { sort: true } }
keyField="id"
data={ props.data }
columns={ columns }
onTableChange={ props.onTableChange }
/>
<Code>{ sourceCode }</Code>
</div>
);
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
data: products
};
}
handleTableChange = (type, { sortField, sortOrder, data }) => {
setTimeout(() => {
let result;
if (sortOrder === 'asc') {
result = data.sort((a, b) => {
if (a[sortField] > b[sortField]) {
return 1;
} else if (b[sortField] > a[sortField]) {
return -1;
}
return 0;
});
} else {
result = data.sort((a, b) => {
if (a[sortField] > b[sortField]) {
return -1;
} else if (b[sortField] > a[sortField]) {
return 1;
}
return 0;
});
}
this.setState(() => ({
data: result
}));
}, 2000);
}
render() {
return (
<RemoteSort
data={ this.state.data }
onTableChange={ this.handleTableChange }
/>
);
}
}
`;
const RemoteSort = props => (
<div>
<BootstrapTable
remote={ { sort: true } }
keyField="id"
data={ props.data }
columns={ columns }
onTableChange={ props.onTableChange }
/>
<Code>{ sourceCode }</Code>
</div>
);
RemoteSort.propTypes = {
data: PropTypes.array.isRequired,
onTableChange: PropTypes.func.isRequired
};
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {
data: products
};
}
handleTableChange = (type, { sortField, sortOrder, data }) => {
setTimeout(() => {
let result;
if (sortOrder === 'asc') {
result = data.sort((a, b) => {
if (a[sortField] > b[sortField]) {
return 1;
} else if (b[sortField] > a[sortField]) {
return -1;
}
return 0;
});
} else {
result = data.sort((a, b) => {
if (a[sortField] > b[sortField]) {
return -1;
} else if (b[sortField] > a[sortField]) {
return 1;
}
return 0;
});
}
this.setState(() => ({
data: result
}));
}, 2000);
}
render() {
return (
<RemoteSort
data={ this.state.data }
onTableChange={ this.handleTableChange }
/>
);
}
}
export default Container;

View File

@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -23,11 +24,10 @@ const selectRow = {
clickToEdit: true
};
const cellEdit = {
mode: 'click'
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -50,16 +50,23 @@ const cellEdit = {
};
<BootstrapTable
keyField='id'
keyField="id"
data={ products }
columns={ columns }
selectRow={ selectRow }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
`;
export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow } cellEdit={ cellEdit } />
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
selectRow={ selectRow }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -23,6 +23,8 @@ const selectRow = {
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -25,6 +25,8 @@ const selectRow = {
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -23,6 +23,8 @@ const selectRow = {
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -24,6 +24,8 @@ const selectRow = {
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -31,6 +31,8 @@ const selectRow2 = {
};
const sourceCode1 = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -32,6 +32,8 @@ const selectRow2 = {
};
const sourceCode1 = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -2,7 +2,7 @@
/* eslint no-console: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -34,6 +34,8 @@ const selectRow = {
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -34,6 +34,8 @@ const selectRow2 = {
};
const sourceCode1 = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -23,6 +23,8 @@ const selectRow = {
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +20,8 @@ const columns = [{
const rowClasses1 = 'custom-row-class';
const sourceCode1 = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -1,8 +1,8 @@
/* eslint no-unused-vars: 0 */
/* eslint no-console: 0 */
/* eslint no-alert: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -21,11 +21,13 @@ const columns = [{
const rowEvents = {
onClick: (e) => {
console.log('click on row');
alert('click on row');
}
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -39,15 +41,16 @@ const columns = [{
const rowEvents = {
onClick: (e) => {
console.log('click on row');
alert('click on row');
}
};
<BootstrapTable keyField='id' data={ products } columns={ columns } rowStyle={ rowStyle } />
<BootstrapTable keyField='id' data={ products } columns={ columns } rowEvents={ rowEvents } />
`;
export default () => (
<div>
<h3>Try to click on any rows</h3>
<BootstrapTable keyField="id" data={ products } columns={ columns } rowEvents={ rowEvents } />
<Code>{ sourceCode }</Code>
</div>

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +20,8 @@ const columns = [{
const rowStyle1 = { backgroundColor: '#c8e6c9' };
const sourceCode1 = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID'

View File

@@ -2,7 +2,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -29,6 +29,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',
@@ -54,6 +56,7 @@ const columns = [{
export default () => (
<div>
<h3>Product ID sorting is reverted</h3>
<BootstrapTable keyField="id" data={ products } columns={ columns } />
<Code>{ sourceCode }</Code>
</div>

View File

@@ -1,7 +1,7 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -27,6 +27,8 @@ const defaultSorted = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -1,6 +1,6 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +20,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{
dataField: 'id',
text: 'Product ID',

View File

@@ -5,7 +5,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -31,6 +31,8 @@ const columns = [{
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const headerSortingClasses = (column, sortOrder, isLastSorting, colIndex) => (
sortOrder === 'asc' ? 'demo-sorting-asc' : 'demo-sorting-desc'
);

View File

@@ -1,7 +1,7 @@
/* eslint no-unused-vars: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
import BootstrapTable from 'react-bootstrap-table-next';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -26,6 +26,8 @@ const columns = [{
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const headerSortingStyle = { backgroundColor: '#c8e6c9' };
const columns = [{

View File

@@ -1,12 +1,14 @@
{
"name": "react-bootstrap-table2-example",
"version": "0.0.1",
"version": "0.1.1",
"description": "",
"main": "index.js",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
"gh-pages:clean": "rimraf ./storybook-static",
"gh-pages:build": "build-storybook"
},
"author": "",
"license": "ISC",
@@ -16,15 +18,13 @@
"react-dom": "^15.0.0"
},
"dependencies": {
"bootstrap": "^3.3.7",
"react-bootstrap-table2": "0.0.1",
"react-bootstrap-table2-paginator": "0.0.1",
"react-bootstrap-table2-overlay": "0.0.1",
"react-bootstrap-table2-filter": "0.0.1"
"bootstrap": "^3.3.7"
},
"devDependencies": {
"@storybook/addon-console": "^1.0.0",
"@storybook/react": "^3.2.8",
"babel-plugin-transform-class-properties": "6.24.1",
"babel-preset-env": "^1.6.1",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",

Some files were not shown because too many files have changed in this diff Show More