Compare commits

...

209 Commits

Author SHA1 Message Date
AllenFang
258ea43225 Publish
- react-bootstrap-table2-example@0.1.10
 - react-bootstrap-table2-filter@0.3.0
 - react-bootstrap-table2-paginator@0.1.5
 - react-bootstrap-table-next@0.1.14
2018-06-24 22:42:50 +08:00
Allen
7a7b708029 Merge pull request #390 from react-bootstrap-table/develop
20180624 release
2018-06-24 22:40:15 +08:00
Allen
0cf89861af Merge pull request #389 from react-bootstrap-table/feat/custom-filter
Implement custom filter
2018-06-24 15:33:22 +08:00
AllenFang
eb74625835 patch docs for custom filter 2018-06-24 15:15:57 +08:00
AllenFang
cbaec4c655 add stories for custom filter 2018-06-24 15:04:59 +08:00
AllenFang
04c21cb63d implement custom filter 2018-06-24 15:03:46 +08:00
AllenFang
7d72002b6e fix wrong eslint rule 2018-06-24 13:16:48 +08:00
AllenFang
279cc25da0 Merge branch 'develop' of https://github.com/react-bootstrap-table/react-bootstrap-table2 into develop 2018-06-24 13:16:07 +08:00
AllenFang
1152bb8440 fix #380 2018-06-23 13:49:38 +08:00
AllenFang
88befb8136 fix #380 2018-06-23 13:47:53 +08:00
Allen
42c6bc0337 Merge pull request #371 from sean-ww/fix/remote-filtered-pagination
Prevent remote pagination from setting the page incorrectly
2018-06-23 12:59:02 +08:00
sean
6e753bb955 Prevent remote pagination from setting the page incorrectly 2018-06-06 15:11:54 +02:00
AllenFang
64df3e1fae Publish
- react-bootstrap-table2-example@0.1.9
 - react-bootstrap-table2-filter@0.2.0
 - react-bootstrap-table2-overlay@0.1.2
 - react-bootstrap-table2-paginator@0.1.4
 - react-bootstrap-table-next@0.1.13
2018-06-04 13:53:02 +08:00
Allen
5cdd1ad093 20180604 release #366 from react-bootstrap-table/develop
20180604 release
2018-06-04 13:49:03 +08:00
AllenFang
36e754b6bc patch docs 2018-06-03 22:58:03 +08:00
AllenFang
6730dcf60d fix overlay test bugs 2018-06-03 22:52:15 +08:00
AllenFang
fb54809dc9 fix docs 2018-06-03 21:36:09 +08:00
AllenFang
d43c622fdb fix docs 2018-06-03 21:31:13 +08:00
AllenFang
7253d7a1d7 fix overlay tests 2018-06-03 20:40:31 +08:00
AllenFang
a6daa50417 improve overlay wrapping 2018-06-03 15:50:10 +08:00
AllenFang
b11019ce20 fix #358 2018-06-03 14:49:58 +08:00
Allen
dda47f7b7d Merge pull request #365 from react-bootstrap-table/feat/349
Feat/349
2018-06-03 14:39:22 +08:00
AllenFang
4da8ba7ecc patch docs for date filter 2018-06-03 14:24:20 +08:00
Allen
2ff0b27747 Merge pull request #359 from sean-ww/feature/pagination-total
Adding custom pagination total
2018-06-03 14:18:50 +08:00
AllenFang
c3f279fb0c patch tests for date filter 2018-06-03 14:04:06 +08:00
AllenFang
06bcf1edca add stories for date filter 2018-06-03 14:03:38 +08:00
AllenFang
fc1f75cfac implement date filter 2018-06-03 14:02:39 +08:00
sean
1cf12ab707 paginationTotal renamed to paginationTotalRenderer 2018-06-02 10:43:56 +02:00
Allen
288ccc1049 Merge pull request #364 from react-bootstrap-table/feat/351
Fix #351
2018-06-02 15:37:51 +08:00
AllenFang
f13c139f63 patch docs for custom selection 2018-06-02 15:27:10 +08:00
AllenFang
e72ad0586e add story for custom selection column 2018-06-02 15:20:57 +08:00
AllenFang
c2044fe8b5 patch test for selection box 2018-06-02 15:20:40 +08:00
AllenFang
a7b3690a7c custom selection box 2018-06-02 15:20:19 +08:00
Amol Udage
68afc348db fixes sorting issue (#354)
+ when remote sort is true then disable client side sorting
2018-06-02 13:21:25 +08:00
sean-ww88
5404124a78 Added missing commas on the custom pagination example 2018-05-30 17:35:27 +02:00
sean-ww88
d592871c0d Adding custom pagination total 2018-05-30 17:29:58 +02:00
AllenFang
6019e550fd Merge branch 'develop' of https://github.com/react-bootstrap-table/react-bootstrap-table2 into develop 2018-05-28 18:07:31 +08:00
AllenFang
765a49fb07 Publish
- react-bootstrap-table-next@0.1.12
2018-05-23 22:44:40 +08:00
Allen
fe2fd93c20 fix the bool rendering issues in React (#340) (#348) 2018-05-23 22:42:46 +08:00
Allen
19ba336e32 gix the bool rendering issues in React (#340) 2018-05-19 13:07:57 +08:00
AllenFang
a50148fe85 Publish
- react-bootstrap-table2-example@0.1.8
 - react-bootstrap-table2-filter@0.1.7
 - react-bootstrap-table-next@0.1.11
2018-05-14 23:09:49 +08:00
Allen
c96156503f Merge pull request #336 from react-bootstrap-table/develop
20180513 release
2018-05-14 23:02:15 +08:00
AllenFang
ed2ba2a5c5 fix #334 2018-05-14 22:44:28 +08:00
AllenFang
f87fe3e544 patch docs, example and test for wrapperClasses 2018-05-12 13:54:40 +08:00
MikeSha
43e73313e6 implement wrapperClasses(#325) 2018-05-12 13:40:24 +08:00
Allen
888aa1d08b fix #303 (#330) 2018-05-10 14:07:24 +08:00
AllenFang
028834da8b add release command 2018-05-08 22:33:46 +08:00
AllenFang
8f3b989b00 Publish
- react-bootstrap-table2-editor@0.2.1
2018-05-08 22:23:23 +08:00
AllenFang
fe8761427d Publish
- react-bootstrap-table2-paginator@0.1.3
2018-05-08 22:22:47 +08:00
AllenFang
27a09de008 Publish
- react-bootstrap-table-next@0.1.10
2018-05-08 22:22:10 +08:00
AllenFang
20ba8cc24e Publish
- react-bootstrap-table2-editor@0.2.0
 - react-bootstrap-table2-example@0.1.7
 - react-bootstrap-table2-paginator@0.1.2
 - react-bootstrap-table-next@0.1.9
2018-05-06 16:59:28 +08:00
Allen
b8b52e7fc0 20180507 release #326
20180507 release
2018-05-06 16:57:29 +08:00
Allen
05a8c3be5f fix #309 (#324) 2018-05-06 15:50:18 +08:00
Allen
2f9bedbeeb Merge pull request #323 from react-bootstrap-table/feat/pagination-total
Implement pagination total
2018-05-06 15:16:49 +08:00
AllenFang
01be6fc275 example for #238 2018-05-06 15:08:43 +08:00
AllenFang
c20a4bb220 fix #238 2018-05-06 15:08:20 +08:00
Allen
ed21b3cb65 Merge pull request #322 from react-bootstrap-table/feat/rich-editor
Rich Editors
2018-05-06 14:05:08 +08:00
AllenFang
f2a44c976d patch docs 2018-05-06 13:50:59 +08:00
AllenFang
ca5189d8ad patch tests for rich editors 2018-05-05 18:18:52 +08:00
AllenFang
03f51c36ac add example for rich cell editor 2018-05-05 18:18:52 +08:00
AllenFang
607202b4e9 implement rich cell editor 2018-05-05 18:18:52 +08:00
AllenFang
4db4f4fb2d Publish
- react-bootstrap-table2-example@0.1.6
 - react-bootstrap-table2-filter@0.1.6
 - react-bootstrap-table-next@0.1.8
2018-04-15 21:25:09 +08:00
Allen
1d7df6819e 2018/04/01 release
2018/04/01 release
2018-04-15 21:21:50 +08:00
Allen
e4b6993692 fix #302 (#304) 2018-04-15 17:29:17 +08:00
Allen
b15d7a3412 Merge pull request #287 from react-bootstrap-table/feature/pogrammatically-filter
Feature/programmatically filter
2018-04-15 15:46:54 +08:00
Allen
b172c6801c fix #228 2018-04-08 21:17:24 +08:00
Chun-MingChen
dc1f4dcc38 update travis.yml 2018-04-05 16:35:26 +08:00
Chun-MingChen
a82e611358 [test] add test for pogrammatically filter 2018-04-04 17:58:19 +08:00
Chun-MingChen
c64951fd6f [test] correct tests for filter components
* <Text />, <Select /> and <Numbner />
2018-04-04 17:58:19 +08:00
Chun-MingChen
a35701fabf [test] correct test for filter wrapper 2018-04-04 17:58:19 +08:00
Chun-MingChen
f54c1f77b4 display filter condition correctly and make sure text filter to be String 2018-04-04 17:58:19 +08:00
Chun-MingChen
377534512a rename props and variable in samples for better readability 2018-04-04 17:45:56 +08:00
Chun-MingChen
09032349d0 [example] example for programmatically filter by text, number and select 2018-04-04 17:45:56 +08:00
Chun-MingChen
4dd39aeed8 export onFilter function to allow user to access 2018-04-04 17:45:56 +08:00
Chun-MingChen
a1477e2ad3 filter column by new onFilter 2018-04-04 17:45:56 +08:00
Chun-MingChen
f34cb4bf63 allow user to filter column without inputField
* wrap onFilter to HOF to allow filter dynamically
2018-04-04 17:45:56 +08:00
AllenFang
3dc9cd3941 Publish
- react-bootstrap-table2-editor@0.1.5
 - react-bootstrap-table2-filter@0.1.5
 - react-bootstrap-table-next@0.1.7
2018-04-02 23:46:59 +08:00
AllenFang
e8458b4b63 Publish
- react-bootstrap-table2-editor@0.1.4
 - react-bootstrap-table2-example@0.1.5
 - react-bootstrap-table2-filter@0.1.4
 - react-bootstrap-table-next@0.1.6
2018-04-01 15:56:53 +08:00
Allen
1d87ce9ffc 2018/04/01 release
2018/04/01 release
2018-04-01 15:55:45 +08:00
Allen
88e1a0774b fix #281 2018-04-01 14:14:32 +08:00
Patrick O'Meara
11d4f40089 noDataIndication (#276)
* use the correct amount of cells when the first row is select
* storybook added for development, not necessary in docs

fixes react-bootstrap-table/react-bootstrap-table2#264
2018-04-01 13:34:06 +08:00
Patrick O'Meara
41dc3ef619 empty noDataIndication when empty (#275)
* don't display unneeded empty row when noDataIndication isn't set
2018-04-01 13:32:24 +08:00
Nixon Kwok
4501ddb632 Fix textFilter() for Internet Explorer (includes() and find() are not supported) (#274)
* Fix textFilter() for Internet Explorer 11
- replace includes() with indexOf() !== -1
- replace find() with for loop

* Requested changes; more readability with for loop
- use .length of the columns instead of the Object.keys()
2018-04-01 13:30:59 +08:00
Allen
05657ee217 Merge pull request #273 from react-bootstrap-table/revert-265-264_indication_no_data
Revert "fix#264: wrong col span when enable selection in a empty tabl…
2018-03-25 17:38:32 +08:00
Allen
c91f521913 fix #258 (#268) 2018-03-25 16:44:27 +08:00
Allen
9ee9c7de43 Revert "fix#264: wrong col span when enable selection in a empty table (#265)"
This reverts commit 42dbd00fd9.
2018-03-25 16:37:27 +08:00
Patrick O'Meara
42dbd00fd9 fix#264: wrong col span when enable selection in a empty table (#265)
* noDataIndication

* use the correct amount of cells when the first row is select
* storybook added for development, not necessary in docs

fixes react-bootstrap-table/react-bootstrap-table2#264

* eslint complaints

  4:11  error  'columnLen' is never reassigned. Use 'const' instead                   prefer-const
  7:9   error  Expected an assignment or function call and instead saw an expression  no-unused-expressions

* tests updated
2018-03-25 16:36:58 +08:00
AllenFang
bd9150f88f Publish
- react-bootstrap-table2-editor@0.1.3
 - react-bootstrap-table2-example@0.1.4
 - react-bootstrap-table-next@0.1.5
2018-03-18 23:07:46 +08:00
Allen
3956fbca11 Merge pull request #263 from react-bootstrap-table/develop
2018/03/19 release
2018-03-18 23:03:55 +08:00
NickChen
240bcd75c0 Merge pull request #262 from prajapati-parth/update-readme
Add TravisCI badge to README
2018-03-18 17:48:11 +08:00
Chun-MingChen
6de57737ea allow travis to run test for master branch 2018-03-18 17:35:05 +08:00
Parth Prajapati
33a8da701b Add TravisCI badge 2018-03-18 14:28:27 +05:30
AllenFang
d5ddd8c3af add selection management example 2018-03-18 16:44:39 +08:00
Chun-MingChen
6f9361934a set state.selectedRowKeys based on store 2018-03-18 16:10:06 +08:00
Parth Prajapati
6bc81dddd0 Fixed #237 (#261)
* Fixed #237

* Solved lint errors

* Removed test cases for display: none checks
- added test cases for hidden columns check
2018-03-18 15:42:21 +08:00
AllenFang
c11539b9fb [docs] patch id and classes for BootstrapTable 2018-03-18 14:33:11 +08:00
Allen
94f1a5ee57 Merge pull request #247 from Chun-MingChen/feature/customized-class-n-id-on-table
customized classes and id on BootstrapTable (#235)
2018-03-18 14:25:55 +08:00
Allen
de27072ceb Merge pull request #260 from react-bootstrap-table/bugfix/default-selection
Bugfix/default selection
2018-03-18 14:16:49 +08:00
AllenFang
55336108a0 should recieve newest selectRow.selected 2018-03-18 14:07:44 +08:00
Chun-MingChen
923439dc81 correct typo 2018-03-17 17:29:30 +08:00
Chun-MingChen
d80ae13513 [test] test for RowSelectionWrapper#componentWillReceiveProps 2018-03-17 17:27:27 +08:00
Chun-MingChen
ceebdf5a13 refine store to set selectRow when receiving props 2018-03-17 17:27:27 +08:00
Chun-MingChen
0eda54b772 correct the typo of documents 2018-03-17 16:23:09 +08:00
Chun-MingChen
3ed4d87b29 correct attribute key of columns.headerEvent in column-event-tables 2018-03-17 15:29:23 +08:00
Chun-MingChen
8a8c2d4964 [example] add demo for customized classes and id table 2018-03-10 18:54:59 +08:00
Chun-MingChen
3cea9658c7 [test] test for customized classes and id 2018-03-10 18:54:41 +08:00
Chun-MingChen
9f9203bffa implement customized classes and id on the table 2018-03-10 18:54:26 +08:00
AllenFang
4011cae18e Publish 2018-03-06 23:59:04 +08:00
Allen
60f32f0336 Merge pull request #240 from react-bootstrap-table/develop
2018/03/06 release
2018-03-06 23:40:05 +08:00
Allen
a5cb806d98 implement default selection (#234) 2018-03-05 22:27:46 +08:00
Allen
9382ed587b implement row event delegater (#233) 2018-03-04 17:22:52 +08:00
Allen
a11913c49a fix #210 (#232) 2018-03-04 16:21:10 +08:00
AllenFang
4635b60da0 Merge branch 'develop' of https://github.com/react-bootstrap-table/react-bootstrap-table2 into develop 2018-03-04 16:10:23 +08:00
AllenFang
4d9e20e9c8 fix #221 2018-03-04 16:05:10 +08:00
Parth Prajapati
931cf80450 Fixes #186 (#219)
* Fixes #186

* Solved lint error
2018-03-04 16:05:10 +08:00
AllenFang
5dd1f1e9ea fix #221 2018-02-24 23:03:09 +08:00
Parth Prajapati
a8083ac17d Fixes #186 (#219)
* Fixes #186

* Solved lint error
2018-02-24 22:53:52 +08:00
AllenFang
096799c403 Publish
- react-bootstrap-table2-example@0.1.2
 - react-bootstrap-table2-filter@0.1.3
 - react-bootstrap-table-next@0.1.3
2018-02-14 16:33:51 +08:00
Allen
6dee718081 2018/02/14 release
2018/02/14 release
2018-02-14 16:30:02 +08:00
Allen
936a82954c fix #196
Support sort event listener
2018-02-10 21:17:00 +08:00
AllenFang
ba24990994 add story for sort event listener 2018-02-10 17:46:38 +08:00
AllenFang
e7ccd47817 implement sort events listener 2018-02-10 17:46:38 +08:00
AllenFang
a0af964d76 fix #195 2018-02-10 17:00:29 +08:00
Allen
865be93ef7 refine caseSensitive for filter (#201) 2018-02-10 16:54:01 +08:00
makenova
65a596a0e9 case insensitive text filter (#190)
* case insensitive text filter

* optional case insensitive filter
2018-02-10 16:17:45 +08:00
Allen
024bba15fa fix #192
Implement number filter
2018-02-10 16:15:37 +08:00
AllenFang
f9217930e7 patch docs for number filter 2018-02-10 16:04:46 +08:00
AllenFang
fc34ea12e6 patch test for number filter 2018-02-10 16:04:46 +08:00
AllenFang
b0f411e934 add number filter stories 2018-02-10 16:04:46 +08:00
AllenFang
28a1077bad implement number filter 2018-02-10 15:43:22 +08:00
AllenFang
ca32eee28e patch rowEvents docs 2018-02-04 21:41:52 +08:00
Allen
7030b54cbd Fix #179
Solves #179
2018-02-04 21:37:10 +08:00
Allen
4d7378e3f1 create LICENSE 2018-02-01 23:41:30 +08:00
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
Parth Prajapati
577973a147 Updated storybook example 2018-02-01 06:27:49 +05:30
Parth Prajapati
c4f14e2b69 Added row object to onClick
- attach onClick only if defined
2018-02-01 06:20:50 +05:30
AllenFang
38bb2290dc README 2018-01-31 23:50:02 +08:00
Parth Prajapati
feedcb9f4b Solves #179 2018-01-31 07:43:05 +05:30
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
228 changed files with 12958 additions and 3776 deletions

7
.gitignore vendored
View File

@@ -15,3 +15,10 @@ lerna-debug.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.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

@@ -9,9 +9,10 @@ cache:
branches: branches:
only: only:
# skip master branch when it's under development phase - master
# - master
- develop - develop
except:
- gh-pages-src
before_install: before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s - curl -o- -L https://yarnpkg.com/install.sh | bash -s

View File

@@ -12,6 +12,7 @@ Additionally, asking questions and requesting new features are welcomed via [iss
# Pull Requests # Pull Requests
Check [here](./docs/development.md) for getting started with development. 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. * 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. * 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. * 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.

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 react-bootstrap-table2
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,25 +1,42 @@
# react-bootstrap-table2 # react-bootstrap-table2
[![Build Status](https://travis-ci.org/react-bootstrap-table/react-bootstrap-table2.svg?branch=master)](https://travis-ci.org/react-bootstrap-table/react-bootstrap-table2)
Rebuilt [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-table) Rebuilt [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-table)
## The problems/features I want to solve > `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
* 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
## The feature may lost on react-bootstrap-table `react-bootstrap-table2` separate some functionalities from core modules to other modules like following:
* Have a great chance that I don't support the vertical scrollbar on table
* [`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

@@ -15,12 +15,16 @@
* [bordered](#bordered) * [bordered](#bordered)
* [hover](#hover) * [hover](#hover)
* [condensed](#condensed) * [condensed](#condensed)
* [id](#id)
* [classes](#classes)
* [wrapperClasses](#wrapperClasses)
* [cellEdit](#cellEdit) * [cellEdit](#cellEdit)
* [selectRow](#selectRow) * [selectRow](#selectRow)
* [rowStyle](#rowStyle) * [rowStyle](#rowStyle)
* [rowClasses](#rowClasses) * [rowClasses](#rowClasses)
* [rowEvents](#rowEvents) * [rowEvents](#rowEvents)
* [defaultSorted](#defaultSorted) * [defaultSorted](#defaultSorted)
* [defaultSortDirection](#defaultSortDirection)
* [pagination](#pagination) * [pagination](#pagination)
* [filter](#filter) * [filter](#filter)
* [onTableChange](#onTableChange) * [onTableChange](#onTableChange)
@@ -40,7 +44,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: For flexibility reason, you can control what functionality should be handled on remote via a object return:
```js ```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. In above case, only column filter will be handled on remote.
@@ -53,20 +63,20 @@ A special case for remote pagination:
remote={ { pagination: true, filter: false, sort: false } } 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 special case for remote pagination, even you only specified the pagination 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 data.
### <a name='loading'>loading - [Bool]</a> ### <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. 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> ### <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 function which should returning a higher order component. By default, `react-bootstrap-table2-overlay` can be a good option for you:
```sh ```sh
$ npm install react-bootstrap-table-overlay $ npm install react-bootstrap-table2-overlay
``` ```
```js ```js
import overlayFactory from 'react-bootstrap-table-overlay'; import overlayFactory from 'react-bootstrap-table2-overlay';
<BootstrapTable <BootstrapTable
data={ data } data={ data }
@@ -94,6 +104,13 @@ Same as bootstrap `.table-hover` class for adding mouse hover effect (grey backg
### <a name='condensed'>condensed - [Bool]</a> ### <a name='condensed'>condensed - [Bool]</a>
Same as bootstrap `.table-condensed` class for making a table more compact by cutting cell padding in half. Same as bootstrap `.table-condensed` class for making a table more compact by cutting cell padding in half.
### <a name='id'>id - [String]</a>
Customize id on `table` element.
### <a name='classes'>classes - [String]</a>
Customize class on `table` element.
### <a name='wrapperClasses'>wrapperClasses - [String]</a>
Customize class on the outer element which wrap up the `table` element.
### <a name='cellEdit'>cellEdit - [Object]</a> ### <a name='cellEdit'>cellEdit - [Object]</a>
Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail. Makes table cells editable, please see [cellEdit definition](./cell-edit.md) for more detail.
@@ -139,7 +156,7 @@ Custom the events on row:
```js ```js
const rowEvents = { const rowEvents = {
onClick: (e) => { onClick: (e, row, rowIndex) => {
.... ....
} }
}; };
@@ -156,8 +173,11 @@ const defaultSorted = [{
}]; }];
``` ```
### <a name='defaultSortDirection'>defaultSortDirection - [String]</a>
Default sort direction when user click on header column at first time, available value is `asc` and `desc`. Default is `desc`.
### <a name='pagination'>pagination - [Object]</a> ### <a name='pagination'>pagination - [Object]</a>
`pagination` allow user to render a pagination panel on the bottom of table. But pagination funcitonality is separated from core of `react-bootstrap-table2` so that you are suppose to install `react-bootstrap-table2-paginator` additionaly. `pagination` allow user to render a pagination panel on the bottom of table. But pagination functionality is separated from core of `react-bootstrap-table2` so that you are suppose to install `react-bootstrap-table2-paginator` additionally.
```sh ```sh
$ npm install react-bootstrap-table2-paginator --save $ npm install react-bootstrap-table2-paginator --save
@@ -182,6 +202,7 @@ paginator({
totalSize, // Total data size. It's necessary when remote is enabled totalSize, // Total data size. It's necessary when remote is enabled
pageStartIndex: 0, // first page will be 0, default is 1 pageStartIndex: 0, // first page will be 0, default is 1
paginationSize: 3, // the pagination bar size, default is 5 paginationSize: 3, // the pagination bar size, default is 5
showTotal: true, // display pagination information
sizePerPageList: [ { sizePerPageList: [ {
text: '5', value: 5 text: '5', value: 5
}, { }, {
@@ -199,15 +220,16 @@ paginator({
prePageTitle: 'Go to previous', // the title of previous page button prePageTitle: 'Go to previous', // the title of previous page button
firstPageTitle: 'Go to first', // the title of first page button firstPageTitle: 'Go to first', // the title of first page button
lastPageTitle: 'Go to last', // the title of last page button lastPageTitle: 'Go to last', // the title of last page button
hideSizePerPage: true, // hide the size per page dorpdown hideSizePerPage: true, // hide the size per page dropdown
hidePageListOnlyOnePage: true, // hide pagination bar when only one page, default is false hidePageListOnlyOnePage: true, // hide pagination bar when only one page, default is false
onPageChange: (page, sizePerPage) => {}, // callback function when page was changing onPageChange: (page, sizePerPage) => {}, // callback function when page was changing
onSizePerPageChange: (sizePerPage, page) => {}, // callback function when page size was changing onSizePerPageChange: (sizePerPage, page) => {}, // callback function when page size was changing
paginationTotalRenderer: (from, to, size) => { ... } // custom the pagination total
}) })
``` ```
### <a name='filter'>filter - [Object]</a> ### <a name='filter'>filter - [Object]</a>
`filter` allow user to filter data by column. However, filter funcitonality is separated from core of `react-bootstrap-table2` so that you are suppose to install `react-bootstrap-table2-filter` firstly. `filter` allow user to filter data by column. However, filter functionality is separated from core of `react-bootstrap-table2` so that you are suppose to install `react-bootstrap-table2-filter` firstly.
```sh ```sh
$ npm install react-bootstrap-table2-filter --save $ npm install react-bootstrap-table2-filter --save
@@ -249,13 +271,23 @@ There's only two arguments will be passed to `onTableChange`: `type` and `newSta
* `filter` * `filter`
* `pagination` * `pagination`
* `sort`
* `cellEdit`
Following is a shape of `newState` Following is a shape of `newState`
```js ```js
{ {
page, // newest page page, // newest page
sizePerPage, //newest sizePerPage sizePerPage, // newest sizePerPage
filters // an object which have current filter status per column 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 # Properties on cellEdit prop
* [mode (**required**)](#mode) * [mode (**required**)](#mode)
* [blurToSave](#blurToSave) * [blurToSave](#blurToSave)
@@ -5,8 +12,6 @@
* [timeToCloseMessage](#timeToCloseMessage) * [timeToCloseMessage](#timeToCloseMessage)
* [beforeSaveCell](#beforeSaveCell) * [beforeSaveCell](#beforeSaveCell)
* [afterSaveCell](#afterSaveCell) * [afterSaveCell](#afterSaveCell)
* [onUpdate](#onUpdate)
* [editing](#editing)
* [errorMessage](#errorMessage) * [errorMessage](#errorMessage)
* [onErrorMessageDisappear](#onErrorMessageDisappear) * [onErrorMessageDisappear](#onErrorMessageDisappear)
@@ -21,9 +26,7 @@ Following is the shape of `cellEdit` object:
mode: 'click', mode: 'click',
blurToSave: true, blurToSave: true,
timeToCloseMessage: 2500, timeToCloseMessage: 2500,
editing: false|true,
errorMessage: '', errorMessage: '',
onUpdate: (rowId, dataField, newValue) => { ... },
beforeSaveCell: (oldValue, newValue, row, column) => { ... }, beforeSaveCell: (oldValue, newValue, row, column) => { ... },
afterSaveCell: (oldValue, newValue, row, column) => { ... }, afterSaveCell: (oldValue, newValue, row, column) => { ... },
onErrorMessageDisappear: () => { ... }, 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> ### <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> ### <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

@@ -12,6 +12,7 @@ Available properties in a column object:
* [formatExtraData](#formatExtraData) * [formatExtraData](#formatExtraData)
* [sort](#sort) * [sort](#sort)
* [sortFunc](#sortFunc) * [sortFunc](#sortFunc)
* [onSort](#onSort)
* [classes](#classes) * [classes](#classes)
* [style](#style) * [style](#style)
* [title](#title) * [title](#title)
@@ -31,6 +32,10 @@ Available properties in a column object:
* [validator](#validator) * [validator](#validator)
* [editCellStyle](#editCellStyle) * [editCellStyle](#editCellStyle)
* [editCellClasses](#editCellClasses) * [editCellClasses](#editCellClasses)
* [editorStyle](#editorStyle)
* [editorClasses](#editorClasses)
* [editor](#editor)
* [editorRenderer](#editorRenderer)
* [filter](#filter) * [filter](#filter)
* [filterValue](#filterValue) * [filterValue](#filterValue)
@@ -73,7 +78,7 @@ dataField: 'address.city'
``` ```
## <a name='text'>column.text (**required**) - [String]</a> ## <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> ## <a name='hidden'>column.hidden - [Bool]</a>
`hidden` allow you to hide column when `true` given. `hidden` allow you to hide column when `true` given.
@@ -89,9 +94,9 @@ dataField: 'address.city'
## <a name='headerFormatter'>column.headerFormatter - [Function]</a> ## <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. `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 * `column`: current column object itself
* `colIndex` * `colIndex`: index of current column
* `components`: it's an object which contain all of other react element, like sort caret or filter etc. * `components`: an object which contain all of other react element, like sort caret or filter etc.
The third argument: `components` have following specified properties: The third argument: `components` have following specified properties:
```js ```js
@@ -122,8 +127,21 @@ Enable the column sort via a `true` value given.
``` ```
> The possible value of `order` argument is **`asc`** and **`desc`**. > The possible value of `order` argument is **`asc`** and **`desc`**.
## <a name='sortFunc'>column.onSort - [Function]</a>
`column.onSort` is an event listener for sort change event:
```js
{
// omit...
sort: true,
onSort: (field, order) => {
// ....
}
}
```
## <a name='classes'>column.classes - [String | Function]</a> ## <a name='classes'>column.classes - [String | Function]</a>
It's availabe to have custom class on table column: It's available to have custom class on table column:
```js ```js
{ {
@@ -131,7 +149,7 @@ It's availabe to have custom class on table column:
classes: 'id-custom-cell' 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 ```js
@@ -148,10 +166,10 @@ In addition, `classes` also accept a callback function which have more power to
**Return value** **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> ## <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: It's similar to [`column.classes`](#classes), `headerClasses` is available to have customized class on table header column:
```js ```js
{ {
@@ -176,7 +194,7 @@ Furthermore, it also accept a callback function which takes 2 arguments and a `S
A new `String` will be the result of element headerClasses. A new `String` will be the result of element headerClasses.
## <a name='style'>column.style - [Object | Function]</a> ## <a name='style'>column.style - [Object | Function]</a>
It's availabe to have custom style on table column: It's available to have custom style on table column:
```js ```js
{ {
@@ -185,7 +203,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 ```js
@@ -206,7 +224,7 @@ A new `Object` will be the result of element style.
## <a name='headerStyle'>column.headerStyle - [Object | Function]</a> ## <a name='headerStyle'>column.headerStyle - [Object | Function]</a>
It's availabe to have customized inline-style on table header column: It's available to have customized inline-style on table header column:
```js ```js
{ {
@@ -215,7 +233,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 ```js
{ {
@@ -233,7 +251,7 @@ A new `Object` will be the result of element headerStyle.
## <a name='title'>column.title - [Bool | Function]</a> ## <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 ```js
@@ -264,7 +282,7 @@ A new `String` will be the result of element title.
} }
``` ```
It's also availabe to custom via a callback function: It's also available to custom via a callback function:
```js ```js
{ {
headerTitle: function callback(column, colIndex) { ... } headerTitle: function callback(column, colIndex) { ... }
@@ -282,7 +300,7 @@ A new `String` will be the result of element headerTitle.
## <a name='align'>column.align - [String | Function]</a> ## <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. 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 ```js
{ {
@@ -385,20 +403,20 @@ Not only `Object`, `callback function` is also acceptable. It takes `4` argument
A new `Object` will be the result of element HTML attributes. 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 priority and it will be overwritten.
```js ```js
{ {
// omit... // omit...
title: true, // it will be chosen. title: true, // get higher priority
attrs: { title: 'test' } attrs: { title: 'test' }
} }
``` ```
## <a name='headerAttrs'>column.headerAttrs - [Object | Function]</a> ## <a name='headerAttrs'>column.headerAttrs - [Object | Function]</a>
`headerAttrs` is similiar to [`column.attrs`](#attrs) but it works for header column. `headerAttrs` is similar to [`column.attrs`](#attrs) but it works for header column.
```js ```js
{ {
// omit... // omit...
@@ -409,7 +427,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 ```js
{ {
@@ -430,7 +448,7 @@ A new `Object` will be the result of element headerAttrs.
> Caution: > Caution:
> Same as [column.attrs](#attrs), it has lower priority and will be > Same as [column.attrs](#attrs), it has lower priority and will be
> overwrited when other props related to HTML attributes were given. > overwritten when other props related to HTML attributes were given.
### <a name='headerSortingClasses'>headerSortingClasses - [String | Function]</a> ### <a name='headerSortingClasses'>headerSortingClasses - [String | Function]</a>
@@ -453,7 +471,7 @@ const headerSortingClasses = (column, sortOrder, isLastSorting, colIndex) => { .
### <a name='headerSortingStyle'>headerSortingStyle - [Object | Function]</a> ### <a name='headerSortingStyle'>headerSortingStyle - [Object | Function]</a>
It's similiar to [headerSortingClasses](#headerSortingClasses). It allows to customize the style of header cell when this column is sorting. A style `Object` and `callback` are acceptable. `callback` takes **4** arguments and an `Object` is expected to return: It's similar to [headerSortingClasses](#headerSortingClasses). It allows to customize the style of header cell when this column is sorting. A style `Object` and `callback` are acceptable. `callback` takes **4** arguments and an `Object` is expected to return:
```js ```js
const sortingHeaderStyle = { const sortingHeaderStyle = {
@@ -488,7 +506,7 @@ If a callback function given, you can control the editable level as cell level:
} }
``` ```
The return value can be a bool or an object. If your valiation is pass, return `true` explicitly. If your valiation is invalid, return following object instead: The return value can be a bool or an object. If your validation is pass, return `true` explicitly. If your validation is invalid, return following object instead:
```js ```js
{ {
valid: false, valid: false,
@@ -538,10 +556,100 @@ Or take a callback function
} }
``` ```
## <a name='editorStyle'>column.editorStyle - [Object | Function]</a>
This is almost same as [`column.editCellStyle`](#editCellStyle), but `column.editorStyle` is custom the style on editor instead of cell(`td`).
## <a name='editorClasses'>column.editorClasses - [Object | Function]</a>
This is almost same as [`column.editCellClasses`](#editCellClasses), but `column.editorClasses` is custom the class on editor instead of cell(`td`).
## <a name='editor'>column.editor - [Object]</a>
`column.editor` allow you to custom the type of cell editor by following predefined type:
* Text(Default)
* Dropdown
* Date
* Textarea
* Checkbox
Following is a quite example:
```js
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
const columns = [
//...
, {
dataField: 'done',
text: 'Done',
editor: {
type: Type.CHECKBOX,
value: 'Y:N'
}
}
];
```
If you want more information, please check [here](https://github.com/react-bootstrap-table/react-bootstrap-table2/tree/master/packages/react-bootstrap-table2-editor).
## <a name='editorRenderer'>column.editorRenderer - [Function]</a>
If you feel above predefined editors are not satisfied to your requirement, you can totally custom the editor via `column.editorRenderer`:
```js
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
// Custom Editor
class QualityRanger extends React.Component {
static propTypes = {
value: PropTypes.number,
onUpdate: PropTypes.func.isRequired
}
static defaultProps = {
value: 0
}
getValue() {
return parseInt(this.range.value, 10);
}
render() {
const { value, onUpdate, ...rest } = this.props;
return [
<input
{ ...rest }
key="range"
ref={ node => this.range = node }
type="range"
min="0"
max="100"
/>,
<button
key="submit"
className="btn btn-default"
onClick={ () => onUpdate(this.getValue()) }
>
done
</button>
];
}
}
const columns = [
//...
, {
dataField: 'done',
text: 'Done',
editorRenderer: (editorProps, value, row, column, rowIndex, columnIndex) =>
<QualityRanger { ...editorProps } value={ value } />;
}
];
```
## <a name='filter'>column.filter - [Object]</a> ## <a name='filter'>column.filter - [Object]</a>
Configure `column.filter` will able to setup a column level filter on the header column. Currently, `react-bootstrap-table2` support following filters: Configure `column.filter` will able to setup a column level filter on the header column. Currently, `react-bootstrap-table2` support following filters:
* Text(`textFilter`) * Text(`textFilter`)
* Select(`selectFilter`)
* Number(`numberFilter`)
* Date(`dateFilter`)
We have a quick example to show you how to use `column.filter`: We have a quick example to show you how to use `column.filter`:
@@ -556,4 +664,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 filtered:
**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 ### Development
```bash ```bash
$ npm start $ npm run storybook
``` ```
### Launch StoryBook ### Launch StoryBook

118
docs/migration.md Normal file
View File

@@ -0,0 +1,118 @@
# 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 [Road Map](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 [official 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 kernel module(SRP). Hence, which means you probably need to install above addons when you need specific features.
## Core Table Migration
There is a big change 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` Definition](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/table-props.html)
* [Column Definition](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
- [x] Sort event listener
- [ ] 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 definition.
## 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.
## 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
- [x] Custom Filter Component
- [ ] Regex Filter
- [x] Select Filter
- [x] Custom Select Filter
- [X] Number Filter
- [X] Date Filter
- [ ] Array Filter
- [X] 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 definition 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,11 @@
# Row selection # 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. `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.
## Required
## Available properties
The following are available properties in `selectRow`:
#### Required
* [mode (**required**)](#mode) * [mode (**required**)](#mode)
## Optional
* [selected](#selected)
* [style](#style) * [style](#style)
* [classes)](#classes) * [classes)](#classes)
* [bgColor](#bgColor) * [bgColor](#bgColor)
@@ -18,16 +16,16 @@ The following are available properties in `selectRow`:
* [onSelect](#onSelect) * [onSelect](#onSelect)
* [onSelectAll](#onSelectAll) * [onSelectAll](#onSelectAll)
* [hideSelectColumn](#hideSelectColumn) * [hideSelectColumn](#hideSelectColumn)
* [selectionRenderer](#selectionRenderer)
* [selectionHeaderRenderer](#selectionHeaderRenderer)
#### 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. 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 #### values
* `radio` * **radio**
* `checkbox` * **checkbox**
#### examples #### examples
@@ -35,6 +33,7 @@ Specifying the selection way for `single(radio)` or `multiple(checkbox)`. If `ra
const selectRow = { const selectRow = {
mode: 'radio' // single row selection mode: 'radio' // single row selection
}; };
<BootstrapTable <BootstrapTable
keyField='id' keyField='id'
data={ products } data={ products }
@@ -56,7 +55,17 @@ const selectRow = {
/> />
``` ```
## <a name='style'>selectRow.style - [Object | Function]</a> ### <a name='selected'>selectRow.selected - [Array]</a>
`selectRow.selected` allow you have default selections on table.
```js
const selectRow = {
mode: 'checkbox',
selected: [1, 3] // should be a row keys array
};
```
### <a name='style'>selectRow.style - [Object | Function]</a>
`selectRow.style` allow you to have custom style on selected rows: `selectRow.style` allow you to have custom style on selected rows:
```js ```js
@@ -75,7 +84,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: `selectRow.classes` allow you to add css class on selected rows:
```js ```js
@@ -94,8 +103,8 @@ 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 The background color when row is selected
```js ```js
const selectRow = { const selectRow = {
@@ -115,7 +124,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. This prop allow you to restrict some rows which can not be selected by user. `selectRow.nonSelectable` accept an rowkeys array.
```js ```js
@@ -125,8 +134,8 @@ const selectRow = {
}; };
``` ```
## <a name='clickToSelect'>selectRow.clickToSelect - [Bool]</a> ### <a name='clickToSelect'>selectRow.clickToSelect - [Bool]</a>
Able to select row when clicking on row. Allow user to select row by clicking on the row.
```js ```js
const selectRow = { const selectRow = {
@@ -135,10 +144,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) > 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 Able to click to edit cell and select row
```js ```js
@@ -149,32 +158,60 @@ const selectRow = {
}; };
``` ```
## <a name='onSelect'>selectRow.onSelect - [Function]</a> ### <a name='selectionRenderer'>selectRow.selectionRenderer - [Function]</a>
This callback function will be called when a row is select/unselect and pass following three arguments: Provide a callback function which allow you to custom the checkbox/radio box. This callback only have one argument which is an object and contain following properties:
`row`, `isSelect` and `rowIndex`.
```js ```js
const selectRow = { const selectRow = {
mode: 'checkbox', mode: 'checkbox',
onSelect: (row, isSelect, rowIndex) => { selectionRenderer: ({ mode, checked, disabled }) => (
// ....
)
};
```
> By default, `react-bootstrap-table2` will help you to handle the click event, it's not necessary to handle again by developer.
### <a name='selectionHeaderRenderer'>selectRow.selectionHeaderRenderer - [Function]</a>
Provide a callback function which allow you to custom the checkbox/radio box in the selection header column. This callback only have one argument which is an object and contain following properties:
```js
const selectRow = {
mode: 'checkbox',
selectionHeaderRenderer: ({ mode, checked, indeterminate }) => (
// ....
)
};
```
> By default, `react-bootstrap-table2` will help you to handle the click event, it's not necessary to handle again by developer.
### <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`, `rowIndex` and `e`.
```js
const selectRow = {
mode: 'checkbox',
onSelect: (row, isSelect, rowIndex, e) => {
// ... // ...
} }
}; };
``` ```
## <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`. This callback function will be called when select/unselect all and it only work when you configure [`selectRow.mode`](#mode) as `checkbox`.
```js ```js
const selectRow = { const selectRow = {
mode: 'checkbox', mode: 'checkbox',
onSelectAll: (isSelect, results) => { onSelectAll: (isSelect, results, e) => {
// ... // ...
} }
}; };
``` ```
## <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` Default is `false`, if you don't want to have a selection column, give this prop as `true`
```js ```js

91
gulpfile.babel.js Normal file
View File

@@ -0,0 +1,91 @@
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(done) {
gulp.parallel(
() => gulp.src('./webpack/next.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])),
() => gulp.src('./webpack/editor.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])),
() => gulp.src('./webpack/filter.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])),
() => gulp.src('./webpack/overlay.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>'])),
() => gulp.src('./webpack/paginator.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>']))
)();
done();
}
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": [
"packages/*" "packages/*"
], ],
"version": "0.0.0" "version": "independent"
} }

View File

@@ -1,29 +1,46 @@
{ {
"name": "react-bootstrap-table2", "name": "react-bootstrap-table2",
"version": "0.0.1", "version": "0.0.1",
"private": true,
"description": "Rebuilt for react-bootstrap-table", "description": "Rebuilt for react-bootstrap-table",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"postinstall": "lerna bootstrap", "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", "lint": "eslint ./packages --ext .js --ext .jsx --ignore-path .gitignore",
"pretest": "yarn lint --cache", "pretest": "yarn lint --cache",
"test": "jest", "test": "jest",
"test:coverage": "jest --coverage", "test:coverage": "jest --coverage",
"test:watch": "jest --watch", "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",
"release": "yarn install && yarn build && lerna publish"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/react-bootstrap-table/react-bootstrap-table2.git" "url": "git+https://github.com/react-bootstrap-table/react-bootstrap-table2.git"
}, },
"author": "", "author": "AllenFang",
"license": "ISC", "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": { "bugs": {
"url": "https://github.com/react-bootstrap-table/react-bootstrap-table2/issues" "url": "https://github.com/react-bootstrap-table/react-bootstrap-table2/issues"
}, },
"homepage": "https://github.com/react-bootstrap-table/react-bootstrap-table2#readme", "homepage": "https://github.com/react-bootstrap-table/react-bootstrap-table2#readme",
"devDependencies": { "devDependencies": {
"babel-cli": "6.26.0",
"babel-core": "6.25.0", "babel-core": "6.25.0",
"babel-eslint": "7.2.3", "babel-eslint": "7.2.3",
"babel-jest": "20.0.3", "babel-jest": "20.0.3",
@@ -41,11 +58,18 @@
"eslint-plugin-import": "2.7.0", "eslint-plugin-import": "2.7.0",
"eslint-plugin-jsx-a11y": "5.1.1", "eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.2.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", "html-webpack-plugin": "2.30.1",
"jest": "20.0.4", "jest": "20.0.4",
"jsdom": "11.2.0", "jsdom": "11.2.0",
"jsdom-global": "3.0.2", "jsdom-global": "3.0.2",
"lerna": "2.0.0", "lerna": "2.8.0",
"node-sass": "4.5.3", "node-sass": "4.5.3",
"react-test-renderer": "16.0.0", "react-test-renderer": "16.0.0",
"sass-loader": "6.0.6", "sass-loader": "6.0.6",
@@ -60,14 +84,10 @@
"react": "16.0.0", "react": "16.0.0",
"react-dom": "16.0.0" "react-dom": "16.0.0"
}, },
"peerDependencies": {
"prop-types": "^15.0.0",
"react": "^16.0.0",
"react-dom": "^16.0.0"
},
"jest": { "jest": {
"collectCoverageFrom": [ "collectCoverageFrom": [
"packages/**/*.js" "packages/*/src/*.js",
"packages/*/index.js"
], ],
"roots": [ "roots": [
"<rootDir>/packages" "<rootDir>/packages"

View File

@@ -0,0 +1,229 @@
# 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)
## 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!
## Customize Style/Class
### 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)
### Editor
* Customize the editor style via [column.editorStyle](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditorstyle-object-function)
* Customize the editor classname via [column.editoClasses](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditorclasses-string-function)
## Rich Editors
`react-bootstrap-table2` have following predefined editor:
* Text(Default)
* Dropdown
* Date
* Textarea
* Checkbox
In a nutshell, you just only give a [column.editor](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditor-object) and define the `type`:
```js
import { Type } from 'react-bootstrap-table2-editor';
const columns = [
..., {
dataField: 'done',
text: 'Done',
editor: {
type: Type.SELECT | Type.TEXTAREA | Type.CHECKBOX | Type.DATE,
... // The rest properties will be rendered into the editor's DOM element
}
}
]
```
In the following, we go though all the predefined editors:
### Dropdown Editor
Dropdown editor give a select menu to choose a data from a list, the `editor.options` is required property for dropdown editor.
```js
import { Type } from 'react-bootstrap-table2-editor';
const columns = [
..., {
dataField: 'type',
text: 'Job Type',
editor: {
type: Type.SELECT,
options: [{
value: 'A',
label: 'A'
}, {
value: 'B',
label: 'B'
}, {
value: 'C',
label: 'C'
}, {
value: 'D',
label: 'D'
}, {
value: 'E',
label: 'E'
}]
}
}];
```
### Date Editor
Date editor is use `<input type="date">`, the configuration is very simple:
```js
const columns = [
..., {
dataField: 'inStockDate',
text: 'Stock Date',
formatter: (cell) => {
let dateObj = cell;
if (typeof cell !== 'object') {
dateObj = new Date(cell);
}
return `${('0' + dateObj.getDate()).slice(-2)}/${('0' + (dateObj.getMonth() + 1)).slice(-2)}/${dateObj.getFullYear()}`;
},
editor: {
type: Type.DATE
}
}];
```
### Textarea Editor
Textarea editor is use `<input type="textarea">`, user can press `ENTER` to change line and in the `react-bootstrap-table2`, user allow to save result via press `SHIFT` + `ENTER`.
```js
const columns = [
..., {
dataField: 'comment',
text: 'Product Comments',
editor: {
type: Type.TEXTAREA
}
}];
```
### Checkbox Editor
Checkbox editor allow you to have a pair value choice, the `editor.value` is required value to represent the actual value for check and uncheck.
```js
const columns = [
..., {
dataField: 'comment',
text: 'Product Comments',
editor: {
type: Type.CHECKBOX,
value: 'Y:N'
}
}];
```
## Customize Editor
If you feel above predefined editors are not satisfied to your requirement, you can certainly custom the editor via [column.editorRenderer](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditorrenderer-function). It accept a function and pass following arguments when function called:
* `editorProps`: Some useful attributes you can use on DOM editor, like class, style etc.
* `value`: Current cell value
* `row`: Current row data
* `column`: Current column definition
* `rowIndex`: Current row index
* `columnIndex`: Current column index
> Note when implement a custom React editor component, this component should have a **getValue** function which return current value on editor
> Note when you want to save value, you can call **editorProps.onUpdate** function
Following is a short example:
```js
class QualityRanger extends React.Component {
static propTypes = {
value: PropTypes.number,
onUpdate: PropTypes.func.isRequired
}
static defaultProps = {
value: 0
}
getValue() {
return parseInt(this.range.value, 10);
}
render() {
const { value, onUpdate, ...rest } = this.props;
return [
<input
{ ...rest }
key="range"
ref={ node => this.range = node }
type="range"
min="0"
max="100"
/>,
<button
key="submit"
className="btn btn-default"
onClick={ () => onUpdate(this.getValue()) }
>
done
</button>
];
}
}
const columns = [
..., {
dataField: 'quality',
text: 'Product Quality',
editorRenderer: (editorProps, value, row, column, rowIndex, columnIndex) => (
<QualityRanger { ...editorProps } value={ value } />
)
}];
```

View File

@@ -0,0 +1,19 @@
import wrapperFactory from './src/wrapper';
import editingCellFactory from './src/editing-cell';
import {
EDITTYPE,
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
});
export const Type = EDITTYPE;

View File

@@ -0,0 +1,47 @@
{
"name": "react-bootstrap-table2-editor",
"version": "0.2.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,61 @@
/* eslint no-return-assign: 0 */
import React, { Component } from 'react';
import cs from 'classnames';
import PropTypes from 'prop-types';
class CheckBoxEditor extends Component {
constructor(props) {
super(props);
this.state = {
checked: props.defaultValue.toString() === props.value.split(':')[0]
};
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
this.checkbox.focus();
}
getValue() {
const [positive, negative] = this.props.value.split(':');
return this.checkbox.checked ? positive : negative;
}
handleChange(e) {
if (this.props.onChange) this.props.onChange(e);
const { target } = e;
this.setState(() => ({ checked: target.checked }));
}
render() {
const { defaultValue, className, ...rest } = this.props;
const editorClass = cs('editor edit-chseckbox checkbox', className);
return (
<input
ref={ node => this.checkbox = node }
type="checkbox"
className={ editorClass }
{ ...rest }
checked={ this.state.checked }
onChange={ this.handleChange }
/>
);
}
}
CheckBoxEditor.propTypes = {
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
]),
value: PropTypes.string,
defaultValue: PropTypes.any,
onChange: PropTypes.func
};
CheckBoxEditor.defaultProps = {
className: '',
value: 'on:off',
defaultValue: false,
onChange: undefined
};
export default CheckBoxEditor;

View File

@@ -0,0 +1,12 @@
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';
export const EDITTYPE = {
TEXT: 'text',
SELECT: 'select',
TEXTAREA: 'textarea',
CHECKBOX: 'checkbox',
DATE: 'date'
};

View File

@@ -0,0 +1,42 @@
/* eslint no-return-assign: 0 */
import React, { Component } from 'react';
import cs from 'classnames';
import PropTypes from 'prop-types';
class DateEditor extends Component {
componentDidMount() {
const { defaultValue } = this.props;
this.date.valueAsDate = new Date(defaultValue);
this.date.focus();
}
getValue() {
return this.date.value;
}
render() {
const { defaultValue, className, ...rest } = this.props;
const editorClass = cs('form-control editor edit-date', className);
return (
<input
ref={ node => this.date = node }
type="date"
className={ editorClass }
{ ...rest }
/>
);
}
}
DateEditor.propTypes = {
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
]),
defaultValue: PropTypes.string
};
DateEditor.defaultProps = {
className: '',
defaultValue: ''
};
export default DateEditor;

View File

@@ -0,0 +1,61 @@
/* eslint no-return-assign: 0 */
import React, { Component } from 'react';
import cs from 'classnames';
import PropTypes from 'prop-types';
class DropDownEditor extends Component {
componentDidMount() {
const { defaultValue } = this.props;
this.select.value = defaultValue;
this.select.focus();
}
getValue() {
return this.select.value;
}
render() {
const { defaultValue, className, options, ...rest } = this.props;
const editorClass = cs('form-control editor edit-select', className);
const attr = {
...rest,
className: editorClass
};
return (
<select
{ ...attr }
ref={ node => this.select = node }
defaultValue={ defaultValue }
>
{
options.map(({ label, value }) => (
<option key={ value } value={ value }>{ label }</option>
))
}
</select>
);
}
}
DropDownEditor.propTypes = {
defaultValue: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
className: PropTypes.string,
style: PropTypes.object,
options: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string,
value: PropTypes.any
}))
]).isRequired
};
DropDownEditor.defaultProps = {
className: '',
defaultValue: '',
style: {}
};
export default DropDownEditor;

View File

@@ -0,0 +1,193 @@
/* 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 DropdownEditor from './dropdown-editor';
import TextAreaEditor from './textarea-editor';
import CheckBoxEditor from './checkbox-editor';
import DateEditor from './date-editor';
import TextEditor from './text-editor';
import EditorIndicator from './editor-indicator';
import { TIME_TO_CLOSE_MESSAGE, EDITTYPE } from './const';
export default _ =>
class EditingCell extends Component {
static propTypes = {
row: PropTypes.object.isRequired,
rowIndex: PropTypes.number.isRequired,
column: PropTypes.object.isRequired,
columnIndex: PropTypes.number.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(newValue) {
const { onUpdate, row, column } = 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 } = this.props;
if (blurToSave) {
this.beforeComplete(this.editor.getValue());
} else {
onEscape();
}
}
handleKeyDown(e) {
const { onEscape } = this.props;
if (e.keyCode === 27) { // ESC
onEscape();
} else if (e.keyCode === 13) { // ENTER
this.beforeComplete(this.editor.getValue());
}
}
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() {
let editor;
const { row, column, className, style, rowIndex, columnIndex } = this.props;
const { dataField } = column;
const value = _.get(row, dataField);
const hasError = _.isDefined(this.state.invalidMessage);
let customEditorClass = column.editorClasses || '';
if (_.isFunction(column.editorClasses)) {
customEditorClass = column.editorClasses(value, row, rowIndex, columnIndex);
}
let editorStyle = column.editorStyle || {};
if (_.isFunction(column.editorStyle)) {
editorStyle = column.editorStyle(value, row, rowIndex, columnIndex);
}
const editorClass = cs({
animated: hasError,
shake: hasError
}, customEditorClass);
let editorProps = {
ref: node => this.editor = node,
defaultValue: value,
style: editorStyle,
className: editorClass,
onKeyDown: this.handleKeyDown,
onBlur: this.handleBlur
};
const isDefaultEditorDefined = _.isObject(column.editor);
if (isDefaultEditorDefined) {
editorProps = {
...editorProps,
...column.editor
};
} else if (_.isFunction(column.editorRenderer)) {
editorProps = {
...editorProps,
onUpdate: this.beforeComplete
};
}
if (_.isFunction(column.editorRenderer)) {
editor = column.editorRenderer(editorProps, value, row, column, rowIndex, columnIndex);
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.SELECT) {
editor = <DropdownEditor { ...editorProps } />;
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.TEXTAREA) {
editor = <TextAreaEditor { ...editorProps } />;
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.CHECKBOX) {
editor = <CheckBoxEditor { ...editorProps } />;
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.DATE) {
editor = <DateEditor { ...editorProps } />;
} else {
editor = <TextEditor { ...editorProps } />;
}
return (
<td
className={ cs('react-bootstrap-table-editing-cell', className) }
style={ style }
onClick={ this.handleClick }
>
{ editor }
{ hasError ? <EditorIndicator invalidMessage={ this.state.invalidMessage } /> : null }
</td>
);
}
};

View File

@@ -10,6 +10,10 @@ class TextEditor extends Component {
this.text.focus(); this.text.focus();
} }
getValue() {
return this.text.value;
}
render() { render() {
const { defaultValue, className, ...rest } = this.props; const { defaultValue, className, ...rest } = this.props;
const editorClass = cs('form-control editor edit-text', className); const editorClass = cs('form-control editor edit-text', className);
@@ -32,9 +36,10 @@ TextEditor.propTypes = {
defaultValue: PropTypes.oneOfType([ defaultValue: PropTypes.oneOfType([
PropTypes.string, PropTypes.string,
PropTypes.number PropTypes.number
]).isRequired ])
}; };
TextEditor.defaultProps = { TextEditor.defaultProps = {
className: null className: null,
defaultValue: ''
}; };
export default TextEditor; export default TextEditor;

View File

@@ -0,0 +1,60 @@
/* eslint no-return-assign: 0 */
import React, { Component } from 'react';
import cs from 'classnames';
import PropTypes from 'prop-types';
class TextAreaEditor extends Component {
constructor(props) {
super(props);
this.handleKeyDown = this.handleKeyDown.bind(this);
}
componentDidMount() {
const { defaultValue } = this.props;
this.text.value = defaultValue;
this.text.focus();
}
getValue() {
return this.text.value;
}
handleKeyDown(e) {
if (e.keyCode === 13 && !e.shiftKey) return;
if (this.props.onKeyDown) {
this.props.onKeyDown(e);
}
}
render() {
const { defaultValue, className, ...rest } = this.props;
const editorClass = cs('form-control editor edit-textarea', className);
return (
<textarea
ref={ node => this.text = node }
type="textarea"
className={ editorClass }
{ ...rest }
onKeyDown={ this.handleKeyDown }
/>
);
}
}
TextAreaEditor.propTypes = {
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
]),
defaultValue: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
onKeyDown: PropTypes.func
};
TextAreaEditor.defaultProps = {
className: '',
defaultValue: '',
onKeyDown: undefined
};
export default TextAreaEditor;

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

@@ -0,0 +1,541 @@
/* eslint react/prop-types: 0 */
import 'jsdom-global/register';
import React from 'react';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
import _ from 'react-bootstrap-table-next/src/utils';
import editingCellFactory from '../src/editing-cell';
import * as constants from '../src/const';
import TextEditor from '../src/text-editor';
import DateEditor from '../src/date-editor';
import DropDownEditor from '../src/dropdown-editor';
import TextAreaEditor from '../src/textarea-editor';
import CheckBoxEditor from '../src/checkbox-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;
let onUpdate;
let onEscape;
const row = {
id: 1,
name: 'A'
};
const rowIndex = 1;
const columnIndex = 1;
let column = {
dataField: 'id',
text: 'ID'
};
beforeEach(() => {
onEscape = sinon.stub();
onUpdate = sinon.stub();
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render default editor successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find('td').length).toBe(1);
expect(wrapper.find(TextEditor).length).toBe(1);
expect(wrapper.state().invalidMessage).toBeNull();
});
it('should render TextEditor with correct props', () => {
const textEditor = wrapper.find(TextEditor);
expect(textEditor.props().defaultValue).toEqual(row[column.dataField]);
expect(textEditor.props().onKeyDown).toBeDefined();
expect(textEditor.props().onBlur).toBeDefined();
expect(textEditor.props().className).toEqual('');
});
it('should not render EditorIndicator due to state.invalidMessage is null', () => {
const indicator = wrapper.find(EditorIndicator);
expect(indicator.length).toEqual(0);
});
it('when press ENTER on TextEditor should call onUpdate correctly', () => {
const newValue = 'test';
const textEditor = wrapper.find(TextEditor);
sinon.stub(textEditor.instance(), 'getValue').returns(newValue);
textEditor.simulate('keyDown', { keyCode: 13 });
expect(onUpdate.callCount).toBe(1);
expect(onUpdate.calledWith(row, column, newValue)).toBe(true);
});
it('when press ESC on TextEditor should call onEscape correctly', () => {
const textEditor = wrapper.find(TextEditor);
textEditor.simulate('keyDown', { keyCode: 27 });
expect(onEscape.callCount).toBe(1);
});
it('when blur from TextEditor should call onEscape correctly', () => {
const textEditor = wrapper.find(TextEditor);
textEditor.simulate('blur');
expect(onEscape.callCount).toBe(1);
});
describe('if style prop is defined', () => {
const customStyle = { backgroundColor: 'red' };
beforeEach(() => {
wrapper = shallow(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
style={ customStyle }
/>
);
});
it('should render component with style successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.find('td').prop('style')).toEqual(customStyle);
});
});
describe('if className prop is defined', () => {
const className = 'test-class';
beforeEach(() => {
wrapper = shallow(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
className={ className }
/>
);
});
it('should render component with style successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.hasClass(className)).toBe(true);
});
});
describe('if column.editorClasses is defined', () => {
let columnWithEditorClasses;
const classes = 'test test1';
describe('and it is a function', () => {
beforeEach(() => {
columnWithEditorClasses = {
...column,
editorClasses: jest.fn(() => classes)
};
wrapper = shallow(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ columnWithEditorClasses }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render TextEditor with correct props', () => {
const textEditor = wrapper.find(TextEditor);
expect(textEditor.props().className).toEqual(classes);
});
it('should call column.editorClasses correctly', () => {
expect(columnWithEditorClasses.editorClasses).toHaveBeenCalledTimes(1);
expect(columnWithEditorClasses.editorClasses).toHaveBeenCalledWith(
_.get(row, column.dataField),
row,
rowIndex,
columnIndex
);
});
});
describe('and it is a string', () => {
beforeEach(() => {
columnWithEditorClasses = {
...column,
editorClasses: classes
};
wrapper = shallow(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ columnWithEditorClasses }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render TextEditor with correct props', () => {
const textEditor = wrapper.find(TextEditor);
expect(textEditor.props().className).toEqual(classes);
});
});
});
describe('if column.editorStyle is defined', () => {
let columnWithEditorStyle;
const style = { color: 'red' };
describe('and it is a function', () => {
beforeEach(() => {
columnWithEditorStyle = {
...column,
editorStyle: jest.fn(() => style)
};
wrapper = shallow(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ columnWithEditorStyle }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render TextEditor with correct props', () => {
const textEditor = wrapper.find(TextEditor);
expect(textEditor.props().style).toEqual(style);
});
it('should call column.editorStyle correctly', () => {
expect(columnWithEditorStyle.editorStyle).toHaveBeenCalledTimes(1);
expect(columnWithEditorStyle.editorStyle).toHaveBeenCalledWith(
_.get(row, column.dataField),
row,
rowIndex,
columnIndex
);
});
});
describe('and it is an object', () => {
beforeEach(() => {
columnWithEditorStyle = {
...column,
editorStyle: style
};
wrapper = shallow(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ columnWithEditorStyle }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render TextEditor with correct props', () => {
const textEditor = wrapper.find(TextEditor);
expect(textEditor.props().style).toEqual(style);
});
});
});
describe('if blurToSave prop is true', () => {
beforeEach(() => {
wrapper = mount(
<TableRowWrapper>
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
blurToSave
/>
</TableRowWrapper>
);
});
it('when blur from TextEditor should call onUpdate correctly', () => {
const textEditor = wrapper.find(TextEditor);
textEditor.simulate('blur');
expect(onUpdate.callCount).toBe(1);
expect(onUpdate.calledWith(row, column, `${row[column.dataField]}`)).toBe(true);
});
});
describe('when column.validator is defined', () => {
let newValue;
let validForm;
let validatorCallBack;
describe('and column.validator return an object', () => {
beforeEach(() => {
newValue = 'newValue';
validForm = { valid: false, message: 'Something is invalid' };
validatorCallBack = sinon.stub().returns(validForm);
column = {
dataField: 'id',
text: 'ID',
validator: validatorCallBack
};
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
wrapper.instance().beforeComplete(newValue);
});
it('should call column.validator successfully', () => {
expect(validatorCallBack.callCount).toBe(1);
expect(validatorCallBack.calledWith(newValue, row, column)).toBe(true);
});
it('should not call onUpdate', () => {
expect(onUpdate.callCount).toBe(0);
});
it('should set indicatorTimer successfully', () => {
expect(wrapper.instance().indicatorTimer).toBeDefined();
});
it('should set invalidMessage state correctly', () => {
expect(wrapper.state().invalidMessage).toEqual(validForm.message);
});
it('should render TextEditor with correct shake and animated class', () => {
const editor = wrapper.find(TextEditor);
expect(editor.html()).toEqual('<input type="text" class="form-control editor edit-text animated shake">');
/* Following is better, but it will not work after upgrade React to 16 and enzyme... */
// expect(editor.length).toEqual(1);
// expect(editor.props().classNames).toEqual('animated shake');
});
/* Following is better, but it will not work after upgrade React to 16 and enzyme... */
xit('should render EditorIndicator correctly', () => {
const indicator = wrapper.find(EditorIndicator);
expect(indicator.length).toEqual(1);
expect(indicator.props().invalidMessage).toEqual(validForm.message);
});
});
describe('and column.validator return true or something', () => {
beforeEach(() => {
newValue = 'newValue';
validForm = true;
validatorCallBack = sinon.stub().returns(validForm);
column = {
dataField: 'id',
text: 'ID',
validator: validatorCallBack
};
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
wrapper.instance().beforeComplete(newValue);
});
it('should call column.validator successfully', () => {
expect(validatorCallBack.callCount).toBe(1);
expect(validatorCallBack.calledWith(newValue, row, column)).toBe(true);
});
it('should call onUpdate', () => {
expect(onUpdate.callCount).toBe(1);
});
});
});
describe('if column.editorRenderer is defined', () => {
const TestEditor = () => <input type="text" />;
beforeEach(() => {
column = {
dataField: 'id',
text: 'ID',
editorRenderer: sinon.stub().returns(<TestEditor />)
};
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should call column.editorRenderer correctly', () => {
expect(column.editorRenderer.callCount).toBe(1);
});
it('should render correctly', () => {
expect(wrapper.find(TestEditor)).toHaveLength(1);
});
});
describe('if column.editor is select', () => {
beforeEach(() => {
column = {
dataField: 'id',
text: 'ID',
editor: {
type: constants.EDITTYPE.SELECT,
options: [{
value: 1,
label: 'A'
}]
}
};
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render dropdown editor successfully', () => {
const editor = wrapper.find(DropDownEditor);
expect(wrapper.length).toBe(1);
expect(editor.length).toBe(1);
expect(editor.props().options).toEqual(column.editor.options);
});
});
describe('if column.editor is textarea', () => {
beforeEach(() => {
column = {
dataField: 'id',
text: 'ID',
editor: {
type: constants.EDITTYPE.TEXTAREA
}
};
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render textarea editor successfully', () => {
const editor = wrapper.find(TextAreaEditor);
expect(wrapper.length).toBe(1);
expect(editor.length).toBe(1);
});
});
describe('if column.editor is checkbox', () => {
beforeEach(() => {
column = {
dataField: 'id',
text: 'ID',
editor: {
type: constants.EDITTYPE.CHECKBOX
}
};
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render checkbox editor successfully', () => {
const editor = wrapper.find(CheckBoxEditor);
expect(wrapper.length).toBe(1);
expect(editor.length).toBe(1);
});
});
describe('if column.editor is date', () => {
beforeEach(() => {
column = {
dataField: 'id',
text: 'ID',
editor: {
type: constants.EDITTYPE.DATE
}
};
wrapper = mount(
<EditingCell
row={ row }
rowIndex={ rowIndex }
columnIndex={ columnIndex }
column={ column }
onUpdate={ onUpdate }
onEscape={ onEscape }
/>
);
});
it('should render date editor successfully', () => {
const editor = wrapper.find(DateEditor);
expect(wrapper.length).toBe(1);
expect(editor.length).toBe(1);
});
});
});

View File

@@ -2,7 +2,7 @@ import 'jsdom-global/register';
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import TextEditor from '../../src/cell-edit/text-editor'; import TextEditor from '../src/text-editor';
describe('TextEditor', () => { describe('TextEditor', () => {
let wrapper; 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 path = require('path');
const sourcePath = path.join(__dirname, '../../react-bootstrap-table2/src'); const sourcePath = path.join(__dirname, '../../react-bootstrap-table2/index.js');
const paginationSourcePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/src'); const paginationSourcePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/index.js');
const overlaySourcePath = path.join(__dirname, '../../react-bootstrap-table2-overlay/src'); const overlaySourcePath = path.join(__dirname, '../../react-bootstrap-table2-overlay/index.js');
const filterSourcePath = path.join(__dirname, '../../react-bootstrap-table2-filter/src'); 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 sourceStylePath = path.join(__dirname, '../../react-bootstrap-table2/style');
const paginationStylePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/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 storyPath = path.join(__dirname, '../stories');
const examplesPath = path.join(__dirname, '../examples'); const examplesPath = path.join(__dirname, '../examples');
const srcPath = path.join(__dirname, '../src'); const srcPath = path.join(__dirname, '../src');
@@ -15,6 +17,12 @@ const aliasPath = {
src: srcPath, src: srcPath,
components: path.join(srcPath, 'components'), components: path.join(srcPath, 'components'),
utils: path.join(srcPath, 'utils'), 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 = [{ const loaders = [{
@@ -26,15 +34,14 @@ const loaders = [{
}, { }, {
test: /\.js?$/, test: /\.js?$/,
use: ['babel-loader'], use: ['babel-loader'],
exclude: /node_modules/, exclude: /node_modules/
include: [sourcePath, paginationSourcePath, overlaySourcePath, filterSourcePath, storyPath],
}, { }, {
test: /\.css$/, test: /\.css$/,
use: ['style-loader', 'css-loader'], use: ['style-loader', 'css-loader'],
}, { }, {
test: /\.scss$/, test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'], use: ['style-loader', 'css-loader', 'sass-loader'],
include: [storyPath, sourceStylePath, paginationStylePath], include: [storyPath, sourceStylePath, paginationStylePath, filterStylePath],
}, { }, {
test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/, test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000', loader: 'url-loader?limit=100000',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,8 @@
/* eslint no-console: 0 */ /* eslint no-console: 0 */
import React from 'react'; 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 Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common'; import { productsGenerator } from 'utils/common';
@@ -20,6 +21,9 @@ const columns = [{
}]; }];
const sourceCode = `\ const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{ const columns = [{
dataField: 'id', dataField: 'id',
text: 'Product ID' text: 'Product ID'
@@ -31,28 +35,30 @@ const columns = [{
text: 'Product Price' 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 <BootstrapTable
keyField='id' keyField="id"
data={ products } data={ products }
columns={ columns } 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 () => ( export default () => (
<div> <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> <Code>{ sourceCode }</Code>
</div> </div>
); );

View File

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

View File

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

View File

@@ -0,0 +1,64 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { todosGenerator } from 'utils/common';
const todos = todosGenerator();
const columns = [{
dataField: 'id',
text: 'Todo ID'
}, {
dataField: 'todo',
text: 'Todo Name'
}, {
dataField: 'done',
text: 'Done',
editor: {
type: Type.CHECKBOX,
value: 'Y:N'
}
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Todo ID'
}, {
dataField: 'todo',
text: 'Todo Name'
}, {
dataField: 'done',
text: 'Done',
editor: {
type: Type.CHECKBOX,
value: 'Y:N'
}
}];
<BootstrapTable
keyField="id"
data={ todos }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
`;
export default () => (
<div>
<h3>Dropdown Editor</h3>
<BootstrapTable
keyField="id"
data={ todos }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

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

View File

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

View File

@@ -0,0 +1,130 @@
/* eslint react/prefer-stateless-function: 0 */
/* eslint no-return-assign: 0 */
/* eslint no-unused-vars: 0 */
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 { productsQualityGenerator } from 'utils/common';
const products = productsQualityGenerator();
class QualityRanger extends React.Component {
static propTypes = {
value: PropTypes.number,
onUpdate: PropTypes.func.isRequired
}
static defaultProps = {
value: 0
}
getValue() {
return parseInt(this.range.value, 10);
}
render() {
const { value, onUpdate, ...rest } = this.props;
return [
<input
{ ...rest }
key="range"
ref={ node => this.range = node }
type="range"
min="0"
max="100"
/>,
<button
key="submit"
className="btn btn-default"
onClick={ () => onUpdate(this.getValue()) }
>
done
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quality',
editorRenderer: (editorProps, value, row, column, rowIndex, columnIndex) => (
<QualityRanger { ...editorProps } value={ value } />
)
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
class QualityRanger extends React.Component {
static propTypes = {
value: PropTypes.number,
onUpdate: PropTypes.func.isRequired
}
static defaultProps = {
value: 0
}
getValue() {
return parseInt(this.range.value, 10);
}
render() {
const { value, onUpdate, ...rest } = this.props;
return [
<input
{ ...rest }
key="range"
ref={ node => this.range = node }
type="range"
min="0"
max="100"
/>,
<button
key="submit"
className="btn btn-default"
onClick={ () => onUpdate(this.getValue()) }
>
done
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quality',
editorRenderer: (editorProps, value, row, rowIndex, columnIndex) => (
<QualityRanger { ...editorProps } value={ value } />
)
}];
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
`;
export default () => (
<div>
<h3>Dropdown Editor</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,77 @@
/* eslint prefer-template: 0 */
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { stockGenerator } from 'utils/common';
const stocks = stockGenerator();
const columns = [{
dataField: 'id',
text: 'ID'
}, {
dataField: 'name',
text: 'Name'
}, {
dataField: 'inStockDate',
text: 'Stock Date',
formatter: (cell) => {
let dateObj = cell;
if (typeof cell !== 'object') {
dateObj = new Date(cell);
}
return `${('0' + dateObj.getDate()).slice(-2)}/${('0' + (dateObj.getMonth() + 1)).slice(-2)}/${dateObj.getFullYear()}`;
},
editor: {
type: Type.DATE
}
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'ID'
}, {
dataField: 'name',
text: 'Name'
}, {
dataField: 'inStockDate',
text: 'Stock Date',
formatter: (cell) => {
let dateObj = cell;
if (typeof cell !== 'object') {
dateObj = new Date(cell);
}
return \`$\{('0' + dateObj.getDate()).slice(-2)}/$\{('0' + (dateObj.getMonth() + 1)).slice(-2)}/$\{dateObj.getFullYear()}\`;
},
editor: {
type: Type.DATE
}
}];
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
`;
export default () => (
<div>
<h3>Dropdown Editor</h3>
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

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

View File

@@ -0,0 +1,100 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { jobsGenerator } from 'utils/common';
const jobs = jobsGenerator();
const columns = [{
dataField: 'id',
text: 'Job ID'
}, {
dataField: 'name',
text: 'Job Name'
}, {
dataField: 'owner',
text: 'Job Owner'
}, {
dataField: 'type',
text: 'Job Type',
editor: {
type: Type.SELECT,
options: [{
value: 'A',
label: 'A'
}, {
value: 'B',
label: 'B'
}, {
value: 'C',
label: 'C'
}, {
value: 'D',
label: 'D'
}, {
value: 'E',
label: 'E'
}]
}
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Job ID'
}, {
dataField: 'name',
text: 'Job Name'
}, {
dataField: 'owner',
text: 'Job Owner'
}, {
dataField: 'type',
text: 'Job Type',
editor: {
type: Type.SELECT,
options: [{
value: 'A',
label: 'A'
}, {
value: 'B',
label: 'B'
}, {
value: 'C',
label: 'C'
}, {
value: 'D',
label: 'D'
}, {
value: 'E',
label: 'E'
}]
}
}];
<BootstrapTable
keyField="id"
data={ jobs }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
`;
export default () => (
<div>
<h3>Dropdown Editor</h3>
<BootstrapTable
keyField="id"
data={ jobs }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,61 @@
/* eslint no-unused-vars: 0 */
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';
const products = productsGenerator();
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
editorClasses: 'editing-name'
}, {
dataField: 'price',
text: 'Product Price',
editorClasses: (cell, row, rowIndex, colIndex) =>
(cell > 2101 ? 'editing-price-bigger-than-2101' : 'editing-price-small-than-2101')
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
editorClasses: 'editing-name'
}, {
dataField: 'price',
text: 'Product Price',
editorClasses: (cell, row, rowIndex, colIndex) =>
(cell > 2101 ? 'editing-price-bigger-than-2101' : 'editing-price-small-than-2101')
}];
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,69 @@
/* eslint no-unused-vars: 0 */
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';
const products = productsGenerator();
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
editorStyle: {
backgroundColor: '#20B2AA'
}
}, {
dataField: 'price',
text: 'Product Price',
editorStyle: (cell, row, rowIndex, colIndex) => {
const backgroundColor = cell > 2101 ? '#00BFFF' : '#00FFFF';
return { backgroundColor };
}
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
editorStyle: {
backgroundColor: '#20B2AA'
}
}, {
dataField: 'price',
text: 'Product Price',
editorStyle: (cell, row, rowIndex, colIndex) => {
const backgroundColor = cell > 2101 ? '#00BFFF' : '#00FFFF';
return { backgroundColor };
}
}];
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click' }) }
/>
`;
export default () => (
<div>
<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 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 Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common'; import { productsGenerator } from 'utils/common';
@@ -18,6 +19,9 @@ const columns = [{
}]; }];
const sourceCode = `\ const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{ const columns = [{
dataField: 'id', dataField: 'id',
text: 'Product ID' text: 'Product ID'
@@ -29,29 +33,30 @@ const columns = [{
text: 'Product Price' text: 'Product Price'
}]; }];
const cellEdit = {
mode: 'click',
blurToSave: true,
// Product ID: 0, 3 will be non-editable
nonEditableRows: () => [0, 3]
};
<BootstrapTable <BootstrapTable
keyField='id' keyField="id"
data={ products } data={ products }
columns={ columns } columns={ columns }
cellEdit={ cellEdit } cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true,
nonEditableRows: () => [0, 3]
}) }
/> />
`; `;
const cellEdit = {
mode: 'click',
blurToSave: true,
nonEditableRows: () => [0, 3]
};
export default () => ( export default () => (
<div> <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> <Code>{ sourceCode }</Code>
</div> </div>
); );

View File

@@ -0,0 +1,68 @@
/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { jobsGenerator } from 'utils/common';
const jobs = jobsGenerator();
const columns = [{
dataField: 'id',
text: 'Job ID'
}, {
dataField: 'name',
text: 'Job Name'
}, {
dataField: 'owner',
text: 'Job Owner'
}, {
dataField: 'type',
text: 'Job Type',
editor: {
type: Type.TEXTAREA
}
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Job ID'
}, {
dataField: 'name',
text: 'Job Name'
}, {
dataField: 'owner',
text: 'Job Owner'
}, {
dataField: 'type',
text: 'Job Type',
editor: {
type: Type.TEXTAREA
}
}];
<BootstrapTable
keyField="id"
data={ jobs }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
`;
export default () => (
<div>
<h3>Dropdown Editor</h3>
<BootstrapTable
keyField="id"
data={ jobs }
columns={ columns }
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,184 @@
/* eslint no-return-assign: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter, Comparator, FILTER_TYPES } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
this.onChange = this.onChange.bind(this);
this.state = { value: 2100 };
}
onChange(e) {
this.setState({ value: e.target.value });
}
getValue() {
return parseInt(this.range.value, 10);
}
filter() {
this.props.onFilter({
number: this.getValue(),
comparator: this.select.value
});
}
render() {
return [
<input
key="range"
ref={ node => this.range = node }
type="range"
min="2100"
max="2110"
onChange={ this.onChange }
/>,
<p
key="show"
ref={ node => this.showValue = node }
style={ { textAlign: 'center' } }
>
{ this.state.value }
</p>,
<select
key="select"
ref={ node => this.select = node }
className="form-control"
>
<option value={ Comparator.GT }>&gt;</option>
<option value={ Comparator.EQ }>=</option>
<option value={ Comparator.LT }>&lt;</option>
</select>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ `Filter ${this.props.column.text}` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter({
type: FILTER_TYPES.NUMBER // ask react-bootstrap-table to filter data as number
}),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter, Comparator, FILTER_TYPES } from 'react-bootstrap-table2-filter';
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
this.onChange = this.onChange.bind(this);
this.state = { value: 2100 };
}
onChange(e) {
this.setState({ value: e.target.value });
}
getValue() {
return parseInt(this.range.value, 10);
}
filter() {
this.props.onFilter({
number: this.getValue(),
comparator: this.select.value
});
}
render() {
return [
<input
key="range"
ref={ node => this.range = node }
type="range"
min="2100"
max="2110"
onChange={ this.onChange }
/>,
<p
key="show"
ref={ node => this.showValue = node }
style={ { textAlign: 'center' } }
>
{ this.state.value }
</p>,
<select
key="select"
ref={ node => this.select = node }
className="form-control"
>
<option value={ Comparator.GT }>&gt;</option>
<option value={ Comparator.EQ }>=</option>
<option value={ Comparator.LT }>&lt;</option>
</select>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ \`Filter $\{this.props.column.text}\` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter({
type: FILTER_TYPES.NUMBER // ask react-bootstrap-table to filter data as number
}),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
<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,77 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { stockGenerator } from 'utils/common';
const stocks = stockGenerator(8);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter({
delay: 400,
placeholder: 'custom placeholder',
withoutEmptyComparatorOption: true,
comparators: [Comparator.EQ, Comparator.GT, Comparator.LT],
style: { display: 'inline-grid' },
className: 'custom-datefilter-class',
comparatorStyle: { backgroundColor: 'antiquewhite' },
comparatorClassName: 'custom-comparator-class',
dateStyle: { backgroundColor: 'cadetblue', margin: '0px' },
dateClassName: 'custom-date-class'
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter } from 'react-bootstrap-table2-filter';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter({
delay: 400,
placeholder: 'custom placeholder',
withoutEmptyComparatorOption: true,
comparators: [Comparator.EQ, Comparator.GT, Comparator.LT],
style: { display: 'inline-grid' },
className: 'custom-datefilter-class',
comparatorStyle: { backgroundColor: 'antiquewhite' },
comparatorClassName: 'custom-comparator-class',
dateStyle: { backgroundColor: 'cadetblue', margin: '0px' },
dateClassName: 'custom-date-class'
})
}];
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
filter={ filterFactory() }
/>
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

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

View File

@@ -0,0 +1,128 @@
/* eslint no-return-assign: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
}
getValue() {
return this.input.value;
}
filter() {
this.props.onFilter(this.getValue());
}
render() {
return [
<input
key="input"
ref={ node => this.input = node }
type="text"
placeholder="Input price"
/>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ `Find ${this.props.column.text}` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter(),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
class PriceFilter extends React.Component {
static propTypes = {
column: PropTypes.object.isRequired,
onFilter: PropTypes.func.isRequired
}
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
this.getValue = this.getValue.bind(this);
}
getValue() {
return this.input.value;
}
filter() {
this.props.onFilter(this.getValue());
}
render() {
return [
<input
key="input"
ref={ node => this.input = node }
type="text"
placeholder="Input price"
/>,
<button
key="submit"
className="btn btn-warning"
onClick={ this.filter }
>
{ \`Filter $\{this.props.column.text}\` }
</button>
];
}
}
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price',
filter: customFilter(),
filterRenderer: (onFilter, column) =>
<PriceFilter onFilter={ onFilter } column={ column } />
}];
<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,74 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter({
options: [2100, 2103, 2105],
delay: 600,
placeholder: 'custom placeholder',
withoutEmptyComparatorOption: true,
comparators: [Comparator.EQ, Comparator.GT, Comparator.LT],
style: { display: 'inline-grid' },
className: 'custom-numberfilter-class',
comparatorStyle: { backgroundColor: 'antiquewhite' },
comparatorClassName: 'custom-comparator-class',
numberStyle: { backgroundColor: 'cadetblue', margin: '0px' },
numberClassName: 'custom-number-class'
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter({
options: [2100, 2103, 2105],
delay: 600,
placeholder: 'custom placeholder',
withoutEmptyComparatorOption: true,
comparators: [Comparator.EQ, Comparator.GT, Comparator.LT],
style: { display: 'inline-grid' },
className: 'custom-numberfilter-class',
comparatorStyle: { backgroundColor: 'antiquewhite' },
comparatorClassName: 'custom-comparator-class',
numberStyle: { backgroundColor: 'cadetblue', margin: '0px' },
numberClassName: 'custom-number-class'
})
}];
<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,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 */ /* eslint no-console: 0 */
import React from 'react'; 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 filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block'; import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common'; import { productsGenerator } from 'utils/common';
@@ -29,6 +29,7 @@ const columns = [{
}]; }];
const sourceCode = `\ const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const columns = [{ const columns = [{

View File

@@ -0,0 +1,59 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { stockGenerator } from 'utils/common';
const stocks = stockGenerator(8);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter({
defaultValue: { date: new Date(2018, 0, 1), comparator: Comparator.GT }
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter } from 'react-bootstrap-table2-filter';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter({
defaultValue: { date: new Date(2018, 0, 1), comparator: Comparator.GT }
})
}];
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
filter={ filterFactory() }
/>
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,55 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { stockGenerator } from 'utils/common';
const stocks = stockGenerator(8);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter()
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter } from 'react-bootstrap-table2-filter';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter()
}];
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
filter={ filterFactory() }
/>
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,54 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter({
defaultValue: { number: 2103, comparator: Comparator.GT }
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter({
defaultValue: { number: 2103, comparator: Comparator.GT }
})
}];
<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,50 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter()
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter()
}];
<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,85 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { stockGenerator } from 'utils/common';
const stocks = stockGenerator(8);
let inStockDateFilter;
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter({
getFilter: (filter) => {
// inStockDateFilter was assigned once the component has been mounted.
inStockDateFilter = filter;
}
})
}];
const handleClick = () => {
inStockDateFilter({
date: new Date(2018, 0, 1),
comparator: Comparator.GT
});
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { dateFilter, Comparator } from 'react-bootstrap-table2-filter';
let inStockDateFilter;
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'inStockDate',
text: 'InStock Date',
filter: dateFilter({
getFilter: (filter) => {
// inStockDateFilter was assigned once the component has been mounted.
inStockDateFilter = filter;
}
})
}];
const handleClick = () => {
inStockDateFilter({
date: new Date(2018, 0, 1),
comparator: Comparator.GT
});
};
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }> filter InStock Date columns which is greater than 2018.01.01 </button>
<BootstrapTable keyField='id' data={ stocks } columns={ columns } filter={ filterFactory() } />
</div>
);
`;
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }> filter InStock Date columns which is greater than 2018.01.01 </button>
<BootstrapTable
keyField="id"
data={ stocks }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,85 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter, Comparator } from 'react-bootstrap-table2-filter';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const products = productsGenerator(8);
let priceFilter;
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter({
getFilter: (filter) => {
// pricerFilter was assigned once the component has been mounted.
priceFilter = filter;
}
})
}];
const handleClick = () => {
priceFilter({
number: 2103,
comparator: Comparator.GT
});
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { numberFilter } from 'react-bootstrap-table2-filter';
let priceFilter;
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price',
filter: numberFilter({
getFilter: (filter) => {
// pricerFilter was assigned once the component has been mounted.
priceFilter = filter;
}
})
}];
const handleClick = () => {
priceFilter({
number: 2103,
comparator: Comparator.GT
});
};
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }> filter all columns which is greater than 2103 </button>
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
</div>
);
`;
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }> filter all columns which is greater than 2103 </button>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,96 @@
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);
let qualityFilter;
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quality',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions,
getFilter: (filter) => {
// qualityFilter was assigned once the component has been mounted.
qualityFilter = filter;
}
})
}];
const handleClick = () => {
qualityFilter(0);
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
let qualityFilter;
const selectOptions = {
0: 'good',
1: 'Bad',
2: 'unknown'
};
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quality',
formatter: cell => selectOptions[cell],
filter: selectFilter({
options: selectOptions,
getFilter: (filter) => {
// qualityFilter was assigned once the component has been mounted.
qualityFilter = filter;
}
})
}];
const handleClick = () => {
qualityFilter(0);
};
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }>{' filter columns by option "good" '}</button>
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
</div>
);
`;
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }>{' filter columns by option "good" '}</button>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -0,0 +1,81 @@
import React from 'react';
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';
const products = productsGenerator(8);
let nameFilter;
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter({
getFilter: (filter) => {
// nameFilter was assigned once the component has been mounted.
nameFilter = filter;
}
})
}, {
dataField: 'price',
text: 'Product Price',
filter: textFilter()
}];
const handleClick = () => {
nameFilter(0);
};
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
let nameFilter;
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter({
getFilter: (filter) => {
// nameFilter was assigned once the component has been mounted.
nameFilter = filter;
}
})
}, {
dataField: 'price',
text: 'Product Price',
filter: textFilter()
}];
const handleClick = () => {
nameFilter(0);
};
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }> filter columns by 0 </button>
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
</div>
);
`;
export default () => (
<div>
<button className="btn btn-lg btn-primary" onClick={ handleClick }> filter columns by 0 </button>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

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

@@ -0,0 +1,51 @@
import React from 'react';
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';
const products = productsGenerator(8);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter({ caseSensitive: true })
}, {
dataField: 'price',
text: 'Product Price'
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter({ caseSensitive: true })
}, {
dataField: 'price',
text: 'Product Price'
}];
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
`;
export default () => (
<div>
<h3>Product Name is case sensitive</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
filter={ filterFactory() }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
/* eslint no-alert: 0 */ /* eslint no-alert: 0 */
import React from 'react'; 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 Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common'; import { productsGenerator } from 'utils/common';
@@ -23,10 +23,12 @@ const columns = [{
}]; }];
const sourceCode = `\ const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = [{ const columns = [{
dataField: 'id', dataField: 'id',
text: 'Product ID', text: 'Product ID',
events: { headerEvents: {
onClick: () => alert('Click on Product ID header column') onClick: () => alert('Click on Product ID header column')
} }
}, { }, {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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