mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-06-29 13:40:07 +00:00
Compare commits
566 Commits
react-boot
...
react-boot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a44384e3c | ||
|
|
ec742a43f6 | ||
|
|
7138b68559 | ||
|
|
e6e7d6f9d2 | ||
|
|
909a6e211e | ||
|
|
83c9d69e27 | ||
|
|
aad2ad3823 | ||
|
|
9190cfc6d9 | ||
|
|
45b133579b | ||
|
|
970f7c0d15 | ||
|
|
def898f636 | ||
|
|
be916d81a3 | ||
|
|
49d1ce8812 | ||
|
|
18caf0ac8d | ||
|
|
1b9bd63370 | ||
|
|
b2121fdf24 | ||
|
|
4aaf140de5 | ||
|
|
569aa0195e | ||
|
|
cf5b24e9e8 | ||
|
|
da86b4aa1a | ||
|
|
7d28d46185 | ||
|
|
16128e77e6 | ||
|
|
ec1f96cd1f | ||
|
|
00b1558df0 | ||
|
|
4dc5e6099f | ||
|
|
d9acbace67 | ||
|
|
7c8bf00cde | ||
|
|
63df43a1e0 | ||
|
|
bb42514e56 | ||
|
|
79e3247921 | ||
|
|
c25192145f | ||
|
|
056957b0b5 | ||
|
|
c12d3faba3 | ||
|
|
963b8d669b | ||
|
|
47f6340a99 | ||
|
|
23cb0bb317 | ||
|
|
70827eecd6 | ||
|
|
43b5eeb74f | ||
|
|
eb204f6526 | ||
|
|
2b410fb8ac | ||
|
|
110744f4cb | ||
|
|
47848e7f34 | ||
|
|
1a44ce0ea6 | ||
|
|
08ec8a9f65 | ||
|
|
27387c2a69 | ||
|
|
05b50ac71a | ||
|
|
9b6d9904e7 | ||
|
|
4de565b759 | ||
|
|
c53d2612d4 | ||
|
|
0c2863d63c | ||
|
|
a534d525c9 | ||
|
|
856e63d524 | ||
|
|
c59b963436 | ||
|
|
b50dc95e06 | ||
|
|
2619a1e424 | ||
|
|
423769c134 | ||
|
|
6530ff1570 | ||
|
|
9af61b54b1 | ||
|
|
72f7333a34 | ||
|
|
64c113da26 | ||
|
|
db22bb9adb | ||
|
|
d7e1f1dfd0 | ||
|
|
c277c8139e | ||
|
|
ec4864da5c | ||
|
|
92f1449177 | ||
|
|
46258b0264 | ||
|
|
5e8bb3426a | ||
|
|
03f2ce4792 | ||
|
|
7382010822 | ||
|
|
a1a59f9419 | ||
|
|
59f184d74d | ||
|
|
643b9bca5f | ||
|
|
31724fec7f | ||
|
|
4cf6e65abc | ||
|
|
40c5ae7459 | ||
|
|
3747c36039 | ||
|
|
0d0d1a8913 | ||
|
|
db612eaa99 | ||
|
|
4d76d88e9a | ||
|
|
1cd31dc54c | ||
|
|
4ec02b294a | ||
|
|
e31b5eb691 | ||
|
|
60eb47dc9e | ||
|
|
d74ecb63b4 | ||
|
|
2c6cc915f0 | ||
|
|
a1457dfe59 | ||
|
|
036c3fdc32 | ||
|
|
55eea6f337 | ||
|
|
7c259cd1ee | ||
|
|
1e164bb3f4 | ||
|
|
8a7c1def5b | ||
|
|
77b8ed53bf | ||
|
|
6bc54ef3ec | ||
|
|
6168bd7532 | ||
|
|
36fa9b8630 | ||
|
|
737922a5a4 | ||
|
|
0f37fae23d | ||
|
|
ce7e05d7f9 | ||
|
|
067006eb72 | ||
|
|
8fa10e3b6f | ||
|
|
e2e6c51d40 | ||
|
|
fb724331d3 | ||
|
|
160dede412 | ||
|
|
363a43251f | ||
|
|
8ad0e65679 | ||
|
|
6d5cca0047 | ||
|
|
204e75c9c2 | ||
|
|
fc27c56cbb | ||
|
|
8436edba7e | ||
|
|
3606fa3b7b | ||
|
|
73e8701bde | ||
|
|
6d2493d537 | ||
|
|
1a1f6969cb | ||
|
|
d47a3757b8 | ||
|
|
ba7512969e | ||
|
|
955ee17939 | ||
|
|
497bf44192 | ||
|
|
fcefcf8c84 | ||
|
|
04e3af0bbb | ||
|
|
9f47fa009c | ||
|
|
0edf9c8891 | ||
|
|
df5024892c | ||
|
|
4448c3f28c | ||
|
|
196ae33295 | ||
|
|
7f1b7a6c97 | ||
|
|
a6ccafcc75 | ||
|
|
06d87299a3 | ||
|
|
5891ec1b93 | ||
|
|
c5d9e04c2c | ||
|
|
dba3da28c1 | ||
|
|
a0e09cd804 | ||
|
|
d0e70f7246 | ||
|
|
b93c683f17 | ||
|
|
f80e1ea66c | ||
|
|
7642bfa1a3 | ||
|
|
8f304a849f | ||
|
|
956f1cef4d | ||
|
|
c45deee590 | ||
|
|
2aab4301dd | ||
|
|
43aa280761 | ||
|
|
3af30a0265 | ||
|
|
4b8b8b261e | ||
|
|
e44782f222 | ||
|
|
921e8c7ecc | ||
|
|
a3b3ce0dc4 | ||
|
|
e9f08d278d | ||
|
|
b4973c826c | ||
|
|
33c026c7e2 | ||
|
|
6cac7f6dc8 | ||
|
|
da5b93c3cf | ||
|
|
3ffccce1fe | ||
|
|
09f21e8130 | ||
|
|
bf0c5c43a2 | ||
|
|
c01f45a719 | ||
|
|
d26c13b9be | ||
|
|
d84fd5c801 | ||
|
|
8e940112f5 | ||
|
|
6070d150a9 | ||
|
|
dab6f1b206 | ||
|
|
2a497194e7 | ||
|
|
f5f17897fd | ||
|
|
2932b8a1b8 | ||
|
|
93103e5ca0 | ||
|
|
a7c2a49182 | ||
|
|
cd27ff98ff | ||
|
|
4d815894e6 | ||
|
|
d9ff201373 | ||
|
|
8e142de332 | ||
|
|
322605f14e | ||
|
|
3156e01dd6 | ||
|
|
052284a163 | ||
|
|
3cd8efffb9 | ||
|
|
447d69cae5 | ||
|
|
cacc28e1bc | ||
|
|
d7f84a9da5 | ||
|
|
63c2630f46 | ||
|
|
903dd2e5c8 | ||
|
|
964faa53e3 | ||
|
|
8fb5364cc2 | ||
|
|
8b89b3de0e | ||
|
|
4506a3dea2 | ||
|
|
ecea3efdaa | ||
|
|
8bef7eb348 | ||
|
|
408a004f58 | ||
|
|
bf46dfa026 | ||
|
|
f1b39e3dd6 | ||
|
|
029cd3ab6f | ||
|
|
1c68892a7b | ||
|
|
1bf3fa50db | ||
|
|
9988e790c1 | ||
|
|
bb071c98f9 | ||
|
|
9c5d8aac62 | ||
|
|
7c79b64985 | ||
|
|
16f89989f0 | ||
|
|
58cfdacfd1 | ||
|
|
78d5164056 | ||
|
|
bd2ce5abf0 | ||
|
|
416fcf08d4 | ||
|
|
0c650c0682 | ||
|
|
7d30804da9 | ||
|
|
782c630e58 | ||
|
|
22cc79961f | ||
|
|
a83b3d0d78 | ||
|
|
340ddb8722 | ||
|
|
32e455e65f | ||
|
|
6c0fc2748c | ||
|
|
973ece8b39 | ||
|
|
0a94f3ce39 | ||
|
|
0ca8e54ce2 | ||
|
|
69d534e26c | ||
|
|
c2a30cb716 | ||
|
|
83dc888d17 | ||
|
|
41da9afbcb | ||
|
|
91816fcc01 | ||
|
|
620309115f | ||
|
|
297f3e0c4f | ||
|
|
d42a10bbae | ||
|
|
5c52412542 | ||
|
|
a5f74cecfe | ||
|
|
a30a8fd96b | ||
|
|
424dbea270 | ||
|
|
b261c33e37 | ||
|
|
7dbdc1943b | ||
|
|
d4be1675db | ||
|
|
d3161f02eb | ||
|
|
28ba6d5677 | ||
|
|
4ddbfd4972 | ||
|
|
d84dc46ff1 | ||
|
|
e0163625d4 | ||
|
|
24ab58a464 | ||
|
|
6e19368733 | ||
|
|
bc4697bf95 | ||
|
|
9d2a6a1b23 | ||
|
|
bb752fcec8 | ||
|
|
aedd1f5942 | ||
|
|
5a5f10f609 | ||
|
|
e041a3d736 | ||
|
|
f175fd4186 | ||
|
|
5a6b7e122d | ||
|
|
a7ae524c49 | ||
|
|
a23599f52f | ||
|
|
c50853b16d | ||
|
|
3f74542c98 | ||
|
|
47aa41b8fa | ||
|
|
67ed2e6c80 | ||
|
|
794a97956d | ||
|
|
78ca01bb1a | ||
|
|
b79dbc80f6 | ||
|
|
3f21a67620 | ||
|
|
9e3ae385ce | ||
|
|
c6ea19fe8a | ||
|
|
a5b42dca92 | ||
|
|
28f3c33db3 | ||
|
|
2530a70c00 | ||
|
|
569dd61463 | ||
|
|
68264b45ce | ||
|
|
e251068657 | ||
|
|
e4fbb284b4 | ||
|
|
a6afc9d9a8 | ||
|
|
a0ba41c103 | ||
|
|
4a16cb314d | ||
|
|
98a04a5710 | ||
|
|
c22a2a1d71 | ||
|
|
9bc25c9d3e | ||
|
|
4554db02d2 | ||
|
|
b7fac973d2 | ||
|
|
6925358631 | ||
|
|
27c3cdab29 | ||
|
|
bc0c048735 | ||
|
|
a4c1090a0f | ||
|
|
5fac4540a1 | ||
|
|
f7a06401ae | ||
|
|
858ad9543b | ||
|
|
abf618ce6d | ||
|
|
ea6cb78302 | ||
|
|
bacbfdbbf0 | ||
|
|
465212ff35 | ||
|
|
2a58f99a97 | ||
|
|
7bda61f5be | ||
|
|
7220b2d073 | ||
|
|
f7a1c91904 | ||
|
|
ea827bfeb5 | ||
|
|
f1f4bd784d | ||
|
|
569c22ba49 | ||
|
|
b1e5c0cb20 | ||
|
|
7ee38a647f | ||
|
|
01ec19344d | ||
|
|
19be67c914 | ||
|
|
ae4d38cae6 | ||
|
|
81a6428a03 | ||
|
|
166affc4c1 | ||
|
|
d0fb46e39f | ||
|
|
828844a1e9 | ||
|
|
774293b76d | ||
|
|
e77cbdb2df | ||
|
|
ef2f828572 | ||
|
|
15731932cf | ||
|
|
dd54294382 | ||
|
|
185c184f01 | ||
|
|
d45345ed10 | ||
|
|
dda8460017 | ||
|
|
6735536fd8 | ||
|
|
95623bbb5f | ||
|
|
9567c7829d | ||
|
|
8499991c41 | ||
|
|
1e76ca9bdb | ||
|
|
fa13550d8c | ||
|
|
709d59ce62 | ||
|
|
66329ecdbf | ||
|
|
ee6cec5a2d | ||
|
|
52fc84899b | ||
|
|
8c10867b8c | ||
|
|
640ada7659 | ||
|
|
73a5c34535 | ||
|
|
2879cf891e | ||
|
|
994ed2e395 | ||
|
|
4b790e4bec | ||
|
|
21e7c3a53a | ||
|
|
6fce0d7066 | ||
|
|
154f1c91c3 | ||
|
|
02d78e5104 | ||
|
|
41cc6b01af | ||
|
|
bd410e7303 | ||
|
|
eced3eef1f | ||
|
|
ca5a41a8b3 | ||
|
|
7a31729ebb | ||
|
|
3a8faf8170 | ||
|
|
532581bb6e | ||
|
|
c228b229d2 | ||
|
|
10adbf472c | ||
|
|
a6e2f0f8f8 | ||
|
|
f1d93853ec | ||
|
|
bb7243c5db | ||
|
|
3ea816b2e6 | ||
|
|
b268c4e0cd | ||
|
|
8b8f336878 | ||
|
|
8517248aee | ||
|
|
ae0cd8a32f | ||
|
|
51c82cdfb3 | ||
|
|
8e087329b3 | ||
|
|
ee2885d055 | ||
|
|
901307e471 | ||
|
|
4ff5be706a | ||
|
|
f8a3fedbb2 | ||
|
|
0bf5831b4e | ||
|
|
dd0b8c6b0f | ||
|
|
8f028d9dd4 | ||
|
|
2c68f22646 | ||
|
|
02d566bb32 | ||
|
|
2b12045017 | ||
|
|
0cdf086d56 | ||
|
|
d4fa9a84e3 | ||
|
|
c84fc84b9e | ||
|
|
ad8cdde513 | ||
|
|
db19e7dd9b | ||
|
|
33b36e5108 | ||
|
|
7209441eb6 | ||
|
|
7a1ed67847 | ||
|
|
eaf9f4cd39 | ||
|
|
f0d85520c0 | ||
|
|
0e2862baa5 | ||
|
|
5ac058c489 | ||
|
|
ac38d2f28e | ||
|
|
591abaae6e | ||
|
|
b76566126c | ||
|
|
687583536a | ||
|
|
d136ec3197 | ||
|
|
37db43f5a7 | ||
|
|
a966900752 | ||
|
|
3b1fc3a559 | ||
|
|
849d9af8c4 | ||
|
|
8d62261983 | ||
|
|
6cfb626b8c | ||
|
|
48258be346 | ||
|
|
9d37b23050 | ||
|
|
d64ee2e5e4 | ||
|
|
ad351b28ea | ||
|
|
c633e95e01 | ||
|
|
15a55030a2 | ||
|
|
345cb83493 | ||
|
|
6e526f455b | ||
|
|
b05cf48f36 | ||
|
|
28249c9089 | ||
|
|
2b6081ab31 | ||
|
|
c935447266 | ||
|
|
ba1d6fa3ed | ||
|
|
1b3b68f8a7 | ||
|
|
ac23c31771 | ||
|
|
8b52053af2 | ||
|
|
a0f32bd6e3 | ||
|
|
4a3486cc3c | ||
|
|
cb49455a4e | ||
|
|
5e63d6ae59 | ||
|
|
e3ca6f2c24 | ||
|
|
96d33a60ba | ||
|
|
03389aece0 | ||
|
|
f86876ba51 | ||
|
|
44569d6df9 | ||
|
|
3663d1d4fe | ||
|
|
6225f0e5cb | ||
|
|
f0fd06a5f5 | ||
|
|
b181c98a38 | ||
|
|
1f51f1a08d | ||
|
|
586acaed68 | ||
|
|
528be5c058 | ||
|
|
76575bd9f1 | ||
|
|
54b98f41f4 | ||
|
|
ffac3a42c5 | ||
|
|
97b9e1097b | ||
|
|
a6de7fa84a | ||
|
|
3ec849bd94 | ||
|
|
208feb9849 | ||
|
|
a3ba464f40 | ||
|
|
cb970cded5 | ||
|
|
d5d8c54d98 | ||
|
|
2ec55f6de9 | ||
|
|
f7406bcafc | ||
|
|
925d3d7841 | ||
|
|
62c69490f2 | ||
|
|
3f957db56b | ||
|
|
495875792f | ||
|
|
c0416fc307 | ||
|
|
f7ba8e377d | ||
|
|
0d64443b26 | ||
|
|
7919a4001d | ||
|
|
fadbcdaa24 | ||
|
|
ec77a0539d | ||
|
|
b792803974 | ||
|
|
f0e37b130c | ||
|
|
03ece4b1fc | ||
|
|
0ec5b6cb9f | ||
|
|
e6d4a9641b | ||
|
|
5a442bf7ed | ||
|
|
a18932e9eb | ||
|
|
c36aa24c65 | ||
|
|
81ddd2c25b | ||
|
|
4af5b4f6ef | ||
|
|
dbd0f89a3d | ||
|
|
35b1e37940 | ||
|
|
6eaffe1993 | ||
|
|
46f0ce493b | ||
|
|
18b785d655 | ||
|
|
7b15bf45d9 | ||
|
|
0d4d32c6e4 | ||
|
|
760d459414 | ||
|
|
77301c2cf1 | ||
|
|
78ea63074e | ||
|
|
9c677fe174 | ||
|
|
c13b3fa197 | ||
|
|
167352f199 | ||
|
|
fc0b99e8a0 | ||
|
|
74bf885d47 | ||
|
|
400c307871 | ||
|
|
b1c086f424 | ||
|
|
d534c425d3 | ||
|
|
4ecf2433d0 | ||
|
|
6c086c3892 | ||
|
|
1e72c80566 | ||
|
|
8f4dc9907a | ||
|
|
2f7d0104a0 | ||
|
|
4f6809de84 | ||
|
|
216bc10142 | ||
|
|
5307e58813 | ||
|
|
143acde35e | ||
|
|
2525465a5a | ||
|
|
6d08a24a8f | ||
|
|
906180ad3f | ||
|
|
0ff0c33aa9 | ||
|
|
37e79a654b | ||
|
|
4e7cfdf5ea | ||
|
|
6f4e779a3e | ||
|
|
38d3e2df05 | ||
|
|
4e204f1ccd | ||
|
|
7e29999b40 | ||
|
|
01cf69392f | ||
|
|
7d7688582b | ||
|
|
e26065b116 | ||
|
|
485503c54d | ||
|
|
3c37716dd2 | ||
|
|
1a7f86a321 | ||
|
|
475f8c67b0 | ||
|
|
26314254be | ||
|
|
6522f6d964 | ||
|
|
ecaf439e66 | ||
|
|
90d03676ad | ||
|
|
f35d644608 | ||
|
|
2585a62697 | ||
|
|
6afe58a081 | ||
|
|
6f5bd1a13d | ||
|
|
85a9ab72af | ||
|
|
258ea43225 | ||
|
|
7a7b708029 | ||
|
|
0cf89861af | ||
|
|
eb74625835 | ||
|
|
cbaec4c655 | ||
|
|
04c21cb63d | ||
|
|
7d72002b6e | ||
|
|
279cc25da0 | ||
|
|
1152bb8440 | ||
|
|
88befb8136 | ||
|
|
42c6bc0337 | ||
|
|
6e753bb955 | ||
|
|
64df3e1fae | ||
|
|
5cdd1ad093 | ||
|
|
36e754b6bc | ||
|
|
6730dcf60d | ||
|
|
fb54809dc9 | ||
|
|
d43c622fdb | ||
|
|
7253d7a1d7 | ||
|
|
a6daa50417 | ||
|
|
b11019ce20 | ||
|
|
dda47f7b7d | ||
|
|
4da8ba7ecc | ||
|
|
2ff0b27747 | ||
|
|
c3f279fb0c | ||
|
|
06bcf1edca | ||
|
|
fc1f75cfac | ||
|
|
1cf12ab707 | ||
|
|
288ccc1049 | ||
|
|
f13c139f63 | ||
|
|
e72ad0586e | ||
|
|
c2044fe8b5 | ||
|
|
a7b3690a7c | ||
|
|
68afc348db | ||
|
|
5404124a78 | ||
|
|
d592871c0d | ||
|
|
6019e550fd | ||
|
|
765a49fb07 | ||
|
|
fe2fd93c20 | ||
|
|
19ba336e32 | ||
|
|
a50148fe85 | ||
|
|
c96156503f | ||
|
|
ed2ba2a5c5 | ||
|
|
f87fe3e544 | ||
|
|
43e73313e6 | ||
|
|
888aa1d08b | ||
|
|
028834da8b | ||
|
|
8f3b989b00 | ||
|
|
fe8761427d | ||
|
|
27a09de008 | ||
|
|
20ba8cc24e | ||
|
|
b8b52e7fc0 | ||
|
|
05a8c3be5f | ||
|
|
2f9bedbeeb | ||
|
|
01be6fc275 | ||
|
|
c20a4bb220 | ||
|
|
ed21b3cb65 | ||
|
|
f2a44c976d | ||
|
|
ca5189d8ad | ||
|
|
03f51c36ac | ||
|
|
607202b4e9 | ||
|
|
4db4f4fb2d | ||
|
|
1d7df6819e | ||
|
|
e4b6993692 | ||
|
|
b15d7a3412 | ||
|
|
b172c6801c | ||
|
|
dc1f4dcc38 | ||
|
|
a82e611358 | ||
|
|
c64951fd6f | ||
|
|
a35701fabf | ||
|
|
f54c1f77b4 | ||
|
|
377534512a | ||
|
|
09032349d0 | ||
|
|
4dd39aeed8 | ||
|
|
a1477e2ad3 | ||
|
|
f34cb4bf63 |
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: AllenFang
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is. In addition, please search issues before you open a report to make sure there's no any duplicated report
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**codesandbox**
|
||||||
|
Please give a simple and minimal example on https://codesandbox.io so that we can reproduce it easily and handle it effectively
|
||||||
23
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
23
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: AllenFang
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is this feature requested before?**
|
||||||
|
Please search issues to make sure to create feature which is never report yet.
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
17
.github/ISSUE_TEMPLATE/i-have-a-question.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/i-have-a-question.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: I have a question
|
||||||
|
about: I have a question
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: AllenFang
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Question**
|
||||||
|
A clear and concise description of you question. In addition, please search issues before you open a question to make sure there's no any duplicated questions.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**codesandbox**
|
||||||
|
Please give a simple and minimal example on https://codesandbox.io so that we can reproduce it easily.
|
||||||
@@ -11,6 +11,8 @@ branches:
|
|||||||
only:
|
only:
|
||||||
- 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
|
||||||
|
|||||||
44
README.md
44
README.md
@@ -1,42 +1,52 @@
|
|||||||
# react-bootstrap-table2
|
# react-bootstrap-table2
|
||||||
|
|
||||||
[](https://travis-ci.org/react-bootstrap-table/react-bootstrap-table2)
|
[](https://travis-ci.org/react-bootstrap-table/react-bootstrap-table2)
|
||||||
Rebuilt [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-table)
|
Rebuild of [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-table)
|
||||||
|
|
||||||
> `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
|
> Note that `react-bootstrap-table2`'s npm module name is [**`react-bootstrap-table-next`**](https://www.npmjs.com/package/react-bootstrap-table-next) due to the name being already taken.
|
||||||
|
|
||||||
`react-bootstrap-table2` separate some functionalities from core modules to other modules like following:
|
`react-bootstrap-table2` separates some functionalities from its core modules to other modules as listed in the following:
|
||||||
|
|
||||||
* [`react-bootstrap-table-next`](https://www.npmjs.com/package/react-bootstrap-table-next)
|
- [`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-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-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-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator)
|
||||||
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
- [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
||||||
|
- [`react-bootstrap-table2-toolkit`](https://www.npmjs.com/package/react-bootstrap-table2-toolkit)
|
||||||
|
|
||||||
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).
|
Not only does this reduce the bundle size of your apps but also helps us have a cleaner design to avoid handling too much logic in the kernel module(SRP).
|
||||||
|
|
||||||
## Migration
|
## 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).
|
|
||||||
|
If you are coming from the legacy [`react-bootstrap-table`](https://github.com/AllenFang/react-bootstrap-table/), please check out the [migration guide](./docs/migration.md).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
See [getting started](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/getting-started.html).
|
See [getting started](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/getting-started.html).
|
||||||
|
|
||||||
## Online Demo
|
## Online Demo
|
||||||
|
|
||||||
See `react-bootstrap-table2` [storybook](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html).
|
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
|
## Development
|
||||||
Please check [development guide](./docs/development.md).
|
|
||||||
|
|
||||||
## How should I run storybook example in my local?
|
Please check the [development guide](./docs/development.md).
|
||||||
|
|
||||||
|
## Running storybook example on your local machine
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
# Clone the repo
|
||||||
$ git clone https://github.com/react-bootstrap-table/react-bootstrap-table2.git
|
$ git clone https://github.com/react-bootstrap-table/react-bootstrap-table2.git
|
||||||
|
|
||||||
|
# change dir to the cloned repo
|
||||||
$ cd react-bootstrap-table2
|
$ cd react-bootstrap-table2
|
||||||
|
|
||||||
|
# Install all dependencies with yarn
|
||||||
$ yarn install
|
$ yarn install
|
||||||
|
|
||||||
|
# Start the stroybook server, then go to localhost:6006
|
||||||
$ yarn storybook
|
$ 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)**
|
**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)**
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#### Optional
|
#### Optional
|
||||||
* [remote](#remote)
|
* [remote](#remote)
|
||||||
|
* [bootstrap4](#bootstrap4)
|
||||||
* [loading](#loading)
|
* [loading](#loading)
|
||||||
* [caption](#caption)
|
* [caption](#caption)
|
||||||
* [striped](#striped)
|
* [striped](#striped)
|
||||||
@@ -16,17 +17,24 @@
|
|||||||
* [hover](#hover)
|
* [hover](#hover)
|
||||||
* [condensed](#condensed)
|
* [condensed](#condensed)
|
||||||
* [id](#id)
|
* [id](#id)
|
||||||
|
* [tabIndexCell](#tabIndexCell)
|
||||||
* [classes](#classes)
|
* [classes](#classes)
|
||||||
|
* [wrapperClasses](#wrapperClasses)
|
||||||
|
* [headerClasses](#headerClasses)
|
||||||
* [cellEdit](#cellEdit)
|
* [cellEdit](#cellEdit)
|
||||||
* [selectRow](#selectRow)
|
* [selectRow](#selectRow)
|
||||||
|
* [expandRow](#expandRow)
|
||||||
* [rowStyle](#rowStyle)
|
* [rowStyle](#rowStyle)
|
||||||
* [rowClasses](#rowClasses)
|
* [rowClasses](#rowClasses)
|
||||||
* [rowEvents](#rowEvents)
|
* [rowEvents](#rowEvents)
|
||||||
|
* [hiddenRows](#hiddenRows)
|
||||||
* [defaultSorted](#defaultSorted)
|
* [defaultSorted](#defaultSorted)
|
||||||
* [defaultSortDirection](#defaultSortDirection)
|
* [defaultSortDirection](#defaultSortDirection)
|
||||||
* [pagination](#pagination)
|
* [pagination](#pagination)
|
||||||
* [filter](#filter)
|
* [filter](#filter)
|
||||||
|
* [filterPosition](filterPosition)
|
||||||
* [onTableChange](#onTableChange)
|
* [onTableChange](#onTableChange)
|
||||||
|
* [onDataSizeChange](#onDataSizeChange)
|
||||||
|
|
||||||
### <a name='keyField'>keyField(**required**) - [String]</a>
|
### <a name='keyField'>keyField(**required**) - [String]</a>
|
||||||
Tells `react-bootstrap-table2` which column is unique.
|
Tells `react-bootstrap-table2` which column is unique.
|
||||||
@@ -64,6 +72,9 @@ remote={ { pagination: true, filter: false, sort: false } }
|
|||||||
|
|
||||||
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.
|
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='bootstrap4'>bootstrap4 - [Bool]</a>
|
||||||
|
`true` to indicate your bootstrap version is 4. Default version is 3.
|
||||||
|
|
||||||
### <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-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.
|
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.
|
||||||
@@ -88,7 +99,14 @@ import overlayFactory from 'react-bootstrap-table2-overlay';
|
|||||||
Actually, `react-bootstrap-table-overlay` is depends on [`react-loading-overlay`](https://github.com/derrickpelletier/react-loading-overlay) and `overlayFactory` just a factory function and you can pass any props which available for `react-loading-overlay`:
|
Actually, `react-bootstrap-table-overlay` is depends on [`react-loading-overlay`](https://github.com/derrickpelletier/react-loading-overlay) and `overlayFactory` just a factory function and you can pass any props which available for `react-loading-overlay`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
overlay={ overlayFactory({ spinner: true, background: 'rgba(192,192,192,0.3)' }) }
|
overlay={
|
||||||
|
overlayFactory({
|
||||||
|
spinner: true,
|
||||||
|
styles: {
|
||||||
|
overlay: (base) => ({...base, background: 'rgba(255, 0, 0, 0.5)'})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### <a name='caption'>caption - [String | Node]</a>
|
### <a name='caption'>caption - [String | Node]</a>
|
||||||
@@ -105,14 +123,28 @@ Same as bootstrap `.table-condensed` class for making a table more compact by cu
|
|||||||
|
|
||||||
### <a name='id'>id - [String]</a>
|
### <a name='id'>id - [String]</a>
|
||||||
Customize id on `table` element.
|
Customize id on `table` element.
|
||||||
|
|
||||||
|
### <a name='tabIndexCell'>tabIndexCell - [Bool]</a>
|
||||||
|
Enable the `tabIndex` attribute on `<td>` element.
|
||||||
|
|
||||||
### <a name='classes'>classes - [String]</a>
|
### <a name='classes'>classes - [String]</a>
|
||||||
Customize class on `table` element.
|
Customize class on `table` element.
|
||||||
|
|
||||||
|
### <a name='wrapperClasses'>wrapperClasses - [String]</a>
|
||||||
|
Customize class on the outer element which wrap up the `table` element.
|
||||||
|
|
||||||
|
### <a name='headerClasses'>headerClasses - [String]</a>
|
||||||
|
Customize class on the header row(`tr`).
|
||||||
|
|
||||||
### <a name='cellEdit'>cellEdit - [Object]</a>
|
### <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.
|
||||||
|
|
||||||
### <a name='selectRow'>selectRow - [Object]</a>
|
### <a name='selectRow'>selectRow - [Object]</a>
|
||||||
Makes table rows selectable, please see [selectRow definition](./row-selection.md) for more detail.
|
Makes table rows selectable, please see [selectRow definition](./row-selection.md) for more detail.
|
||||||
|
|
||||||
|
### <a name='expandRow'>expandRow - [Object]</a>
|
||||||
|
Makes table rows expandable, please see [expandRow definition](./row-expand.md) for more detail.
|
||||||
|
|
||||||
### <a name='rowStyle'>rowStyle = [Object | Function]</a>
|
### <a name='rowStyle'>rowStyle = [Object | Function]</a>
|
||||||
Custom the style of table rows:
|
Custom the style of table rows:
|
||||||
|
|
||||||
@@ -159,6 +191,14 @@ const rowEvents = {
|
|||||||
<BootstrapTable data={ data } columns={ columns } rowEvents={ rowEvents } />
|
<BootstrapTable data={ data } columns={ columns } rowEvents={ rowEvents } />
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name='hiddenRows'>hiddenRows - [Array]</a>
|
||||||
|
Hide rows, this props accept an array of row keys:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const hiddenRows = [1, 4];
|
||||||
|
<BootstrapTable data={ data } columns={ columns } hiddenRows={ hiddenRows } />
|
||||||
|
```
|
||||||
|
|
||||||
### <a name='defaultSorted'>defaultSorted - [Array]</a>
|
### <a name='defaultSorted'>defaultSorted - [Array]</a>
|
||||||
`defaultSorted` accept an object array which allow you to define the default sort columns when first render.
|
`defaultSorted` accept an object array which allow you to define the default sort columns when first render.
|
||||||
|
|
||||||
@@ -169,6 +209,8 @@ const defaultSorted = [{
|
|||||||
}];
|
}];
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note**: Only the first column is sorted currently, see #1083.
|
||||||
|
|
||||||
### <a name='defaultSortDirection'>defaultSortDirection - [String]</a>
|
### <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`.
|
Default sort direction when user click on header column at first time, available value is `asc` and `desc`. Default is `desc`.
|
||||||
|
|
||||||
@@ -198,6 +240,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
|
||||||
}, {
|
}, {
|
||||||
@@ -219,6 +262,7 @@ paginator({
|
|||||||
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
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -284,4 +328,23 @@ Following is a shape of `newState`
|
|||||||
newValue
|
newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name='filterPosition'>filterPosition - [String]</a>
|
||||||
|
Available value is `inline`, `top` and `bottom`, default is `inline`. This prop decide where `react-bootstrap-table` render column filter.
|
||||||
|
|
||||||
|
### <a name='onDataSizeChange'>onDataSizeChange - [Function]</a>
|
||||||
|
This callback function will be called only when data size change by search/filter etc. This function have one argument which is an object contains below props:
|
||||||
|
|
||||||
|
* `dataSize`: The new data size
|
||||||
|
|
||||||
|
```js
|
||||||
|
handleDataChange = ({ dataSize }) => {
|
||||||
|
this.setState({ rowCount: dataSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
onDataSizeChange={ handleDataChange }
|
||||||
|
....
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ $ npm install react-bootstrap-table2-editor --save
|
|||||||
* [blurToSave](#blurToSave)
|
* [blurToSave](#blurToSave)
|
||||||
* [nonEditableRows](#nonEditableRows)
|
* [nonEditableRows](#nonEditableRows)
|
||||||
* [timeToCloseMessage](#timeToCloseMessage)
|
* [timeToCloseMessage](#timeToCloseMessage)
|
||||||
|
* [autoSelectText](#autoSelectText)
|
||||||
* [beforeSaveCell](#beforeSaveCell)
|
* [beforeSaveCell](#beforeSaveCell)
|
||||||
* [afterSaveCell](#afterSaveCell)
|
* [afterSaveCell](#afterSaveCell)
|
||||||
* [errorMessage](#errorMessage)
|
* [errorMessage](#errorMessage)
|
||||||
@@ -43,6 +44,11 @@ Default is `false`, enable it will be able to save the cell automatically when b
|
|||||||
### <a name='nonEditableRows'>cellEdit.nonEditableRows - [Function]</a>
|
### <a name='nonEditableRows'>cellEdit.nonEditableRows - [Function]</a>
|
||||||
`cellEdit.nonEditableRows` accept a callback function and expect return an array which used to restrict all the columns of some rows as non-editable. So the each item in return array should be rowkey(`keyField`)
|
`cellEdit.nonEditableRows` accept a callback function and expect return an array which used to restrict all the columns of some rows as non-editable. So the each item in return array should be rowkey(`keyField`)
|
||||||
|
|
||||||
|
### <a name='autoSelectText'>cellEdit.autoSelectText - [Bool]</a>
|
||||||
|
Default is false, when enable it, `react-bootstrap-table2` will help you to select the text in the text input automatically when editing.
|
||||||
|
|
||||||
|
> NOTE: This props only work for `text` and `textarea`.
|
||||||
|
|
||||||
### <a name='timeToCloseMessage'>cellEdit.timeToCloseMessage - [Function]</a>
|
### <a name='timeToCloseMessage'>cellEdit.timeToCloseMessage - [Function]</a>
|
||||||
If a [`column.validator`](./columns.md#validator) defined and the new value is invalid, `react-bootstrap-table2` will popup a alert at the bottom of editor. `cellEdit.timeToCloseMessage` is a chance to let you decide how long the alert should be stay. Default is 3000 millisecond.
|
If a [`column.validator`](./columns.md#validator) defined and the new value is invalid, `react-bootstrap-table2` will popup a alert at the bottom of editor. `cellEdit.timeToCloseMessage` is a chance to let you decide how long the alert should be stay. Default is 3000 millisecond.
|
||||||
|
|
||||||
@@ -56,6 +62,24 @@ const cellEdit = {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you want to perform a async `beforeSaveCell`, you can do it like that:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const cellEdit: {
|
||||||
|
// omit...
|
||||||
|
beforeSaveCell(oldValue, newValue, row, column, done) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (confirm('Do you want to accept this change?')) {
|
||||||
|
done(); // contine to save the changes
|
||||||
|
} else {
|
||||||
|
done(false); // reject the changes
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
return { async: true };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### <a name='afterSaveCell'>cellEdit.afterSaveCell - [Function]</a>
|
### <a name='afterSaveCell'>cellEdit.afterSaveCell - [Function]</a>
|
||||||
This callback function will be called after updating cell.
|
This callback function will be called after updating cell.
|
||||||
|
|
||||||
|
|||||||
385
docs/columns.md
385
docs/columns.md
@@ -7,11 +7,15 @@ Available properties in a column object:
|
|||||||
* [text (**required**)](#text)
|
* [text (**required**)](#text)
|
||||||
|
|
||||||
#### Optional
|
#### Optional
|
||||||
|
* [isDummyField](#isDummyField)
|
||||||
* [hidden](#hidden)
|
* [hidden](#hidden)
|
||||||
* [formatter](#formatter)
|
* [formatter](#formatter)
|
||||||
* [formatExtraData](#formatExtraData)
|
* [formatExtraData](#formatExtraData)
|
||||||
|
* [type](#type)
|
||||||
* [sort](#sort)
|
* [sort](#sort)
|
||||||
|
* [sortValue](#sortValue)
|
||||||
* [sortFunc](#sortFunc)
|
* [sortFunc](#sortFunc)
|
||||||
|
* [sortCaret](#sortCaret)
|
||||||
* [onSort](#onSort)
|
* [onSort](#onSort)
|
||||||
* [classes](#classes)
|
* [classes](#classes)
|
||||||
* [style](#style)
|
* [style](#style)
|
||||||
@@ -28,14 +32,29 @@ Available properties in a column object:
|
|||||||
* [headerAttrs](#headerAttrs)
|
* [headerAttrs](#headerAttrs)
|
||||||
* [headerSortingClasses](#headerSortingClasses)
|
* [headerSortingClasses](#headerSortingClasses)
|
||||||
* [headerSortingStyle](#headerSortingStyle)
|
* [headerSortingStyle](#headerSortingStyle)
|
||||||
|
* [footer](#footer)
|
||||||
|
* [footerFormatter](#footerFormatter)
|
||||||
|
* [footerClasses](#footerClasses)
|
||||||
|
* [footerStyle](#footerStyle)
|
||||||
|
* [footerTitle](#footerTitle)
|
||||||
|
* [footerEvents](#footerEvents)
|
||||||
|
* [footerAlign](#footerAlign)
|
||||||
|
* [footerAttrs](#footerAttrs)
|
||||||
* [editable](#editable)
|
* [editable](#editable)
|
||||||
* [validator](#validator)
|
* [validator](#validator)
|
||||||
* [editCellStyle](#editCellStyle)
|
* [editCellStyle](#editCellStyle)
|
||||||
* [editCellClasses](#editCellClasses)
|
* [editCellClasses](#editCellClasses)
|
||||||
* [editorStyle](#editorStyle)
|
* [editorStyle](#editorStyle)
|
||||||
* [editorClasses](#editorClasses)
|
* [editorClasses](#editorClasses)
|
||||||
|
* [editor](#editor)
|
||||||
|
* [editorRenderer](#editorRenderer)
|
||||||
* [filter](#filter)
|
* [filter](#filter)
|
||||||
* [filterValue](#filterValue)
|
* [filterValue](#filterValue)
|
||||||
|
* [searchable](#searchable)
|
||||||
|
* [csvType](#csvType)
|
||||||
|
* [csvFormatter](#csvFormatter)
|
||||||
|
* [csvText](#csvText)
|
||||||
|
* [csvExport](#csvExport)
|
||||||
|
|
||||||
Following is a most simplest and basic usage:
|
Following is a most simplest and basic usage:
|
||||||
|
|
||||||
@@ -78,6 +97,11 @@ dataField: 'address.city'
|
|||||||
## <a name='text'>column.text (**required**) - [String]</a>
|
## <a name='text'>column.text (**required**) - [String]</a>
|
||||||
`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)
|
`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='isDummyField'>column.isDummyField - [Bool]</a>
|
||||||
|
Sometime, you just want to have a column which is not perform any data but just some action components. In this situation, we suggest you to use `isDummyField`. If column is dummy, the [`column.dataField`](#dataField) can be any string value, cause of it's meaningless.
|
||||||
|
|
||||||
|
There's only one different for dummy column than normal column, which is dummy column will compare the whole row value instead of cell value when call `shouldComponentUpdate`.
|
||||||
|
|
||||||
## <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,6 +113,10 @@ dataField: 'address.city'
|
|||||||
* `rowIndex`
|
* `rowIndex`
|
||||||
* [`formatExtraData`](#formatExtraData)
|
* [`formatExtraData`](#formatExtraData)
|
||||||
|
|
||||||
|
> Attention:
|
||||||
|
> Don't use any state data or any external data in formatter function, please pass them via [`formatExtraData`](#formatExtraData).
|
||||||
|
> In addition, please make formatter function as pure function as possible as you can.
|
||||||
|
|
||||||
## <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.
|
||||||
|
|
||||||
@@ -107,19 +135,57 @@ The third argument: `components` have following specified properties:
|
|||||||
## <a name='formatExtraData'>column.formatExtraData - [Any]</a>
|
## <a name='formatExtraData'>column.formatExtraData - [Any]</a>
|
||||||
It's only used for [`column.formatter`](#formatter), you can define any value for it and will be passed as fourth argument for [`column.formatter`](#formatter) callback function.
|
It's only used for [`column.formatter`](#formatter), you can define any value for it and will be passed as fourth argument for [`column.formatter`](#formatter) callback function.
|
||||||
|
|
||||||
|
## <a name='type'>column.type - [String]</a>
|
||||||
|
Specify the data type on column. Available value so far is `string`, `number`, `bool` and `date`. Default is `string`.
|
||||||
|
`column.type` can be used when you enable the cell editing and want to save your cell data with correct data type.
|
||||||
|
|
||||||
## <a name='sort'>column.sort - [Bool]</a>
|
## <a name='sort'>column.sort - [Bool]</a>
|
||||||
Enable the column sort via a `true` value given.
|
Enable the column sort via a `true` value given.
|
||||||
|
|
||||||
|
## <a name='sortValue'>column.sortValue - [Function]</a>
|
||||||
|
`column.sortValue` only work when `column.sort` enabled. This prop allow you to replace the value when table sorting.
|
||||||
|
|
||||||
|
For example, consider following data:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const types = ['Cloud Service', 'Message Service', 'Add Service', 'Edit Service', 'Money'];
|
||||||
|
const data = [{id: 1, type: 2}, {id: 2, type: 1}, {id: 3, type:0}];
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Job ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'type',
|
||||||
|
text: 'Job Type'
|
||||||
|
sort: true,
|
||||||
|
formatter: (cell, row) => types[cell]
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
In above case, when user try to sort Job Type column which will sort the original value: 0, 1, 2 but we display the type name via [`column.formatter`](#formatter), which will lead confuse because we are sorting by type value instead of type name. So `sortValue` is a way for you to decide what kind of value should be adopted when sorting on a specify column:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Job ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'type',
|
||||||
|
text: 'Job Type'
|
||||||
|
sort: true,
|
||||||
|
formatter: (cell, row) => types[cell],
|
||||||
|
sortValue: (cell, row) => types[cell] // we use type name to sort.
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
## <a name='sortFunc'>column.sortFunc - [Function]</a>
|
## <a name='sortFunc'>column.sortFunc - [Function]</a>
|
||||||
`column.sortFunc` only work when `column.sort` is enable. `sortFunc` allow you to define your sorting algorithm. This callback function accept four arguments:
|
`column.sortFunc` only work when `column.sort` enabled. `sortFunc` allow you to define your sorting algorithm. This callback function accept six arguments:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// omit...
|
// omit...
|
||||||
sort: true,
|
sort: true,
|
||||||
sortFunc: (a, b, order, dataField) => {
|
sortFunc: (valueA, valueB, order, dataField, rowA, rowB) => {
|
||||||
if (order === 'asc') return a - b;
|
if (order === 'asc') return valueA - valueB;
|
||||||
else return b - a;
|
else return valueB - valueA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -138,6 +204,20 @@ Enable the column sort via a `true` value given.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## <a name='sortCaret'>column.sortCaret - [Function]</a>
|
||||||
|
Use`column.sortCaret` to customize the sort caret. This callback function accept two arguments: `order` and `column`
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
sort: true,
|
||||||
|
sortCaret: (order, column) => {
|
||||||
|
return //...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
> The possible value of `order` argument is **`asc`**, **`desc`** and **`undefined`**.
|
||||||
|
|
||||||
## <a name='classes'>column.classes - [String | Function]</a>
|
## <a name='classes'>column.classes - [String | Function]</a>
|
||||||
It's available to have custom class on table column:
|
It's available to have custom class on table column:
|
||||||
|
|
||||||
@@ -271,7 +351,7 @@ A new `Object` will be the result of element headerStyle.
|
|||||||
A new `String` will be the result of element title.
|
A new `String` will be the result of element title.
|
||||||
|
|
||||||
## <a name='headerTitle'>column.headerTitle - [Bool | Function]</a>
|
## <a name='headerTitle'>column.headerTitle - [Bool | Function]</a>
|
||||||
`headerTitle` is only for the title on header column, default is disable. The usage almost same as [`column.title`](#title),
|
Configure the title on header column, default is disable. The usage almost same as [`column.title`](#title),
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
@@ -348,17 +428,27 @@ A new `String` will be the result of element headerAlign.
|
|||||||
|
|
||||||
|
|
||||||
## <a name='events'>column.events - [Object]</a>
|
## <a name='events'>column.events - [Object]</a>
|
||||||
You can assign any [HTML Event](https://www.w3schools.com/tags/ref_eventattributes.asp) on table column via event property:
|
You can assign any [HTML Event](https://www.w3schools.com/tags/ref_eventattributes.asp) on table column via `events` property.
|
||||||
|
|
||||||
|
`react-bootstrap-table2` currently only support following events which will receive some specific information:
|
||||||
|
|
||||||
|
* onClick
|
||||||
|
* onDoubleClick
|
||||||
|
* onMouseEnter
|
||||||
|
* onMouseLeave
|
||||||
|
* onContextMenu
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
// omit...
|
// omit...
|
||||||
events: {
|
events: {
|
||||||
onClick: e => { ... }
|
onClick: (e, column, columnIndex, row, rowIndex) => { ... },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If the events is not listed above, the callback function will only pass the `event` object.
|
||||||
|
|
||||||
## <a name='headerEvents'>column.headerEvents - [Object]</a>
|
## <a name='headerEvents'>column.headerEvents - [Object]</a>
|
||||||
`headerEvents` same as [`column.events`](#events) but this is for header column.
|
`headerEvents` same as [`column.events`](#events) but this is for header column.
|
||||||
|
|
||||||
@@ -366,7 +456,7 @@ You can assign any [HTML Event](https://www.w3schools.com/tags/ref_eventattribut
|
|||||||
{
|
{
|
||||||
// omit...
|
// omit...
|
||||||
headerEvents: {
|
headerEvents: {
|
||||||
onClick: e => { ... }
|
onClick: (e, column, columnIndex) => { ... }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -477,6 +567,162 @@ const sortingHeaderStyle = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name='footer'>footer - [String | Function]</a>
|
||||||
|
Give a string to render the string value on the footer column.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
footerAlign: 'center',
|
||||||
|
footer: 'Footer 1'
|
||||||
|
}, .....];
|
||||||
|
```
|
||||||
|
|
||||||
|
This prop also accept a function:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
footer: column => column.reduce((acc, item) => acc + item, 0)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## <a name='footerFormatter'>column.footerFormatter - [Function]</a>
|
||||||
|
`footerFormatter` allow you to customize the table footer column and only accept a callback function which take two arguments and a JSX/String are expected for return.
|
||||||
|
|
||||||
|
* `column`
|
||||||
|
* `columnIndex`
|
||||||
|
|
||||||
|
## <a name='footerClasses'>column.footerClasses - [String | Function]</a>
|
||||||
|
It's similar to [`column.classes`](#classes), `footerClasses` is available to have customized class on table footer column:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerClasses: 'id-custom-cell'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Furthermore, it also accept a callback function which takes 2 arguments and a `String` is expect to return:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
footerClasses: function callback(column, colIndex) { ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
* `column`: The value of current column.
|
||||||
|
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||||
|
|
||||||
|
## <a name='footerStyle'>column.footerStyle - [Object | Function]</a>
|
||||||
|
Customized the inline-style on table footer column:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerStyle: { backgroundColor: 'green' }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Moreover, it also accept a callback function which takes **2** arguments and an `Object` is expect to return:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
footerStyle: function callback(column, colIndex) { ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
* `column`: The value of current column.
|
||||||
|
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||||
|
|
||||||
|
## <a name='footerTitle'>column.footerTitle - [Bool | Function]</a>
|
||||||
|
Configure the title on footer column, default is disable. The usage is almost same as [`column.title`](#title),
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerTitle: true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It's also available to custom via a callback function:
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
footerTitle: function callback(column, colIndex) { ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
* `column`: The value of current column.
|
||||||
|
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||||
|
|
||||||
|
## <a name='footerEvents'>column.footerEvents - [Object]</a>
|
||||||
|
`footerEvents` same as [`column.events`](#events) but it is for footer column:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerEvents: {
|
||||||
|
onClick: (e, column, columnIndex) => { ... }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## <a name='footerAlign'>column.footerAlign - [String | Function]</a>
|
||||||
|
It's almost same as [`column.align`](#align), but it's for the [CSS text-align](https://www.w3schools.com/cssref/pr_text_text-align.asp) on footer column.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerAlign: 'center'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Also, you can custom the align by a callback function:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerAlign: (column, colIndex) => {
|
||||||
|
// column is an object and perform itself
|
||||||
|
// return custom title here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**Parameters**
|
||||||
|
* `column`: The value of current column.
|
||||||
|
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||||
|
|
||||||
|
## <a name='footerAttrs'>column.footerAttrs - [Object | Function]</a>
|
||||||
|
`footerAttrs` is similar to [`column.attrs`](#attrs) but it works for footer column.
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerAttrs: {
|
||||||
|
title: 'bar',
|
||||||
|
'data-test': 'foo'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, customize the header attributes by a **2** arguments callback function:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
footerAttrs: (column, colIndex) => ({
|
||||||
|
// return customized HTML attribute here
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters**
|
||||||
|
* `column`: The value of current column.
|
||||||
|
* `colIndex`: The index of the current `column` being processed in `BootstrapTable`.
|
||||||
|
|
||||||
## <a name='editable'>column.editable - [Bool | Function]</a>
|
## <a name='editable'>column.editable - [Bool | Function]</a>
|
||||||
`column.editable` default is true, means every column is editable if you configure [`cellEdit`](./README.md#cellEdit). But you can disable some columns editable via setting `false`.
|
`column.editable` default is true, means every column is editable if you configure [`cellEdit`](./README.md#cellEdit). But you can disable some columns editable via setting `false`.
|
||||||
|
|
||||||
@@ -512,6 +758,28 @@ The return value can be a bool or an object. If your validation is pass, return
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you want to perform a asycn validation, you can do it like this:
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
// omit...
|
||||||
|
validator: (newValue, row, column, done) => {
|
||||||
|
settimeout(() => {
|
||||||
|
// async validation ok
|
||||||
|
return done();
|
||||||
|
|
||||||
|
// async validation not ok
|
||||||
|
return done({
|
||||||
|
valid: false,
|
||||||
|
message: 'SOME_REASON_HERE'
|
||||||
|
});
|
||||||
|
|
||||||
|
}, 2000);
|
||||||
|
return { async: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## <a name='editCellStyle'>column.editCellStyle - [Object | Function]</a>
|
## <a name='editCellStyle'>column.editCellStyle - [Object | Function]</a>
|
||||||
You can use `column.editCellStyle` to custom the style of `<td>` when cell editing. It like most of customizable functionality, it also accept a callback function with following params:
|
You can use `column.editCellStyle` to custom the style of `<td>` when cell editing. It like most of customizable functionality, it also accept a callback function with following params:
|
||||||
|
|
||||||
@@ -560,11 +828,94 @@ This is almost same as [`column.editCellStyle`](#editCellStyle), but `column.edi
|
|||||||
## <a name='editorClasses'>column.editorClasses - [Object | Function]</a>
|
## <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`).
|
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`)
|
* 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`:
|
||||||
|
|
||||||
@@ -600,4 +951,20 @@ A final `String` value you want to be filtered.
|
|||||||
filter: textFilter(),
|
filter: textFilter(),
|
||||||
filterValue: (cell, row) => owners[cell]
|
filterValue: (cell, row) => owners[cell]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## <a name='searchable'>column.searchable - [Boolean]</a>
|
||||||
|
Default the column is searchable. Give `false` to disable search functionality on specified column.
|
||||||
|
|
||||||
|
## <a name='csvType'>column.csvType - [Object]</a>
|
||||||
|
Default is `String`. Currently, the available value is `String` and `Number`. If `Number` assigned, the cell value will not wrapped with double quote.
|
||||||
|
|
||||||
|
## <a name='csvFormatter'>column.csvFormatter - [Function]</a>
|
||||||
|
|
||||||
|
This is same as [`column.formatter`](#formatter). But `csvFormatter` only for CSV export and called when export CSV.
|
||||||
|
|
||||||
|
## <a name='csvText'>column.csvText - [String]</a>
|
||||||
|
Custom the CSV header cell, Default is [`column.text`](#text).
|
||||||
|
|
||||||
|
## <a name='csvExport'>column.csvExport - [Bool]</a>
|
||||||
|
Default is `true`, `false` will hide this column when export CSV.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
### Setup
|
### Setup
|
||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/react-bootstrap-table/react-bootstrap-table2.git
|
$ git clone https://github.com/react-bootstrap-table/react-bootstrap-table2.git
|
||||||
$ cd react-bootstrap-table
|
$ cd react-bootstrap-table2
|
||||||
$ npm install
|
$ npm install
|
||||||
$ lerna bootstrap # ./node_modules/.bin/lerna bootstrap
|
$ lerna bootstrap # ./node_modules/.bin/lerna bootstrap
|
||||||
```
|
```
|
||||||
@@ -25,4 +25,4 @@ $ npm run storybook
|
|||||||
$ npm test
|
$ npm test
|
||||||
$ npm run test:watch # for watch mode
|
$ npm run test:watch # for watch mode
|
||||||
$ npm run test:coverage # generate coverage report
|
$ npm run test:coverage # generate coverage report
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ Currently, **I still can't implement all the mainly features in legacy `react-bo
|
|||||||
* Pagination Addons
|
* Pagination Addons
|
||||||
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
||||||
* Overlay/Loading Addons
|
* Overlay/Loading Addons
|
||||||
|
* [`react-bootstrap-table2-toolkit`](https://www.npmjs.com/package/react-bootstrap-table2-toolkit)
|
||||||
|
* Table Toolkits, like search, csv, column toggle etc.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ Due to no `TableHeaderColumn` so that no `dataSort` here, please add [`sort`](ht
|
|||||||
Please see [Work with selection](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-row-select.html).
|
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).
|
Please see [available selectRow configurations](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/row-select-props.html).
|
||||||
|
|
||||||
No huge change for row selection, but can not custom the selection column currently. Coming soon!!!
|
No huge change for row selection.
|
||||||
|
|
||||||
## Column Filter
|
## Column Filter
|
||||||
|
|
||||||
@@ -82,14 +84,14 @@ Please see [available filter configuration](https://react-bootstrap-table.github
|
|||||||
- [x] Text Filter
|
- [x] Text Filter
|
||||||
- [x] Custom Text Filter
|
- [x] Custom Text Filter
|
||||||
- [x] Remote Filter
|
- [x] Remote Filter
|
||||||
- [ ] Custom Filter Component
|
- [x] Custom Filter Component
|
||||||
- [ ] Regex Filter
|
- [ ] Regex Filter
|
||||||
- [x] Select Filter
|
- [x] Select Filter
|
||||||
- [x] Custom Select Filter
|
- [x] Custom Select Filter
|
||||||
- [X] Number Filter
|
- [X] Number Filter
|
||||||
- [ ] Date Filter
|
- [X] Date Filter
|
||||||
- [ ] Array Filter
|
- [X] Array Filter
|
||||||
- [ ] Programmatically Filter
|
- [X] Programmatically Filter
|
||||||
|
|
||||||
Remember to install [`react-bootstrap-table2-filter`](https://www.npmjs.com/package/react-bootstrap-table2-filter) firstly.
|
Remember to install [`react-bootstrap-table2-filter`](https://www.npmjs.com/package/react-bootstrap-table2-filter) firstly.
|
||||||
|
|
||||||
@@ -111,8 +113,34 @@ Please see [available pagination configurations](https://react-bootstrap-table.g
|
|||||||
|
|
||||||
Remember to install [`react-bootstrap-table2-paginator`](https://www.npmjs.com/package/react-bootstrap-table2-paginator) firstly.
|
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.
|
## Table Search
|
||||||
|
The usage of search functionality is a little bit different from legacy search. The mainly different thing is developer have to render the search input field, we do believe it will be very flexible for all the developers who want to custom the search position or search field itself.
|
||||||
|
|
||||||
|
- [x] Custom search component and position
|
||||||
|
- [x] Custom search value
|
||||||
|
- [x] Clear search
|
||||||
|
- [ ] Multiple search
|
||||||
|
- [ ] Strict search
|
||||||
|
|
||||||
|
## Row Expand
|
||||||
|
- [x] Expand Row Events
|
||||||
|
- [x] Expand Row Indicator
|
||||||
|
- [x] Expand Row Management
|
||||||
|
- [x] Custom Expand Row Indicators
|
||||||
|
- [ ] Compatiable with Row Selection
|
||||||
|
- [ ] Expand Column position
|
||||||
|
- [ ] Expand Column Style/Class
|
||||||
|
|
||||||
|
## Export CSV
|
||||||
|
Export CSV functionality is like search, which is one of functionality in the `react-bootstrap-table2-toolkit`. All of the legacy functions we already implemented.
|
||||||
|
|
||||||
## Remote
|
## Remote
|
||||||
|
|
||||||
> It's totally different in `react-bootstrap-table2`. Please [see](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-remote.html).
|
> It's totally different in `react-bootstrap-table2`. Please [see](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/basic-remote.html).
|
||||||
|
|
||||||
|
|
||||||
|
## Row insert/Delete
|
||||||
|
Not support yet
|
||||||
|
|
||||||
|
## Keyboard Navigation
|
||||||
|
Not support yet
|
||||||
|
|||||||
212
docs/row-expand.md
Normal file
212
docs/row-expand.md
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
|
||||||
|
# Row expand
|
||||||
|
`react-bootstrap-table2` supports the row expand feature. By passing prop `expandRow` to enable this functionality.
|
||||||
|
|
||||||
|
> Default is click to expand/collapse a row. In addition, we don't support any way to change this mechanism!
|
||||||
|
|
||||||
|
## Required
|
||||||
|
* [renderer (**required**)](#renderer)
|
||||||
|
|
||||||
|
## Optional
|
||||||
|
* [expanded](#expanded)
|
||||||
|
* [nonExpandable](#nonExpandable)
|
||||||
|
* [onExpand](#onExpand)
|
||||||
|
* [onExpandAll](#onExpandAll)
|
||||||
|
* [showExpandColumn](#showExpandColumn)
|
||||||
|
* [onlyOneExpanding](#onlyOneExpanding)
|
||||||
|
* [expandByColumnOnly](#expandByColumnOnly)
|
||||||
|
* [expandColumnPosition](#expandColumnPosition)
|
||||||
|
* [expandColumnRenderer](#expandColumnRenderer)
|
||||||
|
* [expandHeaderColumnRenderer](#expandHeaderColumnRenderer)
|
||||||
|
* [className](#className)
|
||||||
|
* [parentClassName](#parentClassName)
|
||||||
|
|
||||||
|
### <a name="renderer">expandRow.renderer - [Function]</a>
|
||||||
|
|
||||||
|
Specify the content of expand row, `react-bootstrap-table2` will pass a row object as argument and expect return a react element.
|
||||||
|
|
||||||
|
#### values
|
||||||
|
* **row**
|
||||||
|
* **rowIndex**
|
||||||
|
|
||||||
|
#### examples
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row, rowIndex) => (
|
||||||
|
<div>
|
||||||
|
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
||||||
|
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||||
|
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField='id'
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
expandRow={ expandRow }
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='expanded'>expandRow.expanded - [Array]</a>
|
||||||
|
`expandRow.expanded` allow you have default row expandations on table.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
expanded: [1, 3] // should be a row keys array
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='nonExpandable'>expandRow.nonExpandable - [Array]</a>
|
||||||
|
This prop allow you to restrict some rows which can not be expanded by user. `expandRow.nonExpandable` accept an rowkeys array.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
nonExpandable: [1, 3 ,5]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='onExpand'>expandRow.onExpand - [Function]</a>
|
||||||
|
This callback function will be called when a row is expand/collapse and pass following four arguments:
|
||||||
|
`row`, `isExpand`, `rowIndex` and `e`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
onExpand: (row, isExpand, rowIndex, e) => {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='onExpandAll'>expandRow.onExpandAll - [Function]</a>
|
||||||
|
This callback function will be called when expand/collapse all. It only work when you configure [`expandRow.showExpandColumn`](#showExpandColumn) as `true`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
onExpandAll: (isExpandAll, results, e) => {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='expandColumnRenderer'>expandRow.expandColumnRenderer - [Function]</a>
|
||||||
|
Provide a callback function which allow you to custom the expand indicator. This callback only have one argument which is an object and contain these properties:
|
||||||
|
* `expanded`: If current row is expanded or not
|
||||||
|
* `rowKey`: Current row key
|
||||||
|
* `expandable`: If currnet row is expandable or not
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
expandColumnRenderer: ({ expanded, rowKey, expandable }) => (
|
||||||
|
// ....
|
||||||
|
)
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> By default, `react-bootstrap-table2` will help you to handle the click event, it's not necessary to handle again by developer.
|
||||||
|
|
||||||
|
### <a name='expandHeaderColumnRenderer'>expandRow.expandHeaderColumnRenderer - [Function]</a>
|
||||||
|
Provide a callback function which allow you to custom the expand indicator in the expand header column. This callback only have one argument which is an object and contain one property `isAnyExpands` which indicate if there's any rows are expanded:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
expandHeaderColumnRenderer: ({ isAnyExpands }) => (
|
||||||
|
// ....
|
||||||
|
)
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> By default, `react-bootstrap-table2` will help you to handle the click event, it's not necessary to handle again by developer.
|
||||||
|
|
||||||
|
### <a name='showExpandColumn'>expandRow.showExpandColumn - [Bool]</a>
|
||||||
|
Default is `false`, if you want to have a expand indicator, give this prop as `true`
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
showExpandColumn: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='onlyOneExpanding'>expandRow.onlyOneExpanding - [Bool]</a>
|
||||||
|
Default is `false`. Enable this will only allow one row get expand at the same time.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...
|
||||||
|
onlyOneExpanding: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='expandByColumnOnly'>expandRow.expandByColumnOnly - [Bool]</a>
|
||||||
|
Default is `false`. If you want to restrict user to expand/collapse row via clicking the expand column only, you can enable it.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...,
|
||||||
|
showExpandColumn: true,
|
||||||
|
expandByColumnOnly: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='expandColumnPosition'>expandRow.expandColumnPosition - [String]</a>
|
||||||
|
Default is `left`. You can give this as `right` for rendering expand column in the right side.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...,
|
||||||
|
showExpandColumn: true,
|
||||||
|
expandColumnPosition: 'right'
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='className'>expandRow.className - [String | Function]</a>
|
||||||
|
Apply the custom class name on the expanding row. For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...,
|
||||||
|
className: 'foo'
|
||||||
|
};
|
||||||
|
```
|
||||||
|
following usage is more flexible way for customing the class name:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...,
|
||||||
|
className: (isExpanded, row, rowIndex) => {
|
||||||
|
if (rowIndex > 2) return 'foo';
|
||||||
|
return 'bar';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='parentClassName'>expandRow.parentClassName - [String | Function]</a>
|
||||||
|
Apply the custom class name on parent row of expanded row. For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...,
|
||||||
|
parentClassName: 'foo'
|
||||||
|
};
|
||||||
|
```
|
||||||
|
Below case is more flexible way to custom the class name:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const expandRow = {
|
||||||
|
renderer: (row) => ...,
|
||||||
|
parentClassName: (isExpanded, row, rowIndex) => {
|
||||||
|
if (rowIndex > 2) return 'foo';
|
||||||
|
return 'bar';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
# 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 prepend a new selection column.
|
||||||
|
|
||||||
## Required
|
## Required
|
||||||
* [mode (**required**)](#mode)
|
* [mode (**required**)](#mode)
|
||||||
@@ -12,10 +12,17 @@
|
|||||||
* [bgColor](#bgColor)
|
* [bgColor](#bgColor)
|
||||||
* [nonSelectable)](#nonSelectable)
|
* [nonSelectable)](#nonSelectable)
|
||||||
* [clickToSelect)](#clickToSelect)
|
* [clickToSelect)](#clickToSelect)
|
||||||
|
* [clickToExpand)](#clickToExpand)
|
||||||
* [clickToEdit](#clickToEdit)
|
* [clickToEdit](#clickToEdit)
|
||||||
* [onSelect](#onSelect)
|
* [onSelect](#onSelect)
|
||||||
* [onSelectAll](#onSelectAll)
|
* [onSelectAll](#onSelectAll)
|
||||||
|
* [selectColumnPosition](#selectColumnPosition)
|
||||||
* [hideSelectColumn](#hideSelectColumn)
|
* [hideSelectColumn](#hideSelectColumn)
|
||||||
|
* [hideSelectAll](#hideSelectAll)
|
||||||
|
* [selectionRenderer](#selectionRenderer)
|
||||||
|
* [selectionHeaderRenderer](#selectionHeaderRenderer)
|
||||||
|
* [headerColumnStyle](#headerColumnStyle)
|
||||||
|
* [selectColumnStyle](#selectColumnStyle)
|
||||||
|
|
||||||
### <a name="mode">selectRow.mode - [String]</a>
|
### <a name="mode">selectRow.mode - [String]</a>
|
||||||
|
|
||||||
@@ -145,6 +152,16 @@ const selectRow = {
|
|||||||
> Note: When 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='clickToExpand'>selectRow.clickToExpand - [Bool]</a>
|
||||||
|
Default is false, enable it will let user able to expand and select row when user clicking on the row.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToExpand: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### <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
|
||||||
|
|
||||||
@@ -156,31 +173,156 @@ 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, rowIndex }) => (
|
||||||
|
// ....
|
||||||
|
)
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 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='headerColumnStyle'>selectRow.headerColumnStyle - [Object | Function]</a>
|
||||||
|
A way to custome the selection header cell. `headerColumnStyle` not only accept a simple style object but also a callback function for more flexible customization:
|
||||||
|
|
||||||
|
### Style Object
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
headerColumnStyle: { backgroundColor: 'blue' }
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Callback Function
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
headerColumnStyle: (status) => (
|
||||||
|
// status available value is checked, indeterminate and unchecked
|
||||||
|
return { backgroundColor: 'blue' };
|
||||||
|
)
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='selectColumnStyle'>selectRow.selectColumnStyle - [Object | Function]</a>
|
||||||
|
A way to custome the selection cell. `selectColumnStyle` not only accept a simple style object but also a callback function for more flexible customization:
|
||||||
|
|
||||||
|
### Style Object
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
selectColumnStyle: { backgroundColor: 'blue' }
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Callback Function
|
||||||
|
If a callback function present, you can get below information to custom the selection cell:
|
||||||
|
|
||||||
|
* `checked`: Whether current row is seleccted or not
|
||||||
|
* `disabled`: Whether current row is disabled or not
|
||||||
|
* `rowIndex`: Current row index
|
||||||
|
* `rowKey`: Current row key
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
selectColumnStyle: ({
|
||||||
|
checked,
|
||||||
|
disabled,
|
||||||
|
rowIndex,
|
||||||
|
rowKey
|
||||||
|
}) => (
|
||||||
|
// ....
|
||||||
|
return { backgroundColor: 'blue' };
|
||||||
|
)
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <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) => {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> If you want to reject current select action, just return `false`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
onSelect: (row, isSelect, rowIndex, e) => {
|
||||||
|
if (SOME_CONDITION) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### <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, rows, e) => {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> If you want to control the final selection result, just return a row key array:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
onSelectAll: (isSelect, rows, e) => {
|
||||||
|
if (isSelect && SOME_CONDITION) {
|
||||||
|
return [1, 3, 4]; // finally, key 1, 3, 4 will being selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### <a name='selectColumnPosition'>selectRow.selectColumnPosition - [String]</a>
|
||||||
|
Default is `left`. You can give this as `right` for rendering selection column in the right side.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
selectColumnPosition: 'right'
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### <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`
|
||||||
|
|
||||||
@@ -192,3 +334,13 @@ const selectRow = {
|
|||||||
bgColor: 'red'
|
bgColor: 'red'
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name='hideSelectAll'>selectRow.hideSelectAll - [Bool]</a>
|
||||||
|
Default is `false`, if you don't want to render the select all checkbox on the header of selection column, give this prop as `true`!
|
||||||
|
|
||||||
|
```js
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
hideSelectAll: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Adapter from 'enzyme-adapter-react-16';
|
import Adapter from 'enzyme-adapter-react-16.3';
|
||||||
import { configure } from 'enzyme';
|
import { configure } from 'enzyme';
|
||||||
|
|
||||||
const configureEnzyme = () => {
|
const configureEnzyme = () => {
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ const JS_PKGS = [
|
|||||||
'react-bootstrap-table2-editor',
|
'react-bootstrap-table2-editor',
|
||||||
'react-bootstrap-table2-filter',
|
'react-bootstrap-table2-filter',
|
||||||
'react-bootstrap-table2-overlay',
|
'react-bootstrap-table2-overlay',
|
||||||
'react-bootstrap-table2-paginator'
|
'react-bootstrap-table2-paginator',
|
||||||
|
'react-bootstrap-table2-toolkit'
|
||||||
].reduce((pkg, curr) => `${curr}|${pkg}`, '');
|
].reduce((pkg, curr) => `${curr}|${pkg}`, '');
|
||||||
|
|
||||||
const JS_SKIPS = `+(${TEST}|${LIB}|${DIST}|${NODE_MODULES})`;
|
const JS_SKIPS = `+(${TEST}|${LIB}|${DIST}|${NODE_MODULES})`;
|
||||||
@@ -25,7 +26,8 @@ const JS_SKIPS = `+(${TEST}|${LIB}|${DIST}|${NODE_MODULES})`;
|
|||||||
const STYLE_PKGS = [
|
const STYLE_PKGS = [
|
||||||
'react-bootstrap-table2',
|
'react-bootstrap-table2',
|
||||||
'react-bootstrap-table2-filter',
|
'react-bootstrap-table2-filter',
|
||||||
'react-bootstrap-table2-paginator'
|
'react-bootstrap-table2-paginator',
|
||||||
|
'react-bootstrap-table2-toolkit',
|
||||||
].reduce((pkg, curr) => `${curr}|${pkg}`, '');
|
].reduce((pkg, curr) => `${curr}|${pkg}`, '');
|
||||||
|
|
||||||
const STYLE_SKIPS = `+(${NODE_MODULES})`;
|
const STYLE_SKIPS = `+(${NODE_MODULES})`;
|
||||||
@@ -72,9 +74,16 @@ function styles() {
|
|||||||
.pipe(gulp.dest(PKG_PATH));
|
.pipe(gulp.dest(PKG_PATH));
|
||||||
}
|
}
|
||||||
|
|
||||||
function umd() {
|
function umd(done) {
|
||||||
return gulp.src('./webpack.prod.config.babel.js')
|
gulp.parallel(
|
||||||
.pipe(shell(['webpack --config <%= file.path %>']));
|
() => 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 %>'])),
|
||||||
|
() => gulp.src('./webpack/toolkit.umd.babel.js').pipe(shell(['webpack --config <%= file.path %>']))
|
||||||
|
)();
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildJS = gulp.parallel(umd, scripts);
|
const buildJS = gulp.parallel(umd, scripts);
|
||||||
|
|||||||
21
package.json
21
package.json
@@ -11,10 +11,11 @@
|
|||||||
"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 --coverage --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:clean": "cd ./packages/react-bootstrap-table2-example && yarn gh-pages:clean",
|
||||||
"gh-pages:build": "cd ./packages/react-bootstrap-table2-example && yarn gh-pages:build"
|
"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",
|
||||||
@@ -49,8 +50,9 @@
|
|||||||
"babel-preset-stage-0": "6.24.1",
|
"babel-preset-stage-0": "6.24.1",
|
||||||
"babel-register": "6.24.1",
|
"babel-register": "6.24.1",
|
||||||
"css-loader": "0.28.1",
|
"css-loader": "0.28.1",
|
||||||
"enzyme": "3.1.1",
|
"enzyme": "3.4.0",
|
||||||
"enzyme-adapter-react-16": "1.0.4",
|
"enzyme-adapter-react-16.3": "1.0.0",
|
||||||
|
"enzyme-to-json": "3.3.4",
|
||||||
"eslint": "4.5.0",
|
"eslint": "4.5.0",
|
||||||
"eslint-config-airbnb": "15.1.0",
|
"eslint-config-airbnb": "15.1.0",
|
||||||
"eslint-loader": "1.9.0",
|
"eslint-loader": "1.9.0",
|
||||||
@@ -78,14 +80,17 @@
|
|||||||
"webpack-dev-server": "2.7.1"
|
"webpack-dev-server": "2.7.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"classnames": "2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"prop-types": "15.5.10",
|
"prop-types": "15.5.10",
|
||||||
"react": "16.0.0",
|
"react": "16.4.0",
|
||||||
"react-dom": "16.0.0"
|
"react-dom": "16.4.0",
|
||||||
|
"underscore": "1.9.1"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"collectCoverageFrom": [
|
"collectCoverageFrom": [
|
||||||
"packages/**/*.js"
|
"packages/*/src/**/*.js",
|
||||||
|
"packages/*/index.js",
|
||||||
|
"!packages/react-bootstrap-table2-example/**/*.js"
|
||||||
],
|
],
|
||||||
"roots": [
|
"roots": [
|
||||||
"<rootDir>/packages"
|
"<rootDir>/packages"
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ How user save their new editings? We offer two ways:
|
|||||||
* Column Level (Configure [column.editable](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditable-bool-function) as bool value)
|
* 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)
|
* 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
|
## Customize Style/Class
|
||||||
### Editing Cell
|
### Editing Cell
|
||||||
|
|
||||||
@@ -58,6 +61,212 @@ How user save their new editings? We offer two ways:
|
|||||||
* 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 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)
|
* Customize the editor classname via [column.editoClasses](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columneditorclasses-string-function)
|
||||||
|
|
||||||
## Validation
|
## Rich Editors
|
||||||
|
`react-bootstrap-table2` have following predefined editor:
|
||||||
|
|
||||||
[`column.validator`](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/column-props.html#columnvalidator-function) will help you to work on it!
|
* 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. When use dropdown editor, either `editor.options` or `editor.getOptions` should be required prop.
|
||||||
|
|
||||||
|
#### editor.options
|
||||||
|
This is most simple case for assign the dropdown options data directly.
|
||||||
|
|
||||||
|
```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'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
```
|
||||||
|
|
||||||
|
#### editor.getOptions
|
||||||
|
It is much flexible which accept a function and you can assign the dropdown options dynamically.
|
||||||
|
|
||||||
|
There are two case for `getOptions`:
|
||||||
|
|
||||||
|
* *Synchronous*: Just return the options array in `getOptions` callback function
|
||||||
|
* *Asynchronous*: Call `setOptions` function argument when you get the options from remote.
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Synchronous
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
..., {
|
||||||
|
dataField: 'type',
|
||||||
|
text: 'Job Type',
|
||||||
|
editor: {
|
||||||
|
type: Type.SELECT,
|
||||||
|
getOptions: (setOptions, { row, column }) => [.....]
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
// Asynchronous
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
..., {
|
||||||
|
dataField: 'type',
|
||||||
|
text: 'Job Type',
|
||||||
|
editor: {
|
||||||
|
type: Type.SELECT,
|
||||||
|
getOptions: (setOptions, { row, column }) => {
|
||||||
|
setTimeout(() => setOptions([...]), 1500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
[here](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Cell%20Editing&selectedStory=Dropdown%20Editor%20with%20Dynamic%20Options) is an online example.
|
||||||
|
|
||||||
|
### 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.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
|
||||||
|
},
|
||||||
|
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 } />
|
||||||
|
)
|
||||||
|
}];
|
||||||
|
```
|
||||||
|
|||||||
15
packages/react-bootstrap-table2-editor/index.js
vendored
15
packages/react-bootstrap-table2-editor/index.js
vendored
@@ -1,16 +1,19 @@
|
|||||||
import wrapperFactory from './src/wrapper';
|
import createContext from './src/context';
|
||||||
import editingCellFactory from './src/editing-cell';
|
import withRowLevelCellEdit from './src/row-consumer';
|
||||||
|
import createEditingCell from './src/editing-cell-consumer';
|
||||||
import {
|
import {
|
||||||
CLICK_TO_CELL_EDIT,
|
EDITTYPE,
|
||||||
DBCLICK_TO_CELL_EDIT,
|
DBCLICK_TO_CELL_EDIT,
|
||||||
DELAY_FOR_DBCLICK
|
DELAY_FOR_DBCLICK
|
||||||
} from './src/const';
|
} from './src/const';
|
||||||
|
|
||||||
export default (options = {}) => ({
|
export default (options = {}) => ({
|
||||||
wrapperFactory,
|
createContext,
|
||||||
editingCellFactory,
|
createEditingCell,
|
||||||
CLICK_TO_CELL_EDIT,
|
withRowLevelCellEdit,
|
||||||
DBCLICK_TO_CELL_EDIT,
|
DBCLICK_TO_CELL_EDIT,
|
||||||
DELAY_FOR_DBCLICK,
|
DELAY_FOR_DBCLICK,
|
||||||
options
|
options
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const Type = EDITTYPE;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-editor",
|
"name": "react-bootstrap-table2-editor",
|
||||||
"version": "0.1.5",
|
"version": "1.4.0",
|
||||||
"description": "it's the editor addon for react-bootstrap-table2",
|
"description": "it's the editor addon for react-bootstrap-table2",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
],
|
],
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"prop-types": "^15.0.0",
|
"prop-types": "^15.0.0",
|
||||||
"react": "^16.0.0",
|
"react": "^16.3.0",
|
||||||
"react-dom": "^16.0.0"
|
"react-dom": "^16.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
packages/react-bootstrap-table2-editor/src/checkbox-editor.js
vendored
Normal file
65
packages/react-bootstrap-table2-editor/src/checkbox-editor.js
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/* 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() {
|
||||||
|
const { didMount } = this.props;
|
||||||
|
this.checkbox.focus();
|
||||||
|
if (didMount) didMount();
|
||||||
|
}
|
||||||
|
|
||||||
|
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, didMount, 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,
|
||||||
|
didMount: PropTypes.func
|
||||||
|
};
|
||||||
|
CheckBoxEditor.defaultProps = {
|
||||||
|
className: '',
|
||||||
|
value: 'on:off',
|
||||||
|
defaultValue: false,
|
||||||
|
onChange: undefined,
|
||||||
|
didMount: undefined
|
||||||
|
};
|
||||||
|
export default CheckBoxEditor;
|
||||||
@@ -2,3 +2,11 @@ export const TIME_TO_CLOSE_MESSAGE = 3000;
|
|||||||
export const DELAY_FOR_DBCLICK = 200;
|
export const DELAY_FOR_DBCLICK = 200;
|
||||||
export const CLICK_TO_CELL_EDIT = 'click';
|
export const CLICK_TO_CELL_EDIT = 'click';
|
||||||
export const DBCLICK_TO_CELL_EDIT = 'dbclick';
|
export const DBCLICK_TO_CELL_EDIT = 'dbclick';
|
||||||
|
|
||||||
|
export const EDITTYPE = {
|
||||||
|
TEXT: 'text',
|
||||||
|
SELECT: 'select',
|
||||||
|
TEXTAREA: 'textarea',
|
||||||
|
CHECKBOX: 'checkbox',
|
||||||
|
DATE: 'date'
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,31 +1,40 @@
|
|||||||
|
/* eslint disable-next-line: 0 */
|
||||||
/* eslint react/prop-types: 0 */
|
/* eslint react/prop-types: 0 */
|
||||||
import React, { Component } from 'react';
|
/* eslint react/require-default-props: 0 */
|
||||||
|
/* eslint camelcase: 0 */
|
||||||
|
/* eslint react/no-unused-prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const';
|
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const';
|
||||||
|
|
||||||
|
const CellEditContext = React.createContext();
|
||||||
|
|
||||||
export default (
|
export default (
|
||||||
Base,
|
_,
|
||||||
{ _, remoteResolver }
|
dataOperator,
|
||||||
|
isRemoteCellEdit,
|
||||||
|
handleCellChange
|
||||||
) => {
|
) => {
|
||||||
let EditingCell;
|
class CellEditProvider extends React.Component {
|
||||||
return class CellEditWrapper extends remoteResolver(Component) {
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
data: PropTypes.array.isRequired,
|
||||||
|
selectRow: PropTypes.object,
|
||||||
options: PropTypes.shape({
|
options: PropTypes.shape({
|
||||||
mode: PropTypes.oneOf([CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT]).isRequired,
|
mode: PropTypes.oneOf([CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT]).isRequired,
|
||||||
onErrorMessageDisappear: PropTypes.func,
|
onErrorMessageDisappear: PropTypes.func,
|
||||||
blurToSave: PropTypes.bool,
|
blurToSave: PropTypes.bool,
|
||||||
beforeSaveCell: PropTypes.func,
|
beforeSaveCell: PropTypes.func,
|
||||||
afterSaveCell: PropTypes.func,
|
afterSaveCell: PropTypes.func,
|
||||||
|
onStartEdit: PropTypes.func,
|
||||||
nonEditableRows: PropTypes.func,
|
nonEditableRows: PropTypes.func,
|
||||||
timeToCloseMessage: PropTypes.number,
|
timeToCloseMessage: PropTypes.number,
|
||||||
errorMessage: PropTypes.string
|
errorMessage: PropTypes.any
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
EditingCell = props.cellEdit.editingCellFactory(_);
|
this.doUpdate = this.doUpdate.bind(this);
|
||||||
this.startEditing = this.startEditing.bind(this);
|
this.startEditing = this.startEditing.bind(this);
|
||||||
this.escapeEditing = this.escapeEditing.bind(this);
|
this.escapeEditing = this.escapeEditing.bind(this);
|
||||||
this.completeEditing = this.completeEditing.bind(this);
|
this.completeEditing = this.completeEditing.bind(this);
|
||||||
@@ -33,41 +42,58 @@ export default (
|
|||||||
this.state = {
|
this.state = {
|
||||||
ridx: null,
|
ridx: null,
|
||||||
cidx: null,
|
cidx: null,
|
||||||
message: null,
|
message: null
|
||||||
isDataChanged: false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||||
if (nextProps.cellEdit && this.isRemoteCellEdit()) {
|
if (nextProps.cellEdit && isRemoteCellEdit()) {
|
||||||
if (nextProps.cellEdit.options.errorMessage) {
|
if (nextProps.cellEdit.options.errorMessage) {
|
||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
isDataChanged: false,
|
|
||||||
message: nextProps.cellEdit.options.errorMessage
|
message: nextProps.cellEdit.options.errorMessage
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
this.setState(() => ({
|
|
||||||
isDataChanged: true
|
|
||||||
}));
|
|
||||||
this.escapeEditing();
|
this.escapeEditing();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.setState(() => ({
|
|
||||||
isDataChanged: false
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCellUpdate(row, column, newValue) {
|
handleCellUpdate(row, column, newValue) {
|
||||||
const { keyField, cellEdit, store } = this.props;
|
const newValueWithType = dataOperator.typeConvert(column.type, newValue);
|
||||||
const { beforeSaveCell, afterSaveCell } = cellEdit.options;
|
const { cellEdit } = this.props;
|
||||||
|
const { beforeSaveCell } = cellEdit.options;
|
||||||
const oldValue = _.get(row, column.dataField);
|
const oldValue = _.get(row, column.dataField);
|
||||||
|
const beforeSaveCellDone = (result = true) => {
|
||||||
|
if (result) {
|
||||||
|
this.doUpdate(row, column, newValueWithType);
|
||||||
|
} else {
|
||||||
|
this.escapeEditing();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (_.isFunction(beforeSaveCell)) {
|
||||||
|
const result = beforeSaveCell(
|
||||||
|
oldValue,
|
||||||
|
newValueWithType,
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
beforeSaveCellDone
|
||||||
|
);
|
||||||
|
if (_.isObject(result) && result.async) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.doUpdate(row, column, newValueWithType);
|
||||||
|
}
|
||||||
|
|
||||||
|
doUpdate(row, column, newValue) {
|
||||||
|
const { keyField, cellEdit, data } = this.props;
|
||||||
|
const { afterSaveCell } = cellEdit.options;
|
||||||
const rowId = _.get(row, keyField);
|
const rowId = _.get(row, keyField);
|
||||||
if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
|
const oldValue = _.get(row, column.dataField);
|
||||||
if (this.isRemoteCellEdit()) {
|
if (isRemoteCellEdit()) {
|
||||||
this.handleCellChange(rowId, column.dataField, newValue);
|
handleCellChange(rowId, column.dataField, newValue);
|
||||||
} else {
|
} else {
|
||||||
store.edit(rowId, column.dataField, newValue);
|
dataOperator.editCell(data, keyField, rowId, column.dataField, newValue);
|
||||||
if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column);
|
if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column);
|
||||||
this.completeEditing();
|
this.completeEditing();
|
||||||
}
|
}
|
||||||
@@ -77,8 +103,7 @@ export default (
|
|||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
ridx: null,
|
ridx: null,
|
||||||
cidx: null,
|
cidx: null,
|
||||||
message: null,
|
message: null
|
||||||
isDataChanged: true
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +111,7 @@ export default (
|
|||||||
const editing = () => {
|
const editing = () => {
|
||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
ridx,
|
ridx,
|
||||||
cidx,
|
cidx
|
||||||
isDataChanged: false
|
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,19 +127,17 @@ export default (
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isDataChanged, ...stateRest } = this.state;
|
|
||||||
const {
|
const {
|
||||||
cellEdit: {
|
cellEdit: {
|
||||||
options: { nonEditableRows, errorMessage, ...optionsRest },
|
options: { nonEditableRows, errorMessage, ...optionsRest },
|
||||||
editingCellFactory,
|
|
||||||
...cellEditRest
|
...cellEditRest
|
||||||
}
|
}
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const newCellEdit = {
|
const newCellEdit = {
|
||||||
...optionsRest,
|
...optionsRest,
|
||||||
...cellEditRest,
|
...cellEditRest,
|
||||||
...stateRest,
|
...this.state,
|
||||||
EditingCell,
|
|
||||||
nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [],
|
nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [],
|
||||||
onStart: this.startEditing,
|
onStart: this.startEditing,
|
||||||
onEscape: this.escapeEditing,
|
onEscape: this.escapeEditing,
|
||||||
@@ -123,13 +145,17 @@ export default (
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Base
|
<CellEditContext.Provider
|
||||||
{ ...this.props }
|
value={ { ...newCellEdit } }
|
||||||
data={ this.props.store.data }
|
>
|
||||||
isDataChanged={ isDataChanged }
|
{ this.props.children }
|
||||||
cellEdit={ newCellEdit }
|
</CellEditContext.Provider>
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
Provider: CellEditProvider
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Consumer = CellEditContext.Consumer;
|
||||||
45
packages/react-bootstrap-table2-editor/src/date-editor.js
vendored
Normal file
45
packages/react-bootstrap-table2-editor/src/date-editor.js
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* 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, didMount } = this.props;
|
||||||
|
this.date.valueAsDate = new Date(defaultValue);
|
||||||
|
this.date.focus();
|
||||||
|
if (didMount) didMount();
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue() {
|
||||||
|
return this.date.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { defaultValue, didMount, 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,
|
||||||
|
didMount: PropTypes.func
|
||||||
|
};
|
||||||
|
DateEditor.defaultProps = {
|
||||||
|
className: '',
|
||||||
|
defaultValue: '',
|
||||||
|
didMount: undefined
|
||||||
|
};
|
||||||
|
export default DateEditor;
|
||||||
88
packages/react-bootstrap-table2-editor/src/dropdown-editor.js
vendored
Normal file
88
packages/react-bootstrap-table2-editor/src/dropdown-editor.js
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/* eslint no-return-assign: 0 */
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import cs from 'classnames';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
class DropDownEditor extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
let options = props.options;
|
||||||
|
if (props.getOptions) {
|
||||||
|
options = props.getOptions(
|
||||||
|
this.setOptions.bind(this),
|
||||||
|
{
|
||||||
|
row: props.row,
|
||||||
|
column: props.column
|
||||||
|
}
|
||||||
|
) || [];
|
||||||
|
}
|
||||||
|
this.state = { options };
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { defaultValue, didMount } = this.props;
|
||||||
|
this.select.value = defaultValue;
|
||||||
|
this.select.focus();
|
||||||
|
if (didMount) didMount();
|
||||||
|
}
|
||||||
|
|
||||||
|
setOptions(options) {
|
||||||
|
this.setState({ options });
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue() {
|
||||||
|
return this.select.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { defaultValue, didMount, getOptions, className, ...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 }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
this.state.options.map(({ label, value }) => (
|
||||||
|
<option key={ value } value={ value }>{ label }</option>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropDownEditor.propTypes = {
|
||||||
|
row: PropTypes.object.isRequired,
|
||||||
|
column: PropTypes.object.isRequired,
|
||||||
|
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
|
||||||
|
}))
|
||||||
|
]),
|
||||||
|
didMount: PropTypes.func,
|
||||||
|
getOptions: PropTypes.func
|
||||||
|
};
|
||||||
|
DropDownEditor.defaultProps = {
|
||||||
|
className: '',
|
||||||
|
defaultValue: '',
|
||||||
|
style: {},
|
||||||
|
options: [],
|
||||||
|
didMount: undefined,
|
||||||
|
getOptions: undefined
|
||||||
|
};
|
||||||
|
export default DropDownEditor;
|
||||||
44
packages/react-bootstrap-table2-editor/src/editing-cell-consumer.js
vendored
Normal file
44
packages/react-bootstrap-table2-editor/src/editing-cell-consumer.js
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
import { Consumer } from './context';
|
||||||
|
import createEditingCell from './editing-cell';
|
||||||
|
|
||||||
|
export default (_, onStartEdit) => {
|
||||||
|
const EditingCell = createEditingCell(_, onStartEdit);
|
||||||
|
const renderWithEditingCell = (props, cellEdit) => {
|
||||||
|
const content = _.get(props.row, props.column.dataField);
|
||||||
|
let editCellstyle = props.column.editCellStyle || {};
|
||||||
|
let editCellclasses = props.column.editCellClasses;
|
||||||
|
if (_.isFunction(props.column.editCellStyle)) {
|
||||||
|
editCellstyle = props.column.editCellStyle(
|
||||||
|
content,
|
||||||
|
props.row,
|
||||||
|
props.rowIndex,
|
||||||
|
props.columnIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (_.isFunction(props.column.editCellClasses)) {
|
||||||
|
editCellclasses = props.column.editCellClasses(
|
||||||
|
content,
|
||||||
|
props.row,
|
||||||
|
props.rowIndex,
|
||||||
|
props.columnIndex)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EditingCell
|
||||||
|
{ ...props }
|
||||||
|
className={ editCellclasses }
|
||||||
|
style={ editCellstyle }
|
||||||
|
{ ...cellEdit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return props => (
|
||||||
|
<Consumer>
|
||||||
|
{ cellEdit => renderWithEditingCell(props, cellEdit) }
|
||||||
|
</Consumer>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -2,15 +2,20 @@
|
|||||||
/* eslint no-return-assign: 0 */
|
/* eslint no-return-assign: 0 */
|
||||||
/* eslint class-methods-use-this: 0 */
|
/* eslint class-methods-use-this: 0 */
|
||||||
/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
|
/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
|
||||||
|
/* eslint camelcase: 0 */
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import cs from 'classnames';
|
import cs from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
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 TextEditor from './text-editor';
|
||||||
import EditorIndicator from './editor-indicator';
|
import EditorIndicator from './editor-indicator';
|
||||||
import { TIME_TO_CLOSE_MESSAGE } from './const';
|
import { TIME_TO_CLOSE_MESSAGE, EDITTYPE } from './const';
|
||||||
|
|
||||||
export default _ =>
|
export default (_, onStartEdit) =>
|
||||||
class EditingCell extends Component {
|
class EditingCell extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
row: PropTypes.object.isRequired,
|
row: PropTypes.object.isRequired,
|
||||||
@@ -20,6 +25,7 @@ export default _ =>
|
|||||||
onUpdate: PropTypes.func.isRequired,
|
onUpdate: PropTypes.func.isRequired,
|
||||||
onEscape: PropTypes.func.isRequired,
|
onEscape: PropTypes.func.isRequired,
|
||||||
timeToCloseMessage: PropTypes.number,
|
timeToCloseMessage: PropTypes.number,
|
||||||
|
autoSelectText: PropTypes.bool,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
style: PropTypes.object
|
style: PropTypes.object
|
||||||
}
|
}
|
||||||
@@ -27,6 +33,7 @@ export default _ =>
|
|||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
timeToCloseMessage: TIME_TO_CLOSE_MESSAGE,
|
timeToCloseMessage: TIME_TO_CLOSE_MESSAGE,
|
||||||
className: null,
|
className: null,
|
||||||
|
autoSelectText: false,
|
||||||
style: {}
|
style: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,12 +45,18 @@ export default _ =>
|
|||||||
this.handleClick = this.handleClick.bind(this);
|
this.handleClick = this.handleClick.bind(this);
|
||||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||||
this.beforeComplete = this.beforeComplete.bind(this);
|
this.beforeComplete = this.beforeComplete.bind(this);
|
||||||
|
this.asyncbeforeCompete = this.asyncbeforeCompete.bind(this);
|
||||||
|
this.displayErrorMessage = this.displayErrorMessage.bind(this);
|
||||||
this.state = {
|
this.state = {
|
||||||
invalidMessage: null
|
invalidMessage: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps({ message }) {
|
componentWillUnmount() {
|
||||||
|
this.clearTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
UNSAFE_componentWillReceiveProps({ message }) {
|
||||||
if (_.isDefined(message)) {
|
if (_.isDefined(message)) {
|
||||||
this.createTimer();
|
this.createTimer();
|
||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
@@ -52,10 +65,6 @@ export default _ =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.clearTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
clearTimer() {
|
clearTimer() {
|
||||||
if (this.indicatorTimer) {
|
if (this.indicatorTimer) {
|
||||||
clearTimeout(this.indicatorTimer);
|
clearTimeout(this.indicatorTimer);
|
||||||
@@ -73,44 +82,61 @@ export default _ =>
|
|||||||
}, timeToCloseMessage);
|
}, timeToCloseMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeComplete(row, column, newValue) {
|
displayErrorMessage(message) {
|
||||||
const { onUpdate } = this.props;
|
this.setState(() => ({
|
||||||
if (_.isFunction(column.validator)) {
|
invalidMessage: message
|
||||||
const validateForm = column.validator(newValue, row, column);
|
}));
|
||||||
if (_.isObject(validateForm) && !validateForm.valid) {
|
this.createTimer();
|
||||||
this.setState(() => ({
|
}
|
||||||
invalidMessage: validateForm.message
|
|
||||||
}));
|
asyncbeforeCompete(newValue) {
|
||||||
this.createTimer();
|
return (result = { valid: true }) => {
|
||||||
|
const { valid, message } = result;
|
||||||
|
const { onUpdate, row, column } = this.props;
|
||||||
|
if (!valid) {
|
||||||
|
this.displayErrorMessage(message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
onUpdate(row, column, newValue);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeComplete(newValue) {
|
||||||
|
const { onUpdate, row, column } = this.props;
|
||||||
|
if (_.isFunction(column.validator)) {
|
||||||
|
const validateForm = column.validator(
|
||||||
|
newValue,
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
this.asyncbeforeCompete(newValue)
|
||||||
|
);
|
||||||
|
if (_.isObject(validateForm)) {
|
||||||
|
if (validateForm.async) {
|
||||||
|
return;
|
||||||
|
} else if (!validateForm.valid) {
|
||||||
|
this.displayErrorMessage(validateForm.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onUpdate(row, column, newValue);
|
onUpdate(row, column, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBlur() {
|
handleBlur() {
|
||||||
const { onEscape, blurToSave, row, column } = this.props;
|
const { onEscape, blurToSave } = this.props;
|
||||||
if (blurToSave) {
|
if (blurToSave) {
|
||||||
const value = this.editor.text.value;
|
this.beforeComplete(this.editor.getValue());
|
||||||
if (!_.isDefined(value)) {
|
|
||||||
// TODO: for other custom or embed editor
|
|
||||||
}
|
|
||||||
this.beforeComplete(row, column, value);
|
|
||||||
} else {
|
} else {
|
||||||
onEscape();
|
onEscape();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown(e) {
|
handleKeyDown(e) {
|
||||||
const { onEscape, row, column } = this.props;
|
const { onEscape } = this.props;
|
||||||
if (e.keyCode === 27) { // ESC
|
if (e.keyCode === 27) { // ESC
|
||||||
onEscape();
|
onEscape();
|
||||||
} else if (e.keyCode === 13) { // ENTER
|
} else if (e.keyCode === 13) { // ENTER
|
||||||
const value = e.currentTarget.value;
|
this.beforeComplete(this.editor.getValue());
|
||||||
if (!_.isDefined(value)) {
|
|
||||||
// TODO: for other custom or embed editor
|
|
||||||
}
|
|
||||||
this.beforeComplete(row, column, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,17 +150,13 @@ export default _ =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { invalidMessage } = this.state;
|
let editor;
|
||||||
const { row, column, className, style, rowIndex, columnIndex } = this.props;
|
const { row, column, className, style, rowIndex, columnIndex, autoSelectText } = this.props;
|
||||||
const { dataField } = column;
|
const { dataField } = column;
|
||||||
|
|
||||||
const value = _.get(row, dataField);
|
const value = _.get(row, dataField);
|
||||||
const editorAttrs = {
|
const hasError = _.isDefined(this.state.invalidMessage);
|
||||||
onKeyDown: this.handleKeyDown,
|
|
||||||
onBlur: this.handleBlur
|
|
||||||
};
|
|
||||||
|
|
||||||
const hasError = _.isDefined(invalidMessage);
|
|
||||||
let customEditorClass = column.editorClasses || '';
|
let customEditorClass = column.editorClasses || '';
|
||||||
if (_.isFunction(column.editorClasses)) {
|
if (_.isFunction(column.editorClasses)) {
|
||||||
customEditorClass = column.editorClasses(value, row, rowIndex, columnIndex);
|
customEditorClass = column.editorClasses(value, row, rowIndex, columnIndex);
|
||||||
@@ -150,20 +172,55 @@ export default _ =>
|
|||||||
shake: hasError
|
shake: hasError
|
||||||
}, customEditorClass);
|
}, customEditorClass);
|
||||||
|
|
||||||
|
let editorProps = {
|
||||||
|
ref: node => this.editor = node,
|
||||||
|
defaultValue: value,
|
||||||
|
style: editorStyle,
|
||||||
|
className: editorClass,
|
||||||
|
onKeyDown: this.handleKeyDown,
|
||||||
|
onBlur: this.handleBlur
|
||||||
|
};
|
||||||
|
|
||||||
|
if (onStartEdit) {
|
||||||
|
editorProps.didMount = () => onStartEdit(row, column, rowIndex, columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 } row={ row } column={ column } />;
|
||||||
|
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.TEXTAREA) {
|
||||||
|
editor = <TextAreaEditor { ...editorProps } autoSelectText={ autoSelectText } />;
|
||||||
|
} 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 } autoSelectText={ autoSelectText } />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<td
|
<td
|
||||||
className={ cs('react-bootstrap-table-editing-cell', className) }
|
className={ cs('react-bootstrap-table-editing-cell', className) }
|
||||||
style={ style }
|
style={ style }
|
||||||
onClick={ this.handleClick }
|
onClick={ this.handleClick }
|
||||||
>
|
>
|
||||||
<TextEditor
|
{ editor }
|
||||||
ref={ node => this.editor = node }
|
{ hasError ? <EditorIndicator invalidMessage={ this.state.invalidMessage } /> : null }
|
||||||
defaultValue={ value }
|
|
||||||
style={ editorStyle }
|
|
||||||
className={ editorClass }
|
|
||||||
{ ...editorAttrs }
|
|
||||||
/>
|
|
||||||
{ hasError ? <EditorIndicator invalidMessage={ invalidMessage } /> : null }
|
|
||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
const EditorIndicator = ({ invalidMessage }) =>
|
const EditorIndicator = ({ invalidMessage }) =>
|
||||||
(
|
(
|
||||||
<div className="alert alert-danger fade in">
|
<div className="alert alert-danger in" role="alert">
|
||||||
<strong>{ invalidMessage }</strong>
|
<strong>{ invalidMessage }</strong>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
43
packages/react-bootstrap-table2-editor/src/row-consumer.js
vendored
Normal file
43
packages/react-bootstrap-table2-editor/src/row-consumer.js
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
import { DELAY_FOR_DBCLICK, DBCLICK_TO_CELL_EDIT, CLICK_TO_CELL_EDIT } from './const';
|
||||||
|
import { Consumer } from './context';
|
||||||
|
|
||||||
|
export default (Component, selectRowEnabled) => {
|
||||||
|
const renderWithCellEdit = (props, cellEdit) => {
|
||||||
|
const key = props.value;
|
||||||
|
const editableRow = !(
|
||||||
|
cellEdit.nonEditableRows.length > 0 &&
|
||||||
|
cellEdit.nonEditableRows.indexOf(key) > -1
|
||||||
|
);
|
||||||
|
|
||||||
|
const attrs = {};
|
||||||
|
|
||||||
|
if (selectRowEnabled && cellEdit.mode === DBCLICK_TO_CELL_EDIT) {
|
||||||
|
attrs.DELAY_FOR_DBCLICK = DELAY_FOR_DBCLICK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
{ ...props }
|
||||||
|
{ ...attrs }
|
||||||
|
editingRowIdx={ cellEdit.ridx }
|
||||||
|
editingColIdx={ cellEdit.cidx }
|
||||||
|
editable={ editableRow }
|
||||||
|
onStart={ cellEdit.onStart }
|
||||||
|
clickToEdit={ cellEdit.mode === CLICK_TO_CELL_EDIT }
|
||||||
|
dbclickToEdit={ cellEdit.mode === DBCLICK_TO_CELL_EDIT }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
function withConsumer(props) {
|
||||||
|
return (
|
||||||
|
<Consumer>
|
||||||
|
{ cellEdit => renderWithCellEdit(props, cellEdit) }
|
||||||
|
</Consumer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
withConsumer.displayName = 'WithCellEditingRowConsumer';
|
||||||
|
return withConsumer;
|
||||||
|
};
|
||||||
@@ -5,13 +5,19 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
class TextEditor extends Component {
|
class TextEditor extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { defaultValue } = this.props;
|
const { defaultValue, didMount, autoSelectText } = this.props;
|
||||||
this.text.value = defaultValue;
|
this.text.value = defaultValue;
|
||||||
this.text.focus();
|
this.text.focus();
|
||||||
|
if (autoSelectText) this.text.select();
|
||||||
|
if (didMount) didMount();
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue() {
|
||||||
|
return this.text.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { defaultValue, className, ...rest } = this.props;
|
const { defaultValue, didMount, className, autoSelectText, ...rest } = this.props;
|
||||||
const editorClass = cs('form-control editor edit-text', className);
|
const editorClass = cs('form-control editor edit-text', className);
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
@@ -32,10 +38,14 @@ TextEditor.propTypes = {
|
|||||||
defaultValue: PropTypes.oneOfType([
|
defaultValue: PropTypes.oneOfType([
|
||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
PropTypes.number
|
PropTypes.number
|
||||||
])
|
]),
|
||||||
|
autoSelectText: PropTypes.bool,
|
||||||
|
didMount: PropTypes.func
|
||||||
};
|
};
|
||||||
TextEditor.defaultProps = {
|
TextEditor.defaultProps = {
|
||||||
className: null,
|
className: null,
|
||||||
defaultValue: ''
|
defaultValue: '',
|
||||||
|
autoSelectText: false,
|
||||||
|
didMount: undefined
|
||||||
};
|
};
|
||||||
export default TextEditor;
|
export default TextEditor;
|
||||||
|
|||||||
66
packages/react-bootstrap-table2-editor/src/textarea-editor.js
vendored
Normal file
66
packages/react-bootstrap-table2-editor/src/textarea-editor.js
vendored
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* 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, didMount, autoSelectText } = this.props;
|
||||||
|
this.text.value = defaultValue;
|
||||||
|
this.text.focus();
|
||||||
|
if (autoSelectText) this.text.select();
|
||||||
|
if (didMount) didMount();
|
||||||
|
}
|
||||||
|
|
||||||
|
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, didMount, className, autoSelectText, ...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,
|
||||||
|
autoSelectText: PropTypes.bool,
|
||||||
|
didMount: PropTypes.func
|
||||||
|
};
|
||||||
|
TextAreaEditor.defaultProps = {
|
||||||
|
className: '',
|
||||||
|
defaultValue: '',
|
||||||
|
autoSelectText: false,
|
||||||
|
onKeyDown: undefined,
|
||||||
|
didMount: undefined
|
||||||
|
};
|
||||||
|
export default TextAreaEditor;
|
||||||
416
packages/react-bootstrap-table2-editor/test/context.test.js
Normal file
416
packages/react-bootstrap-table2-editor/test/context.test.js
Normal file
@@ -0,0 +1,416 @@
|
|||||||
|
import 'jsdom-global/register';
|
||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import _ from 'react-bootstrap-table-next/src/utils';
|
||||||
|
import dataOperator from 'react-bootstrap-table-next/src/store/operators';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CLICK_TO_CELL_EDIT,
|
||||||
|
DBCLICK_TO_CELL_EDIT,
|
||||||
|
DELAY_FOR_DBCLICK
|
||||||
|
} from '../src/const';
|
||||||
|
import createCellEditContext, { Consumer } from '../src/context';
|
||||||
|
import cellEditFactory from '../index';
|
||||||
|
|
||||||
|
describe('CellEditContext', () => {
|
||||||
|
let wrapper;
|
||||||
|
let cellEdit;
|
||||||
|
let CellEditContext;
|
||||||
|
|
||||||
|
const data = [{
|
||||||
|
id: 1,
|
||||||
|
name: 'A'
|
||||||
|
}, {
|
||||||
|
id: 2,
|
||||||
|
name: 'B'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const keyField = 'id';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Name'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const defaultCellEdit = {
|
||||||
|
mode: CLICK_TO_CELL_EDIT
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultSelectRow = undefined;
|
||||||
|
|
||||||
|
const mockBase = jest.fn((() => null));
|
||||||
|
|
||||||
|
const handleCellChange = jest.fn();
|
||||||
|
|
||||||
|
function shallowContext(
|
||||||
|
customCellEdit = defaultCellEdit,
|
||||||
|
enableRemote = false,
|
||||||
|
selectRow = defaultSelectRow
|
||||||
|
) {
|
||||||
|
mockBase.mockReset();
|
||||||
|
handleCellChange.mockReset();
|
||||||
|
CellEditContext = createCellEditContext(
|
||||||
|
_,
|
||||||
|
dataOperator,
|
||||||
|
jest.fn().mockReturnValue(enableRemote),
|
||||||
|
handleCellChange
|
||||||
|
);
|
||||||
|
cellEdit = cellEditFactory(customCellEdit);
|
||||||
|
return (
|
||||||
|
<CellEditContext.Provider
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
keyField={ keyField }
|
||||||
|
columns={ columns }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
data={ data }
|
||||||
|
>
|
||||||
|
<Consumer>
|
||||||
|
{
|
||||||
|
cellEditProps => mockBase(cellEditProps)
|
||||||
|
}
|
||||||
|
</Consumer>
|
||||||
|
</CellEditContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('default render', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext());
|
||||||
|
wrapper.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have correct Provider property after calling createCellEditContext', () => {
|
||||||
|
expect(CellEditContext.Provider).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have correct state.ridx', () => {
|
||||||
|
expect(wrapper.state().ridx).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have correct state.cidx', () => {
|
||||||
|
expect(wrapper.state().cidx).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have correct state.message', () => {
|
||||||
|
expect(wrapper.state().message).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass correct cell editing props to children element', () => {
|
||||||
|
expect(wrapper.length).toBe(1);
|
||||||
|
expect(JSON.stringify(mockBase.mock.calls[0])).toEqual(JSON.stringify([{
|
||||||
|
...defaultCellEdit,
|
||||||
|
DBCLICK_TO_CELL_EDIT,
|
||||||
|
DELAY_FOR_DBCLICK,
|
||||||
|
...wrapper.state(),
|
||||||
|
nonEditableRows: []
|
||||||
|
}]));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('componentWillReceiveProps', () => {
|
||||||
|
const initialState = { ridx: 1, cidx: 1, message: 'test' };
|
||||||
|
describe('if nextProps.cellEdit is not existing', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext());
|
||||||
|
wrapper.setState(initialState);
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().UNSAFE_componentWillReceiveProps({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.message', () => {
|
||||||
|
expect(wrapper.state().message).toBe(initialState.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.ridx', () => {
|
||||||
|
expect(wrapper.state().ridx).toBe(initialState.ridx);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.cidx', () => {
|
||||||
|
expect(wrapper.state().cidx).toBe(initialState.cidx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if nextProps.cellEdit is existing but remote cell editing is disable', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext());
|
||||||
|
wrapper.setState(initialState);
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().UNSAFE_componentWillReceiveProps({
|
||||||
|
cellEdit: cellEditFactory(defaultCellEdit)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.message', () => {
|
||||||
|
expect(wrapper.state().message).toBe(initialState.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.ridx', () => {
|
||||||
|
expect(wrapper.state().ridx).toBe(initialState.ridx);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.cidx', () => {
|
||||||
|
expect(wrapper.state().cidx).toBe(initialState.cidx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if nextProps.cellEdit is existing and remote cell editing is enable', () => {
|
||||||
|
describe('if nextProps.cellEdit.options.errorMessage is defined', () => {
|
||||||
|
let message;
|
||||||
|
beforeEach(() => {
|
||||||
|
message = 'validation fail';
|
||||||
|
wrapper = shallow(shallowContext(defaultCellEdit, true));
|
||||||
|
wrapper.setState(initialState);
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().UNSAFE_componentWillReceiveProps({
|
||||||
|
cellEdit: cellEditFactory({
|
||||||
|
...defaultCellEdit,
|
||||||
|
errorMessage: message
|
||||||
|
})
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set state.message', () => {
|
||||||
|
expect(wrapper.state('message')).toBe(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.ridx', () => {
|
||||||
|
expect(wrapper.state().ridx).toBe(initialState.ridx);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.cidx', () => {
|
||||||
|
expect(wrapper.state().cidx).toBe(initialState.cidx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if nextProps.cellEdit.options.errorMessage is not defined', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext(defaultCellEdit, true));
|
||||||
|
wrapper.setState(initialState);
|
||||||
|
wrapper.instance().UNSAFE_componentWillReceiveProps({
|
||||||
|
cellEdit: cellEditFactory({ ...defaultCellEdit })
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state.message', () => {
|
||||||
|
expect(wrapper.state('message')).toBe(initialState.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set correct state.ridx', () => {
|
||||||
|
expect(wrapper.state().ridx).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set correct state.cidx', () => {
|
||||||
|
expect(wrapper.state().cidx).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleCellUpdate', () => {
|
||||||
|
const row = data[1];
|
||||||
|
const column = columns[1];
|
||||||
|
const newValue = 'This is new value';
|
||||||
|
const oldValue = row[column.dataField];
|
||||||
|
|
||||||
|
describe('if cellEdit.beforeSaveCell prop is defined', () => {
|
||||||
|
const beforeSaveCell = jest.fn();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
beforeSaveCell.mockReset();
|
||||||
|
wrapper = shallow(shallowContext({
|
||||||
|
...defaultCellEdit,
|
||||||
|
beforeSaveCell
|
||||||
|
}));
|
||||||
|
wrapper.instance().handleCellUpdate(
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
newValue
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call cellEdit.beforeSaveCell correctly', () => {
|
||||||
|
expect(beforeSaveCell).toHaveBeenCalledTimes(1);
|
||||||
|
expect(beforeSaveCell)
|
||||||
|
.toHaveBeenCalledWith(oldValue, newValue, row, column, expect.anything());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when remote cell editing is enable', () => {
|
||||||
|
const afterSaveCell = jest.fn();
|
||||||
|
beforeEach(() => {
|
||||||
|
afterSaveCell.mockReset();
|
||||||
|
wrapper = shallow(shallowContext({
|
||||||
|
...defaultCellEdit,
|
||||||
|
afterSaveCell
|
||||||
|
}, true));
|
||||||
|
wrapper.instance().handleCellUpdate(
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
newValue
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call handleCellChange correctly', () => {
|
||||||
|
expect(handleCellChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(handleCellChange).toHaveBeenCalledWith(row[keyField], column.dataField, newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call cellEdit.afterSaveCell even if it is defined', () => {
|
||||||
|
expect(afterSaveCell).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when remote cell editing is disable', () => {
|
||||||
|
const afterSaveCell = jest.fn();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
afterSaveCell.mockReset();
|
||||||
|
wrapper = shallow(shallowContext({
|
||||||
|
...defaultCellEdit,
|
||||||
|
afterSaveCell
|
||||||
|
}));
|
||||||
|
wrapper.setState({
|
||||||
|
ridx: 1,
|
||||||
|
cidx: 1
|
||||||
|
});
|
||||||
|
wrapper.instance().handleCellUpdate(
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
newValue
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call handleCellChange correctly', () => {
|
||||||
|
expect(handleCellChange).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set state correctly', () => {
|
||||||
|
expect(wrapper.state('ridx')).toBeNull();
|
||||||
|
expect(wrapper.state('cidx')).toBeNull();
|
||||||
|
expect(wrapper.state('message')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call cellEdit.afterSaveCell if it is defined', () => {
|
||||||
|
expect(afterSaveCell).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('completeEditing', () => {
|
||||||
|
const initialState = { ridx: 1, cidx: 1, message: 'test' };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext());
|
||||||
|
wrapper.setState(initialState);
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().completeEditing();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set state correctly', () => {
|
||||||
|
expect(wrapper.state().ridx).toBeNull();
|
||||||
|
expect(wrapper.state().cidx).toBeNull();
|
||||||
|
expect(wrapper.state().message).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('startEditing', () => {
|
||||||
|
const ridx = 0;
|
||||||
|
const cidx = 1;
|
||||||
|
|
||||||
|
describe('if selectRow prop is not defined', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext());
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().startEditing(ridx, cidx);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set state correctly', () => {
|
||||||
|
expect(wrapper.state().ridx).toEqual(ridx);
|
||||||
|
expect(wrapper.state().cidx).toEqual(cidx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if selectRow prop is defined', () => {
|
||||||
|
describe('and selectRow.clickToEdit is enable', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext(
|
||||||
|
defaultCellEdit,
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
...defaultSelectRow,
|
||||||
|
clickToEdit: true
|
||||||
|
}
|
||||||
|
));
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().startEditing(ridx, cidx);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set state correctly', () => {
|
||||||
|
expect(wrapper.state().ridx).toEqual(ridx);
|
||||||
|
expect(wrapper.state().cidx).toEqual(cidx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and selectRow.clickToSelect is disable', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext(
|
||||||
|
defaultCellEdit,
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
...defaultSelectRow,
|
||||||
|
clickToSelect: false
|
||||||
|
}
|
||||||
|
));
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().startEditing(ridx, cidx);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set state correctly', () => {
|
||||||
|
expect(wrapper.state().ridx).toEqual(ridx);
|
||||||
|
expect(wrapper.state().cidx).toEqual(cidx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and selectRow.clickToEdit & selectRow.clickToSelect is enable', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext(
|
||||||
|
defaultCellEdit,
|
||||||
|
false,
|
||||||
|
{
|
||||||
|
...defaultSelectRow,
|
||||||
|
clickToEdit: false,
|
||||||
|
clickToSelect: true
|
||||||
|
}
|
||||||
|
));
|
||||||
|
wrapper.render();
|
||||||
|
wrapper.instance().startEditing(ridx, cidx);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not set state', () => {
|
||||||
|
expect(wrapper.state().ridx).toBeNull();
|
||||||
|
expect(wrapper.state().cidx).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('escapeEditing', () => {
|
||||||
|
const initialState = { ridx: 1, cidx: 1 };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
wrapper = shallow(shallowContext());
|
||||||
|
wrapper.setState(initialState);
|
||||||
|
wrapper.instance().escapeEditing();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set state correctly', () => {
|
||||||
|
expect(wrapper.state().ridx).toBeNull();
|
||||||
|
expect(wrapper.state().cidx).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
import 'jsdom-global/register';
|
||||||
|
import React from 'react';
|
||||||
|
import { mount, shallow } from 'enzyme';
|
||||||
|
import _ from 'react-bootstrap-table-next/src/utils';
|
||||||
|
|
||||||
|
import cellEditFactory from '..';
|
||||||
|
import { CLICK_TO_CELL_EDIT } from '../src/const';
|
||||||
|
import createCellEditContext from '../src/context';
|
||||||
|
import bindEditingCell from '../src/editing-cell-consumer';
|
||||||
|
|
||||||
|
describe('Editing Cell Consumer', () => {
|
||||||
|
let wrapper;
|
||||||
|
let cellEdit;
|
||||||
|
const data = [{
|
||||||
|
id: 1,
|
||||||
|
name: 'A'
|
||||||
|
}, {
|
||||||
|
id: 2,
|
||||||
|
name: 'B'
|
||||||
|
}];
|
||||||
|
let columns;
|
||||||
|
const rowIndex = 1;
|
||||||
|
const row = { id: 1, name: 'A' };
|
||||||
|
const keyField = 'id';
|
||||||
|
const columnIndex = 1;
|
||||||
|
|
||||||
|
const { Provider } = createCellEditContext(_);
|
||||||
|
const WithCellEditComponent = bindEditingCell(_);
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Name'
|
||||||
|
}];
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellClasses is defined as string', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
||||||
|
columns[1].editCellClasses = 'test-class-1';
|
||||||
|
wrapper = shallow(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent
|
||||||
|
row={ row }
|
||||||
|
column={ columns[1] }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columnIndex={ columnIndex }
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
wrapper = wrapper.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject className target component correctly', () => {
|
||||||
|
expect(wrapper.hasClass(`${columns[1].editCellClasses}`)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellStyle is defined as object', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
||||||
|
columns[1].editCellStyle = { color: 'pink' };
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent
|
||||||
|
row={ row }
|
||||||
|
column={ columns[1] }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columnIndex={ columnIndex }
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject style target component correctly', () => {
|
||||||
|
expect(wrapper.find('.react-bootstrap-table-editing-cell').prop('style')).toEqual(columns[1].editCellStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellClasses is defined as function', () => {
|
||||||
|
const className = 'test-class-1';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
||||||
|
columns[1].editCellClasses = jest.fn().mockReturnValue(className);
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent
|
||||||
|
row={ row }
|
||||||
|
column={ columns[1] }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columnIndex={ columnIndex }
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject empty className and style to target component', () => {
|
||||||
|
expect(wrapper.find(className)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call column.editCellClasses function correctly', () => {
|
||||||
|
expect(columns[1].editCellClasses).toHaveBeenCalledTimes(1);
|
||||||
|
expect(columns[1].editCellClasses).toHaveBeenCalledWith(
|
||||||
|
_.get(row, columns[1].dataField),
|
||||||
|
row,
|
||||||
|
rowIndex,
|
||||||
|
columnIndex
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if column.editCellStyle is defined as function', () => {
|
||||||
|
const style = { color: 'blue' };
|
||||||
|
beforeEach(() => {
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
||||||
|
columns[1].editCellStyle = jest.fn().mockReturnValue(style);
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent
|
||||||
|
row={ row }
|
||||||
|
column={ columns[1] }
|
||||||
|
rowIndex={ rowIndex }
|
||||||
|
columnIndex={ columnIndex }
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject style target component correctly', () => {
|
||||||
|
expect(wrapper.find('.react-bootstrap-table-editing-cell').prop('style')).toEqual(style);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call column.editCellStyle function correctly', () => {
|
||||||
|
expect(columns[1].editCellStyle).toHaveBeenCalledTimes(1);
|
||||||
|
expect(columns[1].editCellStyle).toHaveBeenCalledWith(
|
||||||
|
_.get(row, columns[1].dataField),
|
||||||
|
row,
|
||||||
|
rowIndex,
|
||||||
|
columnIndex
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -6,7 +6,12 @@ import { shallow, mount } from 'enzyme';
|
|||||||
|
|
||||||
import _ from 'react-bootstrap-table-next/src/utils';
|
import _ from 'react-bootstrap-table-next/src/utils';
|
||||||
import editingCellFactory from '../src/editing-cell';
|
import editingCellFactory from '../src/editing-cell';
|
||||||
|
import * as constants from '../src/const';
|
||||||
import TextEditor from '../src/text-editor';
|
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';
|
import EditorIndicator from '../src/editor-indicator';
|
||||||
|
|
||||||
const EditingCell = editingCellFactory(_);
|
const EditingCell = editingCellFactory(_);
|
||||||
@@ -39,7 +44,7 @@ describe('EditingCell', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
onEscape = sinon.stub();
|
onEscape = sinon.stub();
|
||||||
onUpdate = sinon.stub();
|
onUpdate = sinon.stub();
|
||||||
wrapper = shallow(
|
wrapper = mount(
|
||||||
<EditingCell
|
<EditingCell
|
||||||
row={ row }
|
row={ row }
|
||||||
rowIndex={ rowIndex }
|
rowIndex={ rowIndex }
|
||||||
@@ -74,7 +79,8 @@ describe('EditingCell', () => {
|
|||||||
it('when press ENTER on TextEditor should call onUpdate correctly', () => {
|
it('when press ENTER on TextEditor should call onUpdate correctly', () => {
|
||||||
const newValue = 'test';
|
const newValue = 'test';
|
||||||
const textEditor = wrapper.find(TextEditor);
|
const textEditor = wrapper.find(TextEditor);
|
||||||
textEditor.simulate('keyDown', { keyCode: 13, currentTarget: { value: newValue } });
|
sinon.stub(textEditor.instance(), 'getValue').returns(newValue);
|
||||||
|
textEditor.simulate('keyDown', { keyCode: 13 });
|
||||||
expect(onUpdate.callCount).toBe(1);
|
expect(onUpdate.callCount).toBe(1);
|
||||||
expect(onUpdate.calledWith(row, column, newValue)).toBe(true);
|
expect(onUpdate.calledWith(row, column, newValue)).toBe(true);
|
||||||
});
|
});
|
||||||
@@ -311,7 +317,7 @@ describe('EditingCell', () => {
|
|||||||
onEscape={ onEscape }
|
onEscape={ onEscape }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
wrapper.instance().beforeComplete(row, column, newValue);
|
wrapper.instance().beforeComplete(newValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call column.validator successfully', () => {
|
it('should call column.validator successfully', () => {
|
||||||
@@ -357,7 +363,17 @@ describe('EditingCell', () => {
|
|||||||
text: 'ID',
|
text: 'ID',
|
||||||
validator: validatorCallBack
|
validator: validatorCallBack
|
||||||
};
|
};
|
||||||
wrapper.instance().beforeComplete(row, column, newValue);
|
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', () => {
|
it('should call column.validator successfully', () => {
|
||||||
@@ -370,4 +386,156 @@ describe('EditingCell', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
138
packages/react-bootstrap-table2-editor/test/row-consumer.test.js
Normal file
138
packages/react-bootstrap-table2-editor/test/row-consumer.test.js
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
import 'jsdom-global/register';
|
||||||
|
import React from 'react';
|
||||||
|
import { mount } from 'enzyme';
|
||||||
|
import _ from 'react-bootstrap-table-next/src/utils';
|
||||||
|
import op from 'react-bootstrap-table-next/src/store/operators';
|
||||||
|
|
||||||
|
import cellEditFactory from '..';
|
||||||
|
import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT, DELAY_FOR_DBCLICK } from '../src/const';
|
||||||
|
import createCellEditContext from '../src/context';
|
||||||
|
import withRowLevelCellEdit from '../src/row-consumer';
|
||||||
|
|
||||||
|
describe('Row Consumer', () => {
|
||||||
|
let wrapper;
|
||||||
|
let cellEdit;
|
||||||
|
const data = [{
|
||||||
|
id: 1,
|
||||||
|
name: 'A'
|
||||||
|
}, {
|
||||||
|
id: 2,
|
||||||
|
name: 'B'
|
||||||
|
}];
|
||||||
|
const row = { id: 1, name: 'A' };
|
||||||
|
const keyField = 'id';
|
||||||
|
const value = _.get(row, keyField);
|
||||||
|
|
||||||
|
const { Provider } = createCellEditContext(_, op, false, jest.fn());
|
||||||
|
const BaseComponent = () => null;
|
||||||
|
|
||||||
|
describe('if cellEdit.nonEditableRows is undefined', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const WithCellEditComponent = withRowLevelCellEdit(
|
||||||
|
props => <BaseComponent { ...props } />,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent value={ value } />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject correct props to target component', () => {
|
||||||
|
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
||||||
|
expect(wrapper.find(BaseComponent).prop('editingRowIdx')).toBeNull();
|
||||||
|
expect(wrapper.find(BaseComponent).prop('editingColIdx')).toBeNull();
|
||||||
|
expect(wrapper.find(BaseComponent).prop('editable')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if cellEdit.nonEditableRows is defined', () => {
|
||||||
|
const nonEditableRows = jest.fn().mockReturnValue([value]);
|
||||||
|
describe('if value prop is match in one of cellEdit.nonEditableRows', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const WithCellEditComponent = withRowLevelCellEdit(
|
||||||
|
props => <BaseComponent { ...props } />,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT, nonEditableRows });
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent value={ value } />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject correct editable prop as false to target component', () => {
|
||||||
|
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
||||||
|
expect(wrapper.find(BaseComponent).prop('editable')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if value prop is not match in one of cellEdit.nonEditableRows', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const WithCellEditComponent = withRowLevelCellEdit(
|
||||||
|
props => <BaseComponent { ...props } />,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT, nonEditableRows });
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent value={ 2 } />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject correct editable prop as false to target component', () => {
|
||||||
|
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
||||||
|
expect(wrapper.find(BaseComponent).prop('editable')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(`if selectRowEnabled argument is true and cellEdit.mode is ${DBCLICK_TO_CELL_EDIT}`, () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const WithCellEditComponent = withRowLevelCellEdit(
|
||||||
|
props => <BaseComponent { ...props } />,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
cellEdit = cellEditFactory({ mode: DBCLICK_TO_CELL_EDIT });
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent value={ value } />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject correct DELAY_FOR_DBCLICK prop to target component', () => {
|
||||||
|
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
||||||
|
expect(wrapper.find(BaseComponent).prop('DELAY_FOR_DBCLICK')).toEqual(DELAY_FOR_DBCLICK);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if cellEdit.ridx and cellEdit.cidx are defined', () => {
|
||||||
|
const ridx = 0;
|
||||||
|
const cidx = 1;
|
||||||
|
beforeEach(() => {
|
||||||
|
const WithCellEditComponent = withRowLevelCellEdit(
|
||||||
|
props => <BaseComponent { ...props } />,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
cellEdit = cellEditFactory({ mode: CLICK_TO_CELL_EDIT });
|
||||||
|
wrapper = mount(
|
||||||
|
<Provider data={ data } keyField={ keyField } cellEdit={ cellEdit }>
|
||||||
|
<WithCellEditComponent value={ value } />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
wrapper.instance().startEditing(ridx, cidx);
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject correct editable prop as false to target component', () => {
|
||||||
|
expect(wrapper.find(BaseComponent)).toHaveLength(1);
|
||||||
|
expect(wrapper.find(BaseComponent).prop('editingRowIdx')).toEqual(ridx);
|
||||||
|
expect(wrapper.find(BaseComponent).prop('editingColIdx')).toEqual(cidx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,330 +0,0 @@
|
|||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
|
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
|
||||||
|
<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous"> -->
|
||||||
@@ -8,6 +8,8 @@ const editorSourcePath = path.join(__dirname, '../../react-bootstrap-table2-edit
|
|||||||
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 filterStylePath = path.join(__dirname, '../../react-bootstrap-table2-filter/style');
|
||||||
|
const toolkitSourcePath = path.join(__dirname, '../../react-bootstrap-table2-toolkit/index.js');
|
||||||
|
const toolkitStylePath = path.join(__dirname, '../../react-bootstrap-table2-toolkit/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');
|
||||||
@@ -23,6 +25,7 @@ const aliasPath = {
|
|||||||
'react-bootstrap-table2-filter': filterSourcePath,
|
'react-bootstrap-table2-filter': filterSourcePath,
|
||||||
'react-bootstrap-table2-overlay': overlaySourcePath,
|
'react-bootstrap-table2-overlay': overlaySourcePath,
|
||||||
'react-bootstrap-table2-paginator': paginationSourcePath,
|
'react-bootstrap-table2-paginator': paginationSourcePath,
|
||||||
|
'react-bootstrap-table2-toolkit': toolkitSourcePath
|
||||||
};
|
};
|
||||||
|
|
||||||
const loaders = [{
|
const loaders = [{
|
||||||
@@ -41,7 +44,13 @@ const loaders = [{
|
|||||||
}, {
|
}, {
|
||||||
test: /\.scss$/,
|
test: /\.scss$/,
|
||||||
use: ['style-loader', 'css-loader', 'sass-loader'],
|
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||||
include: [storyPath, sourceStylePath, paginationStylePath, filterStylePath],
|
include: [
|
||||||
|
storyPath,
|
||||||
|
sourceStylePath,
|
||||||
|
paginationStylePath,
|
||||||
|
filterStylePath,
|
||||||
|
toolkitStylePath
|
||||||
|
],
|
||||||
}, {
|
}, {
|
||||||
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',
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const columns = [{
|
|||||||
|
|
||||||
<BootstrapTable id="bar" keyField='id' data={ products } columns={ columns } />
|
<BootstrapTable id="bar" keyField='id' data={ products } columns={ columns } />
|
||||||
<BootstrapTable classes="foo" 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 () => (
|
export default () => (
|
||||||
@@ -43,6 +44,9 @@ export default () => (
|
|||||||
<h4> Customized table className </h4>
|
<h4> Customized table className </h4>
|
||||||
<BootstrapTable classes="foo" keyField="id" data={ products } columns={ columns } />
|
<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>
|
<Code>{ sourceCode }</Code>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
186
packages/react-bootstrap-table2-example/examples/basic/exposed-function.js
vendored
Normal file
186
packages/react-bootstrap-table2-example/examples/basic/exposed-function.js
vendored
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
/* eslint no-return-assign: 0 */
|
||||||
|
/* eslint no-console: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = productsGenerator(63);
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
sort: true
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
sort: true,
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
sort: true,
|
||||||
|
filter: textFilter()
|
||||||
|
}];
|
||||||
|
|
||||||
|
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'
|
||||||
|
}];
|
||||||
|
|
||||||
|
class ExposedFunctionTable extends React.Component {
|
||||||
|
handleGetCurrentData = () => {
|
||||||
|
console.log(this.node.table.props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentData = () => {
|
||||||
|
console.log(this.node.table.props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetSelectedData = () => {
|
||||||
|
console.log(this.node.selectionContext.selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetExpandedData = () => {
|
||||||
|
console.log(this.node.rowExpandContext.state.expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentPage = () => {
|
||||||
|
console.log(this.node.paginationContext.currPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentSizePerPage = () => {
|
||||||
|
console.log(this.node.paginationContext.currSizePerPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentSortColumn = () => {
|
||||||
|
console.log(this.node.sortContext.state.sortColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentSortOrder = () => {
|
||||||
|
console.log(this.node.sortContext.state.sortOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentFilter = () => {
|
||||||
|
console.log(this.node.filterContext.currFilters);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const expandRow = {
|
||||||
|
renderer: row => (
|
||||||
|
<div>
|
||||||
|
<p>.....</p>
|
||||||
|
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||||
|
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
showExpandColumn: true
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentData }>Get Current Display Rows</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetSelectedData }>Get Current Selected Rows</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetExpandedData }>Get Current Expanded Rows</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentPage }>Get Current Page</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentSizePerPage }>Get Current Size Per Page</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentSortColumn }>Get Current Sort Column</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentSortOrder }>Get Current Sort Order</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentFilter }>Get Current Filter Information</button>
|
||||||
|
<BootstrapTable
|
||||||
|
ref={ n => this.node = n }
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
selectRow={ { mode: 'checkbox', clickToSelect: true } }
|
||||||
|
expandRow={ expandRow }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default class ExposedFunctionTable extends React.Component {
|
||||||
|
handleGetCurrentData = () => {
|
||||||
|
console.log(this.node.table.props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetSelectedData = () => {
|
||||||
|
console.log(this.node.selectionContext.selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetExpandedData = () => {
|
||||||
|
console.log(this.node.rowExpandContext.state.expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentPage = () => {
|
||||||
|
console.log(this.node.paginationContext.currPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentSizePerPage = () => {
|
||||||
|
console.log(this.node.paginationContext.currSizePerPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentSortColumn = () => {
|
||||||
|
console.log(this.node.sortContext.state.sortColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentSortOrder = () => {
|
||||||
|
console.log(this.node.sortContext.state.sortOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleGetCurrentFilter = () => {
|
||||||
|
console.log(this.node.filterContext.currFilters);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const expandRow = {
|
||||||
|
renderer: row => (
|
||||||
|
<div>
|
||||||
|
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
||||||
|
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||||
|
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
showExpandColumn: true
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentData }>Get Current Display Rows</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetSelectedData }>Get Current Selected Rows</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetExpandedData }>Get Current Expanded Rows</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentPage }>Get Current Page</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentSizePerPage }>Get Current Size Per Page</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentSortColumn }>Get Current Sort Column</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentSortOrder }>Get Current Sort Order</button>
|
||||||
|
<button className="btn btn-default" onClick={ this.handleGetCurrentFilter }>Get Current Filter Information</button>
|
||||||
|
<BootstrapTable
|
||||||
|
ref={ n => this.node = n }
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
selectRow={ { mode: 'checkbox', clickToSelect: true } }
|
||||||
|
expandRow={ expandRow }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
40
packages/react-bootstrap-table2-example/examples/basic/large-table.js
vendored
Normal file
40
packages/react-bootstrap-table2-example/examples/basic/large-table.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = productsGenerator(3000);
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const expandRow = {
|
||||||
|
showExpandColumn: true,
|
||||||
|
renderer: row => (
|
||||||
|
<div>
|
||||||
|
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
||||||
|
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||||
|
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
selectRow={ { mode: 'checkbox', clickToSelect: true } }
|
||||||
|
expandRow={ expandRow }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
54
packages/react-bootstrap-table2-example/examples/basic/tabindex-column.js
vendored
Normal file
54
packages/react-bootstrap-table2-example/examples/basic/tabindex-column.js
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField='id'
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
selectRow={ { mode: 'checkbox' } }
|
||||||
|
tabIndexCell
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
selectRow={ { mode: 'checkbox' } }
|
||||||
|
tabIndexCell
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
81
packages/react-bootstrap-table2-example/examples/bootstrap4/column-toggle.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/bootstrap4/column-toggle.js
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
45
packages/react-bootstrap-table2-example/examples/bootstrap4/pagination.js
vendored
Normal file
45
packages/react-bootstrap-table2-example/examples/bootstrap4/pagination.js
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* eslint react/prefer-stateless-function: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = productsGenerator(87);
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable bootstrap4 keyField='id' data={ products } columns={ columns } pagination={ paginationFactory() } />
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable bootstrap4 keyField="id" data={ products } columns={ columns } pagination={ paginationFactory() } />
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
58
packages/react-bootstrap-table2-example/examples/bootstrap4/row-selection.js
vendored
Normal file
58
packages/react-bootstrap-table2-example/examples/bootstrap4/row-selection.js
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
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 selectRow = {
|
||||||
|
mode: 'radio',
|
||||||
|
clickToSelect: true
|
||||||
|
};
|
||||||
|
|
||||||
|
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'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'radio',
|
||||||
|
clickToSelect: true
|
||||||
|
};
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
bootstrap4
|
||||||
|
keyField='id'
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable bootstrap4 keyField="id" data={ products } columns={ columns } selectRow={ selectRow } />
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
70
packages/react-bootstrap-table2-example/examples/bootstrap4/sort.js
vendored
Normal file
70
packages/react-bootstrap-table2-example/examples/bootstrap4/sort.js
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/* eslint react/prefer-stateless-function: 0 */
|
||||||
|
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',
|
||||||
|
sort: true
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
sort: true
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
sort: true
|
||||||
|
}];
|
||||||
|
|
||||||
|
const defaultSorted = [{
|
||||||
|
dataField: 'name',
|
||||||
|
order: 'desc'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
sort: true
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
sort: true
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
sort: true
|
||||||
|
}];
|
||||||
|
|
||||||
|
const defaultSorted = [{
|
||||||
|
dataField: 'name',
|
||||||
|
order: 'desc'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
bootstrap4
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
defaultSorted={ defaultSorted }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
export default class extends React.PureComponent {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable bootstrap4 keyField="id" data={ products } columns={ columns } defaultSorted={ defaultSorted } />
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
90
packages/react-bootstrap-table2-example/examples/bootstrap4/toolkits.js
vendored
Normal file
90
packages/react-bootstrap-table2-example/examples/bootstrap4/toolkits.js
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { Search, CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { SearchBar, ClearSearchButton } = Search;
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { Search, CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { SearchBar, ClearSearchButton } = Search;
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
search
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<h3>Input something at below input field:</h3>
|
||||||
|
<SearchBar { ...props.searchProps } />
|
||||||
|
<ClearSearchButton { ...props.searchProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
search
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<h3>Input something at below input field:</h3>
|
||||||
|
<SearchBar { ...props.searchProps } />
|
||||||
|
<ClearSearchButton { ...props.searchProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
78
packages/react-bootstrap-table2-example/examples/cell-edit/auto-select-text-input-table.js
vendored
Normal file
78
packages/react-bootstrap-table2-example/examples/cell-edit/auto-select-text-input-table.js
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/* 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',
|
||||||
|
autoSelectText: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Auto Select Text Input Field When Editing</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ jobs }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={
|
||||||
|
cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
autoSelectText: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
86
packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-async-hooks-table.js
vendored
Normal file
86
packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-async-hooks-table.js
vendored
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/* eslint no-unused-vars: 0 */
|
||||||
|
/* eslint no-console: 0 */
|
||||||
|
/* eslint no-alert: 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'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
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'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
function beforeSaveCell(oldValue, newValue, row, column, done) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (confirm('Do you want to accep this change?')) {
|
||||||
|
done(true);
|
||||||
|
} else {
|
||||||
|
done(false);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
return { async: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
beforeSaveCell
|
||||||
|
}) }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
function beforeSaveCell(oldValue, newValue, row, column, done) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (confirm('Do you want to accep this change?')) {
|
||||||
|
done(true);
|
||||||
|
} else {
|
||||||
|
done(false);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
return { async: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h2>You will get a confirm prompt when you try to save a cell</h2>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
beforeSaveCell
|
||||||
|
}) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
101
packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-async-validator-table.js
vendored
Normal file
101
packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-async-validator-table.js
vendored
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/* 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'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
validator: (newValue, row, column, done) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (isNaN(newValue)) {
|
||||||
|
return done({
|
||||||
|
valid: false,
|
||||||
|
message: 'Price should be numeric'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (newValue < 2000) {
|
||||||
|
return done({
|
||||||
|
valid: false,
|
||||||
|
message: 'Price should bigger than 2000'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return done();
|
||||||
|
}, 2000);
|
||||||
|
return {
|
||||||
|
async: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
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'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
validator: (newValue, row, column, done) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (isNaN(newValue)) {
|
||||||
|
return done({
|
||||||
|
valid: false,
|
||||||
|
message: 'Price should be numeric'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (newValue < 2000) {
|
||||||
|
return done({
|
||||||
|
valid: false,
|
||||||
|
message: 'Price should bigger than 2000'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return done();
|
||||||
|
}, 2000);
|
||||||
|
return {
|
||||||
|
async: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
blurToSave: true
|
||||||
|
}) }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Product Price should bigger than $2000</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
blurToSave: true
|
||||||
|
}) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -41,6 +41,7 @@ const columns = [{
|
|||||||
columns={ columns }
|
columns={ columns }
|
||||||
cellEdit={ cellEditFactory({
|
cellEdit={ cellEditFactory({
|
||||||
mode: 'click',
|
mode: 'click',
|
||||||
|
onStartEdit: (row, column, rowIndex, columnIndex) => { console.log('start to edit!!!'); },
|
||||||
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
|
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
|
||||||
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
|
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
|
||||||
}) }
|
}) }
|
||||||
@@ -55,6 +56,7 @@ export default () => (
|
|||||||
columns={ columns }
|
columns={ columns }
|
||||||
cellEdit={ cellEditFactory({
|
cellEdit={ cellEditFactory({
|
||||||
mode: 'click',
|
mode: 'click',
|
||||||
|
onStartEdit: (row, column, rowIndex, columnIndex) => { console.log('Start to edit!!!'); },
|
||||||
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
|
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
|
||||||
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
|
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
|
||||||
}) }
|
}) }
|
||||||
|
|||||||
123
packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-data-type.js
vendored
Normal file
123
packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-data-type.js
vendored
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/* eslint prefer-template: 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 products = stockGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Stock ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Stock Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Price',
|
||||||
|
type: 'number'
|
||||||
|
}, {
|
||||||
|
dataField: 'visible',
|
||||||
|
text: 'Visible?',
|
||||||
|
type: 'bool',
|
||||||
|
editor: {
|
||||||
|
type: Type.CHECKBOX,
|
||||||
|
value: 'true:false'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
dataField: 'inStockDate',
|
||||||
|
text: 'Stock Date',
|
||||||
|
type: 'date',
|
||||||
|
formatter: (cell) => {
|
||||||
|
let dateObj = cell;
|
||||||
|
if (typeof cell !== 'object') {
|
||||||
|
dateObj = new Date(cell);
|
||||||
|
}
|
||||||
|
return `${('0' + dateObj.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
|
||||||
|
},
|
||||||
|
editor: {
|
||||||
|
type: Type.DATE
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import cellEditFactory from 'react-bootstrap-table2-editor';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Stock ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Stock Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Price',
|
||||||
|
type: 'number'
|
||||||
|
}, {
|
||||||
|
dataField: 'visible',
|
||||||
|
text: 'Visible?',
|
||||||
|
type: 'bool',
|
||||||
|
editor: {
|
||||||
|
type: Type.CHECKBOX,
|
||||||
|
value: 'true:false'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
dataField: 'inStockDate',
|
||||||
|
text: 'Stock Date',
|
||||||
|
type: 'date',
|
||||||
|
formatter: (cell) => {
|
||||||
|
let dateObj = cell;
|
||||||
|
if (typeof cell !== 'object') {
|
||||||
|
dateObj = new Date(cell);
|
||||||
|
}
|
||||||
|
return \`$\{('0' + dateObj.getUTCDate()).slice(-2)}/$\{('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/$\{dateObj.getUTCFullYear()}\`;
|
||||||
|
},
|
||||||
|
editor: {
|
||||||
|
type: Type.DATE
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
function afterSaveCell(oldValue, newValue) {
|
||||||
|
console.log('--after save cell--');
|
||||||
|
console.log('New Value was apply as');
|
||||||
|
console.log(newValue);
|
||||||
|
console.log(\`and the type is $\{typeof newValue}\`);
|
||||||
|
}
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
blurToSave: true,
|
||||||
|
afterSaveCell
|
||||||
|
}) }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
function afterSaveCell(oldValue, newValue) {
|
||||||
|
console.log('--after save cell--');
|
||||||
|
console.log('New Value was apply as');
|
||||||
|
console.log(newValue);
|
||||||
|
console.log(`and the type is ${typeof newValue}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Save Cell Value with Specified Data Type</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({
|
||||||
|
mode: 'click',
|
||||||
|
blurToSave: true,
|
||||||
|
afterSaveCell
|
||||||
|
}) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
64
packages/react-bootstrap-table2-example/examples/cell-edit/checkbox-editor-table.js
vendored
Normal file
64
packages/react-bootstrap-table2-example/examples/cell-edit/checkbox-editor-table.js
vendored
Normal 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>Checkbox Editor</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ todos }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
135
packages/react-bootstrap-table2-example/examples/cell-edit/custom-editor-table.js
vendored
Normal file
135
packages/react-bootstrap-table2-example/examples/cell-edit/custom-editor-table.js
vendored
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/* 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
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.range.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
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, column, rowIndex, columnIndex) => (
|
||||||
|
<QualityRanger { ...editorProps } value={ value } />
|
||||||
|
)
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Custom Editor</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
77
packages/react-bootstrap-table2-example/examples/cell-edit/date-editor-table.js
vendored
Normal file
77
packages/react-bootstrap-table2-example/examples/cell-edit/date-editor-table.js
vendored
Normal 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.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
|
||||||
|
},
|
||||||
|
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.getUTCDate()).slice(-2)}/$\{('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/$\{dateObj.getUTCFullYear()}\`;
|
||||||
|
},
|
||||||
|
editor: {
|
||||||
|
type: Type.DATE
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ stocks }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Date Editor</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ stocks }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
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'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true,
|
||||||
|
clickToEdit: true
|
||||||
|
};
|
||||||
|
|
||||||
|
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'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true,
|
||||||
|
clickToEdit: true
|
||||||
|
};
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'dbclick' }) }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Double click to edit cell</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'dbclick' }) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
100
packages/react-bootstrap-table2-example/examples/cell-edit/dropdown-editor-table.js
vendored
Normal file
100
packages/react-bootstrap-table2-example/examples/cell-edit/dropdown-editor-table.js
vendored
Normal 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>
|
||||||
|
);
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/* eslint no-console: 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 { jobsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const jobs = jobsGenerator().map(j => ({
|
||||||
|
...j,
|
||||||
|
type2: j.type
|
||||||
|
}));
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Job ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Job Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'owner',
|
||||||
|
text: 'Job Owner'
|
||||||
|
}, {
|
||||||
|
dataField: 'type',
|
||||||
|
text: 'Job Type1',
|
||||||
|
editor: {
|
||||||
|
type: Type.SELECT,
|
||||||
|
getOptions: (setOptions, { row, column }) => {
|
||||||
|
console.log(`current editing row id: ${row.id}`);
|
||||||
|
console.log(`current editing column: ${column.dataField}`);
|
||||||
|
return [{
|
||||||
|
value: 'A',
|
||||||
|
label: 'A'
|
||||||
|
}, {
|
||||||
|
value: 'B',
|
||||||
|
label: 'B'
|
||||||
|
}, {
|
||||||
|
value: 'C',
|
||||||
|
label: 'C'
|
||||||
|
}, {
|
||||||
|
value: 'D',
|
||||||
|
label: 'D'
|
||||||
|
}, {
|
||||||
|
value: 'E',
|
||||||
|
label: 'E'
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
dataField: 'type2',
|
||||||
|
text: 'Job Type2',
|
||||||
|
editor: {
|
||||||
|
type: Type.SELECT,
|
||||||
|
getOptions: (setOptions) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setOptions([{
|
||||||
|
value: 'A',
|
||||||
|
label: 'A'
|
||||||
|
}, {
|
||||||
|
value: 'B',
|
||||||
|
label: 'B'
|
||||||
|
}, {
|
||||||
|
value: 'C',
|
||||||
|
label: 'C'
|
||||||
|
}, {
|
||||||
|
value: 'D',
|
||||||
|
label: 'D'
|
||||||
|
}, {
|
||||||
|
value: 'E',
|
||||||
|
label: 'E'
|
||||||
|
}]);
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
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 Type1',
|
||||||
|
editor: {
|
||||||
|
type: Type.SELECT,
|
||||||
|
getOptions: (setOptions, { row, column }) => {
|
||||||
|
console.log(\`current editing row id: $\{row.id}\`);
|
||||||
|
console.log(\`current editing column: $\{column.dataField}\`);
|
||||||
|
return [{
|
||||||
|
value: 'A',
|
||||||
|
label: 'A'
|
||||||
|
}, {
|
||||||
|
value: 'B',
|
||||||
|
label: 'B'
|
||||||
|
}, {
|
||||||
|
value: 'C',
|
||||||
|
label: 'C'
|
||||||
|
}, {
|
||||||
|
value: 'D',
|
||||||
|
label: 'D'
|
||||||
|
}, {
|
||||||
|
value: 'E',
|
||||||
|
label: 'E'
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
dataField: 'type2',
|
||||||
|
text: 'Job Type2',
|
||||||
|
editor: {
|
||||||
|
type: Type.SELECT,
|
||||||
|
getOptions: (setOptions) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setOptions([{
|
||||||
|
value: 'A',
|
||||||
|
label: 'A'
|
||||||
|
}, {
|
||||||
|
value: 'B',
|
||||||
|
label: 'B'
|
||||||
|
}, {
|
||||||
|
value: 'C',
|
||||||
|
label: 'C'
|
||||||
|
}, {
|
||||||
|
value: 'D',
|
||||||
|
label: 'D'
|
||||||
|
}, {
|
||||||
|
value: 'E',
|
||||||
|
label: 'E'
|
||||||
|
}]);
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ jobs }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Dropdown Editor with Dynamic Options</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ jobs }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
68
packages/react-bootstrap-table2-example/examples/cell-edit/textarea-editor-table.js
vendored
Normal file
68
packages/react-bootstrap-table2-example/examples/cell-edit/textarea-editor-table.js
vendored
Normal 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>Textarea Editor</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ jobs }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEditFactory({ mode: 'click', blurToSave: true }) }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
184
packages/react-bootstrap-table2-example/examples/column-filter/advance-custom-filter.js
vendored
Normal file
184
packages/react-bootstrap-table2-example/examples/column-filter/advance-custom-filter.js
vendored
Normal 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 }>></option>
|
||||||
|
<option value={ Comparator.EQ }>=</option>
|
||||||
|
<option value={ Comparator.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 }>></option>
|
||||||
|
<option value={ Comparator.EQ }>=</option>
|
||||||
|
<option value={ Comparator.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>
|
||||||
|
);
|
||||||
117
packages/react-bootstrap-table2-example/examples/column-filter/clear-all-filters.js
vendored
Normal file
117
packages/react-bootstrap-table2-example/examples/column-filter/clear-all-filters.js
vendored
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter, dateFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { stockGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = stockGenerator(8);
|
||||||
|
|
||||||
|
let nameFilter;
|
||||||
|
let priceFilter;
|
||||||
|
let stockDateFilter;
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter({
|
||||||
|
getFilter: (filter) => {
|
||||||
|
nameFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Price',
|
||||||
|
filter: textFilter({
|
||||||
|
getFilter: (filter) => {
|
||||||
|
priceFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
dataField: 'inStockDate',
|
||||||
|
text: 'InStock Date',
|
||||||
|
formatter: cell => cell.toString(),
|
||||||
|
filter: dateFilter({
|
||||||
|
getFilter: (filter) => {
|
||||||
|
stockDateFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
nameFilter('');
|
||||||
|
priceFilter('');
|
||||||
|
stockDateFilter();
|
||||||
|
};
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter, dateFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
|
||||||
|
let nameFilter;
|
||||||
|
let priceFilter;
|
||||||
|
let stockDateFilter;
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter({
|
||||||
|
getFilter: (filter) => {
|
||||||
|
nameFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Price',
|
||||||
|
filter: textFilter({
|
||||||
|
getFilter: (filter) => {
|
||||||
|
priceFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
dataField: 'inStockDate',
|
||||||
|
text: 'InStock Date',
|
||||||
|
formatter: cell => cell.toString(),
|
||||||
|
filter: dateFilter({
|
||||||
|
getFilter: (filter) => {
|
||||||
|
stockDateFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
nameFilter('');
|
||||||
|
priceFilter('');
|
||||||
|
stockDateFilter();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-lg btn-primary" onClick={ handleClick }> Clear all filters </button>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-lg btn-primary" onClick={ handleClick }> Clear all filters </button>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
78
packages/react-bootstrap-table2-example/examples/column-filter/custom-date-filter.js
vendored
Normal file
78
packages/react-bootstrap-table2-example/examples/column-filter/custom-date-filter.js
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
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',
|
||||||
|
formatter: cell => cell.toString(),
|
||||||
|
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>
|
||||||
|
);
|
||||||
89
packages/react-bootstrap-table2-example/examples/column-filter/custom-filter-logic.js
vendored
Normal file
89
packages/react-bootstrap-table2-example/examples/column-filter/custom-filter-logic.js
vendored
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/* eslint eqeqeq: 0 */
|
||||||
|
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 sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
|
||||||
|
class Table extends React.Component {
|
||||||
|
filterByPrice = (filterVal, data) => {
|
||||||
|
if (filterVal) {
|
||||||
|
return data.filter(product => product.price == filterVal);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter({
|
||||||
|
onFilter: this.filterByPrice
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default class Table extends React.Component {
|
||||||
|
filterByPrice = (filterVal, data) => {
|
||||||
|
if (filterVal) {
|
||||||
|
return data.filter(product => product.price == filterVal);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter({
|
||||||
|
onFilter: this.filterByPrice
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>Implement a eq price filter</h2>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,9 +3,9 @@ import React from 'react';
|
|||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
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 { jobsGenerator1 } from 'utils/common';
|
||||||
|
|
||||||
const jobs = jobsGenerator(5);
|
const jobs = jobsGenerator1(5);
|
||||||
|
|
||||||
const owners = ['Allen', 'Bob', 'Cat'];
|
const owners = ['Allen', 'Bob', 'Cat'];
|
||||||
const types = ['Cloud Service', 'Message Service', 'Add Service', 'Edit Service', 'Money'];
|
const types = ['Cloud Service', 'Message Service', 'Add Service', 'Edit Service', 'Money'];
|
||||||
|
|||||||
128
packages/react-bootstrap-table2-example/examples/column-filter/custom-filter.js
vendored
Normal file
128
packages/react-bootstrap-table2-example/examples/column-filter/custom-filter.js
vendored
Normal 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>
|
||||||
|
);
|
||||||
80
packages/react-bootstrap-table2-example/examples/column-filter/custom-multi-select-filter.js
vendored
Normal file
80
packages/react-bootstrap-table2-example/examples/column-filter/custom-multi-select-filter.js
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
options: selectOptions,
|
||||||
|
withoutEmptyOption: true,
|
||||||
|
style: {
|
||||||
|
backgroundColor: 'pink'
|
||||||
|
},
|
||||||
|
className: 'test-classname',
|
||||||
|
datamycustomattr: 'datamycustomattr'
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
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>
|
||||||
|
);
|
||||||
60
packages/react-bootstrap-table2-example/examples/column-filter/date-filter-default-value.js
vendored
Normal file
60
packages/react-bootstrap-table2-example/examples/column-filter/date-filter-default-value.js
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
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',
|
||||||
|
formatter: cell => cell.toString(),
|
||||||
|
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>
|
||||||
|
);
|
||||||
56
packages/react-bootstrap-table2-example/examples/column-filter/date-filter.js
vendored
Normal file
56
packages/react-bootstrap-table2-example/examples/column-filter/date-filter.js
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
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',
|
||||||
|
formatter: cell => cell.toString(),
|
||||||
|
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>
|
||||||
|
);
|
||||||
57
packages/react-bootstrap-table2-example/examples/column-filter/filter-hooks.js
vendored
Normal file
57
packages/react-bootstrap-table2-example/examples/column-filter/filter-hooks.js
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/* eslint no-console: 0 */
|
||||||
|
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()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter({
|
||||||
|
onFilter: filterVal => console.log(`Filter Value: ${filterVal}`)
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
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()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter({
|
||||||
|
onFilter: filterVal => console.log(\`Filter Value: $\{filterVal}\`)
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
<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>
|
||||||
|
);
|
||||||
93
packages/react-bootstrap-table2-example/examples/column-filter/filter-position.js
vendored
Normal file
93
packages/react-bootstrap-table2-example/examples/column-filter/filter-position.js
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
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()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter()
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode1 = `\
|
||||||
|
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()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter()
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField='id'
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
filterPosition="top"
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const sourceCode2 = `\
|
||||||
|
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()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter()
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField='id'
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
filterPosition="bottom"
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
filterPosition="top"
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode1 }</Code>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
filterPosition="bottom"
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode2 }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
options: selectOptions,
|
||||||
|
defaultValue: [0, 2]
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
options: selectOptions,
|
||||||
|
defaultValue: [0, 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>
|
||||||
|
);
|
||||||
67
packages/react-bootstrap-table2-example/examples/column-filter/multi-select-filter.js
vendored
Normal file
67
packages/react-bootstrap-table2-example/examples/column-filter/multi-select-filter.js
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
options: selectOptions
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
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>
|
||||||
|
);
|
||||||
86
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-date-filter.js
vendored
Normal file
86
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-date-filter.js
vendored
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
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',
|
||||||
|
formatter: cell => cell.toString(),
|
||||||
|
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>
|
||||||
|
);
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
options: selectOptions,
|
||||||
|
getFilter: (filter) => {
|
||||||
|
// qualityFilter was assigned once the component has been mounted.
|
||||||
|
qualityFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
qualityFilter([0, 2]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { multiSelectFilter } 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: multiSelectFilter({
|
||||||
|
options: selectOptions,
|
||||||
|
getFilter: (filter) => {
|
||||||
|
// qualityFilter was assigned once the component has been mounted.
|
||||||
|
qualityFilter = filter;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
qualityFilter([0, 2]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-lg btn-primary" onClick={ handleClick }>{' filter columns by option "good" and "unknow" '}</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" and "unknow" '}</button>
|
||||||
|
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
85
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js
vendored
Normal file
85
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-number-filter.js
vendored
Normal 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>
|
||||||
|
);
|
||||||
96
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js
vendored
Normal file
96
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-select-filter.js
vendored
Normal 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>
|
||||||
|
);
|
||||||
81
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/column-filter/programmatically-text-filter.js
vendored
Normal 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>
|
||||||
|
);
|
||||||
150
packages/react-bootstrap-table2-example/examples/column-filter/select-filter-option-type.js
vendored
Normal file
150
packages/react-bootstrap-table2-example/examples/column-filter/select-filter-option-type.js
vendored
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
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 selectOptionsArr = [{
|
||||||
|
value: 0,
|
||||||
|
label: 'good'
|
||||||
|
}, {
|
||||||
|
value: 1,
|
||||||
|
label: 'Bad'
|
||||||
|
}, {
|
||||||
|
value: 2,
|
||||||
|
label: 'unknown'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const columns1 = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptions[cell],
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptions
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const columns2 = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptionsArr.filter(opt => opt.value === cell)[0].label || '',
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptionsArr
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const columns3 = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptionsArr.filter(opt => opt.value === cell)[0].label || '',
|
||||||
|
filter: selectFilter({
|
||||||
|
options: () => selectOptionsArr
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
|
||||||
|
// Object map options
|
||||||
|
const selectOptions = {
|
||||||
|
0: 'good',
|
||||||
|
1: 'Bad',
|
||||||
|
2: 'unknown'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Array options
|
||||||
|
const selectOptionsArr = [{
|
||||||
|
value: 0,
|
||||||
|
label: 'good'
|
||||||
|
}, {
|
||||||
|
value: 1,
|
||||||
|
label: 'Bad'
|
||||||
|
}, {
|
||||||
|
value: 2,
|
||||||
|
label: 'unknown'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const columns1 = [..., {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptions[cell],
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptions
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
<BootstrapTable keyField='id' data={ products } columns={ columns1 } filter={ filterFactory() } />
|
||||||
|
|
||||||
|
const columns2 = [..., {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptionsArr.filter(opt => opt.value === cell)[0].label || '',
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptionsArr
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
<BootstrapTable keyField='id' data={ products } columns={ columns2 } filter={ filterFactory() } />
|
||||||
|
|
||||||
|
const columns3 = [..., {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptionsArr.filter(opt => opt.value === cell)[0].label || '',
|
||||||
|
filter: selectFilter({
|
||||||
|
options: () => selectOptionsArr
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
<BootstrapTable keyField='id' data={ products } columns={ columns3 } filter={ filterFactory() } />
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h2>Options as an object</h2>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns1 }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<h2>Options as an array</h2>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns2 }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<h2>Options as a function which return an array</h2>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns3 }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/* eslint max-len: 0 */
|
||||||
|
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 = [
|
||||||
|
{ value: 0, label: 'good' },
|
||||||
|
{ value: 1, label: 'Bad' },
|
||||||
|
{ value: 2, label: 'unknown' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptions.find(opt => opt.value === cell).label,
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptions
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
|
||||||
|
const selectOptions = [
|
||||||
|
{ value: 0, label: 'good' },
|
||||||
|
{ value: 1, label: 'Bad' },
|
||||||
|
{ value: 2, label: 'unknown' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptions.find(opt => opt.value === cell).label,
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptions
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
|
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3><code>selectFilter.options</code> accept an Array and we keep that order when rendering the options</h3>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -8,14 +8,17 @@ const products = productsGenerator(8);
|
|||||||
|
|
||||||
const columns = [{
|
const columns = [{
|
||||||
dataField: 'id',
|
dataField: 'id',
|
||||||
text: 'Product ID'
|
text: 'Product ID',
|
||||||
|
footer: 'hello'
|
||||||
}, {
|
}, {
|
||||||
dataField: 'name',
|
dataField: 'name',
|
||||||
text: 'Product Name',
|
text: 'Product Name',
|
||||||
|
footer: 'hello',
|
||||||
filter: textFilter()
|
filter: textFilter()
|
||||||
}, {
|
}, {
|
||||||
dataField: 'price',
|
dataField: 'price',
|
||||||
text: 'Product Price',
|
text: 'Product Price',
|
||||||
|
footer: 'hello',
|
||||||
filter: textFilter()
|
filter: textFilter()
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@@ -39,6 +42,11 @@ const columns = [{
|
|||||||
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
|
<BootstrapTable keyField='id' data={ products } columns={ columns } filter={ filterFactory() } />
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true
|
||||||
|
};
|
||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<div>
|
<div>
|
||||||
<BootstrapTable
|
<BootstrapTable
|
||||||
@@ -46,6 +54,8 @@ export default () => (
|
|||||||
data={ products }
|
data={ products }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
filter={ filterFactory() }
|
filter={ filterFactory() }
|
||||||
|
filterPosition="bottom"
|
||||||
|
selectRow={ selectRow }
|
||||||
/>
|
/>
|
||||||
<Code>{ sourceCode }</Code>
|
<Code>{ sourceCode }</Code>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
94
packages/react-bootstrap-table2-example/examples/column-toggle/column-toggle-with-filter.js
vendored
Normal file
94
packages/react-bootstrap-table2-example/examples/column-toggle/column-toggle-with-filter.js
vendored
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
sort: true,
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
sort: true,
|
||||||
|
filter: textFilter()
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
sort: true,
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
sort: true,
|
||||||
|
filter: textFilter()
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Table will keep the filter/sort state when column toggle</h3>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
135
packages/react-bootstrap-table2-example/examples/column-toggle/custom-toggle-list.js
vendored
Normal file
135
packages/react-bootstrap-table2-example/examples/column-toggle/custom-toggle-list.js
vendored
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columnsdt = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const CustomToggleList = ({
|
||||||
|
columns,
|
||||||
|
onColumnToggle,
|
||||||
|
toggles
|
||||||
|
}) => (
|
||||||
|
<div className="btn-group btn-group-toggle btn-group-vertical" data-toggle="buttons">
|
||||||
|
{
|
||||||
|
columns
|
||||||
|
.map(column => ({
|
||||||
|
...column,
|
||||||
|
toggle: toggles[column.dataField]
|
||||||
|
}))
|
||||||
|
.map(column => (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
key={ column.dataField }
|
||||||
|
className={ \`btn btn-warning \${column.toggle ? 'active' : ''}\` }
|
||||||
|
data-toggle="button"
|
||||||
|
aria-pressed={ column.toggle ? 'true' : 'false' }
|
||||||
|
onClick={ () => onColumnToggle(column.dataField) }
|
||||||
|
>
|
||||||
|
{ column.text }
|
||||||
|
</button>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columnsdt }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<CustomToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CustomToggleList = ({
|
||||||
|
columns,
|
||||||
|
onColumnToggle,
|
||||||
|
toggles
|
||||||
|
}) => (
|
||||||
|
<div className="btn-group btn-group-toggle btn-group-vertical" data-toggle="buttons">
|
||||||
|
{
|
||||||
|
columns
|
||||||
|
.map(column => ({
|
||||||
|
...column,
|
||||||
|
toggle: toggles[column.dataField]
|
||||||
|
}))
|
||||||
|
.map(column => (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
key={ column.dataField }
|
||||||
|
className={ `btn btn-warning ${column.toggle ? 'active' : ''}` }
|
||||||
|
data-toggle="button"
|
||||||
|
aria-pressed={ column.toggle ? 'true' : 'false' }
|
||||||
|
onClick={ () => onColumnToggle(column.dataField) }
|
||||||
|
>
|
||||||
|
{ column.text }
|
||||||
|
</button>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columnsdt }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<CustomToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
81
packages/react-bootstrap-table2-example/examples/column-toggle/default-visibility.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/column-toggle/default-visibility.js
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
hidden: true
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
hidden: true
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
hidden: true
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
hidden: true
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
81
packages/react-bootstrap-table2-example/examples/column-toggle/index.js
vendored
Normal file
81
packages/react-bootstrap-table2-example/examples/column-toggle/index.js
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList { ...props.columnToggleProps } />
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
91
packages/react-bootstrap-table2-example/examples/column-toggle/styling-toggle-list.js
vendored
Normal file
91
packages/react-bootstrap-table2-example/examples/column-toggle/styling-toggle-list.js
vendored
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { ColumnToggle } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ToggleList } = ColumnToggle;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList
|
||||||
|
contextual="success"
|
||||||
|
className="list-custom-class"
|
||||||
|
btnClassName="list-btn-custom-class"
|
||||||
|
{ ...props.columnToggleProps }
|
||||||
|
/>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
columnToggle
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ToggleList
|
||||||
|
contextual="success"
|
||||||
|
className="list-custom-class"
|
||||||
|
btnClassName="list-btn-custom-class"
|
||||||
|
{ ...props.columnToggleProps }
|
||||||
|
/>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -41,7 +41,7 @@ const columns = [{
|
|||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<div>
|
<div>
|
||||||
<h3>Try to hover on Product Name header column</h3>
|
<h3>Try to hover on Product ID Cell</h3>
|
||||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||||
<Code>{ sourceCode }</Code>
|
<Code>{ sourceCode }</Code>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/* eslint no-unused-vars: 0 */
|
/* eslint no-unused-vars: 0 */
|
||||||
/* eslint no-alert: 0 */
|
/* eslint no-alert: 0 */
|
||||||
|
/* eslint no-console: 0 */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
@@ -12,7 +13,22 @@ const columns = [{
|
|||||||
dataField: 'id',
|
dataField: 'id',
|
||||||
text: 'Product ID',
|
text: 'Product ID',
|
||||||
events: {
|
events: {
|
||||||
onClick: () => alert('Click on Product ID field')
|
onClick: (e, column, columnIndex, row, rowIndex) => {
|
||||||
|
console.log(e);
|
||||||
|
console.log(column);
|
||||||
|
console.log(columnIndex);
|
||||||
|
console.log(row);
|
||||||
|
console.log(rowIndex);
|
||||||
|
alert('Click on Product ID field');
|
||||||
|
},
|
||||||
|
onMouseEnter: (e, column, columnIndex, row, rowIndex) => {
|
||||||
|
console.log(e);
|
||||||
|
console.log(column);
|
||||||
|
console.log(columnIndex);
|
||||||
|
console.log(row);
|
||||||
|
console.log(rowIndex);
|
||||||
|
console.log('onMouseEnter on Product ID field');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
dataField: 'name',
|
dataField: 'name',
|
||||||
@@ -29,7 +45,22 @@ const columns = [{
|
|||||||
dataField: 'id',
|
dataField: 'id',
|
||||||
text: 'Product ID',
|
text: 'Product ID',
|
||||||
events: {
|
events: {
|
||||||
onClick: () => alert('Click on Product ID field')
|
onClick: (e, column, columnIndex, row, rowIndex) => {
|
||||||
|
console.log(e);
|
||||||
|
console.log(column);
|
||||||
|
console.log(columnIndex);
|
||||||
|
console.log(row);
|
||||||
|
console.log(rowIndex);
|
||||||
|
alert('Click on Product ID field');
|
||||||
|
},
|
||||||
|
onMouseEnter: (e, column, columnIndex, row, rowIndex) => {
|
||||||
|
console.log(e);
|
||||||
|
console.log(column);
|
||||||
|
console.log(columnIndex);
|
||||||
|
console.log(row);
|
||||||
|
console.log(rowIndex);
|
||||||
|
console.log('onMouseEnter on Product ID field');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
dataField: 'name',
|
dataField: 'name',
|
||||||
@@ -44,7 +75,7 @@ const columns = [{
|
|||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<div>
|
<div>
|
||||||
<h3>Try to Click on Product ID columns</h3>
|
<h3>Try to Click or Mouse over on Product ID columns</h3>
|
||||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||||
<Code>{ sourceCode }</Code>
|
<Code>{ sourceCode }</Code>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import React from 'react';
|
|||||||
|
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
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, withOnSale } from 'utils/common';
|
||||||
|
|
||||||
const products = productsGenerator();
|
const products = withOnSale(productsGenerator());
|
||||||
|
|
||||||
function priceFormatter(cell, row) {
|
function priceFormatter(cell, row) {
|
||||||
if (row.onSale) {
|
if (row.onSale) {
|
||||||
|
|||||||
254
packages/react-bootstrap-table2-example/examples/columns/dummy-column-table.js
vendored
Normal file
254
packages/react-bootstrap-table2-example/examples/columns/dummy-column-table.js
vendored
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/* eslint jsx-a11y/label-has-for: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
|
||||||
|
|
||||||
|
const products = [
|
||||||
|
{ id: 12, name: 'Item 12', price: 12.5, inStock: false },
|
||||||
|
{ id: 13, name: 'Item 13', price: 13.5, inStock: true },
|
||||||
|
{ id: 14, name: 'Item 14', price: 14.5, inStock: true }
|
||||||
|
];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
|
||||||
|
class ProductList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { products, count: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleInStock = () => {
|
||||||
|
let newProducts = [...this.state.products];
|
||||||
|
newProducts = newProducts.map((d) => {
|
||||||
|
if (d.id === 13) {
|
||||||
|
return {
|
||||||
|
...d,
|
||||||
|
inStock: !d.inStock
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
});
|
||||||
|
this.setState(curr => ({ ...curr, products: newProducts }));
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
formatter: (cell, row, rowIndex, extraData) => (
|
||||||
|
<div>
|
||||||
|
<span>ID: {row.id}</span>
|
||||||
|
<br />
|
||||||
|
<span>state: {extraData}</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
formatExtraData: this.state.count
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'inStock',
|
||||||
|
text: 'In Stock',
|
||||||
|
formatter: (cellContent, row) => (
|
||||||
|
<div className="checkbox disabled">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" checked={ row.inStock } disabled />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'df1',
|
||||||
|
isDummyField: true,
|
||||||
|
text: 'Action 1',
|
||||||
|
formatter: (cellContent, row) => {
|
||||||
|
if (row.inStock) {
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-success"> Available</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-danger"> Backordered</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'df2',
|
||||||
|
isDummyField: true,
|
||||||
|
text: 'Action 2',
|
||||||
|
formatter: (cellContent, row) => {
|
||||||
|
if (row.inStock) {
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-success"> Available</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-danger"> Backordered</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>Action 1 and Action 2 are dummy column</h3>
|
||||||
|
<button onClick={ this.toggleInStock } className="btn btn-primary">
|
||||||
|
Toggle item 13 stock status
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-success"
|
||||||
|
onClick={ () => this.setState(() => ({ count: this.state.count + 1 })) }
|
||||||
|
>
|
||||||
|
Click me to Increase counter
|
||||||
|
</button>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ this.state.products }
|
||||||
|
columns={ columns }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
class ProductList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { products, count: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleInStock = () => {
|
||||||
|
let newProducts = [...this.state.products];
|
||||||
|
newProducts = newProducts.map((d) => {
|
||||||
|
if (d.id === 13) {
|
||||||
|
return {
|
||||||
|
...d,
|
||||||
|
inStock: !d.inStock
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
});
|
||||||
|
this.setState(curr => ({ ...curr, products: newProducts }));
|
||||||
|
};
|
||||||
|
|
||||||
|
counter = () => {
|
||||||
|
this.setState(curr => ({ ...curr, count: this.state.count + 1 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
formatter: (cell, row, rowIndex, extraData) => (
|
||||||
|
<div>
|
||||||
|
<span>ID: {row.id}</span>
|
||||||
|
<br />
|
||||||
|
<span>Counter: {extraData}</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
formatExtraData: this.state.count
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'inStock',
|
||||||
|
text: 'In Stock',
|
||||||
|
formatter: (cellContent, row) => (
|
||||||
|
<div className="checkbox disabled">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" checked={ row.inStock } disabled />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'df1',
|
||||||
|
isDummyField: true,
|
||||||
|
text: 'Action 1',
|
||||||
|
formatter: (cellContent, row) => {
|
||||||
|
if (row.inStock) {
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-success"> Available</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-danger"> Backordered</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'df2',
|
||||||
|
isDummyField: true,
|
||||||
|
text: 'Action 2',
|
||||||
|
formatter: (cellContent, row) => {
|
||||||
|
if (row.inStock) {
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-success"> Available</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<h5>
|
||||||
|
<span className="label label-danger"> Backordered</span>
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>Action 1 and Action 2 are dummy column</h3>
|
||||||
|
<button onClick={ this.toggleInStock } className="btn btn-primary">
|
||||||
|
Toggle item 13 stock status
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-success"
|
||||||
|
onClick={ this.counter }
|
||||||
|
>
|
||||||
|
Click me to Increase counter
|
||||||
|
</button>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ this.state.products }
|
||||||
|
columns={ columns }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductList;
|
||||||
188
packages/react-bootstrap-table2-example/examples/columns/row-expand-with-formatted-dummy-column.js
vendored
Normal file
188
packages/react-bootstrap-table2-example/examples/columns/row-expand-with-formatted-dummy-column.js
vendored
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
/* eslint no-param-reassign: 0 */
|
||||||
|
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 sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
|
||||||
|
class DummyColumnWithRowExpand extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
hoverIdx: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
expandRow = {
|
||||||
|
renderer: () => (
|
||||||
|
<div style={ { width: '100%', height: '20px' } }>Content</div>
|
||||||
|
),
|
||||||
|
showExpandColumn: true,
|
||||||
|
expandByColumnOnly: true
|
||||||
|
};
|
||||||
|
|
||||||
|
actionFormater = (cell, row, rowIndex, { hoverIdx }) => {
|
||||||
|
if ((hoverIdx !== null || hoverIdx !== undefined) && hoverIdx === rowIndex) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={ { width: '20px', height: '20px', backgroundColor: 'orange' } }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={ { width: '20px', height: '20px' } }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowEvents = {
|
||||||
|
onMouseEnter: (e, row, rowIndex) => {
|
||||||
|
this.setState({ hoverIdx: rowIndex });
|
||||||
|
},
|
||||||
|
onMouseLeave: () => {
|
||||||
|
this.setState({ hoverIdx: null });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rowStyle = (row, rowIndex) => {
|
||||||
|
row.index = rowIndex;
|
||||||
|
const style = {};
|
||||||
|
if (rowIndex % 2 === 0) {
|
||||||
|
style.backgroundColor = 'transparent';
|
||||||
|
} else {
|
||||||
|
style.backgroundColor = 'rgba(54, 163, 173, .10)';
|
||||||
|
}
|
||||||
|
style.borderTop = 'none';
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}, {
|
||||||
|
text: '',
|
||||||
|
isDummyField: true,
|
||||||
|
formatter: this.actionFormater,
|
||||||
|
formatExtraData: { hoverIdx: this.state.hoverIdx },
|
||||||
|
headerStyle: { width: '50px' },
|
||||||
|
style: { height: '30px' }
|
||||||
|
}];
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
noDataIndication="There is no data"
|
||||||
|
classes="table"
|
||||||
|
rowStyle={ this.rowStyle }
|
||||||
|
rowEvents={ this.rowEvents }
|
||||||
|
expandRow={ this.expandRow }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default class DummyColumnWithRowExpand extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
hoverIdx: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
expandRow = {
|
||||||
|
renderer: () => (
|
||||||
|
<div style={ { width: '100%', height: '20px' } }>Content</div>
|
||||||
|
),
|
||||||
|
showExpandColumn: true,
|
||||||
|
expandByColumnOnly: true
|
||||||
|
};
|
||||||
|
|
||||||
|
actionFormater = (cell, row, rowIndex, { hoverIdx }) => {
|
||||||
|
if ((hoverIdx !== null || hoverIdx !== undefined) && hoverIdx === rowIndex) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={ { width: '20px', height: '20px', backgroundColor: 'orange' } }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={ { width: '20px', height: '20px' } }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowEvents = {
|
||||||
|
onMouseEnter: (e, row, rowIndex) => {
|
||||||
|
this.setState({ hoverIdx: rowIndex });
|
||||||
|
},
|
||||||
|
onMouseLeave: () => {
|
||||||
|
this.setState({ hoverIdx: null });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rowStyle = (row, rowIndex) => {
|
||||||
|
row.index = rowIndex;
|
||||||
|
const style = {};
|
||||||
|
if (rowIndex % 2 === 0) {
|
||||||
|
style.backgroundColor = 'transparent';
|
||||||
|
} else {
|
||||||
|
style.backgroundColor = 'rgba(54, 163, 173, .10)';
|
||||||
|
}
|
||||||
|
style.borderTop = 'none';
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}, {
|
||||||
|
isDummyField: true,
|
||||||
|
text: '',
|
||||||
|
formatter: this.actionFormater,
|
||||||
|
formatExtraData: { hoverIdx: this.state.hoverIdx },
|
||||||
|
headerStyle: { width: '50px' },
|
||||||
|
style: { height: '30px' }
|
||||||
|
}];
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
rowStyle={ this.rowStyle }
|
||||||
|
rowEvents={ this.rowEvents }
|
||||||
|
expandRow={ this.expandRow }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
80
packages/react-bootstrap-table2-example/examples/csv/csv-column-formatter.js
vendored
Normal file
80
packages/react-bootstrap-table2-example/examples/csv/csv-column-formatter.js
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
/* eslint no-unused-vars: 0 */
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
csvFormatter: (cell, row, rowIndex) => `$ ${cell}NTD`
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
csvFormatter: (cell, row, rowIndex) => \`$ \${cell}NTD\`
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
79
packages/react-bootstrap-table2-example/examples/csv/csv-column-type.js
vendored
Normal file
79
packages/react-bootstrap-table2-example/examples/csv/csv-column-type.js
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
csvType: Number
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
csvType: Number
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
97
packages/react-bootstrap-table2-example/examples/csv/custom-csv-button.js
vendored
Normal file
97
packages/react-bootstrap-table2-example/examples/csv/custom-csv-button.js
vendored
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const MyExportCSV = (props) => {
|
||||||
|
const handleClick = () => {
|
||||||
|
props.onExport();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-success" onClick={ handleClick }>Export to CSV</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
<hr />
|
||||||
|
<MyExportCSV { ...props.csvProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MyExportCSV = (props) => {
|
||||||
|
const handleClick = () => {
|
||||||
|
props.onExport();
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-success" onClick={ handleClick }>Export to CSV</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
<hr />
|
||||||
|
<MyExportCSV { ...props.csvProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
83
packages/react-bootstrap-table2-example/examples/csv/custom-csv-header.js
vendored
Normal file
83
packages/react-bootstrap-table2-example/examples/csv/custom-csv-header.js
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
csvText: 'CSV Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
csvText: 'CSV Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
csvText: 'CSV Product price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
csvText: 'CSV Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
csvText: 'CSV Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
csvText: 'CSV Product price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
82
packages/react-bootstrap-table2-example/examples/csv/custom-csv.js
vendored
Normal file
82
packages/react-bootstrap-table2-example/examples/csv/custom-csv.js
vendored
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV={ {
|
||||||
|
fileName: 'custom.csv',
|
||||||
|
separator: '|',
|
||||||
|
ignoreHeader: true,
|
||||||
|
noAutoBOM: false
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
99
packages/react-bootstrap-table2-example/examples/csv/export-custom-data.js
vendored
Normal file
99
packages/react-bootstrap-table2-example/examples/csv/export-custom-data.js
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const MyExportCSV = (props) => {
|
||||||
|
const handleClick = () => {
|
||||||
|
// passing my custom data
|
||||||
|
props.onExport(products.filter(r => r.id > 2));
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-success" onClick={ handleClick }>Only export Product ID bigger than 2</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
<hr />
|
||||||
|
<MyExportCSV { ...props.csvProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MyExportCSV = (props) => {
|
||||||
|
const handleClick = () => {
|
||||||
|
// passing my custom data
|
||||||
|
props.onExport(products.filter(r => r.id > 2));
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-success" onClick={ handleClick }>Only export Product ID bigger than 2</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
<hr />
|
||||||
|
<MyExportCSV { ...props.csvProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
102
packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js
vendored
Normal file
102
packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js
vendored
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport, Search } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { SearchBar } = Search;
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator(150);
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport, Search } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
|
||||||
|
const { SearchBar } = Search;
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true
|
||||||
|
};
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV={ { onlyExportFiltered: true, exportAll: false } }
|
||||||
|
search
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<SearchBar { ...props.searchProps } />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Export all the filtered/searched rows</h3>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV={ { onlyExportFiltered: true, exportAll: false } }
|
||||||
|
search
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<SearchBar { ...props.searchProps } />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
140
packages/react-bootstrap-table2-example/examples/csv/export-only-selected.js
vendored
Normal file
140
packages/react-bootstrap-table2-example/examples/csv/export-only-selected.js
vendored
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products1 = productsGenerator(15);
|
||||||
|
const products2 = productsGenerator(15);
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true
|
||||||
|
};
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products1 }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV={ { onlyExportSelection: true, exportAll: true } }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products2 }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV={ { onlyExportSelection: true, exportAll: false } }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const selectRow = {
|
||||||
|
mode: 'checkbox',
|
||||||
|
clickToSelect: true
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<h3>Export all selected row</h3>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products1 }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV={ { onlyExportSelection: true, exportAll: true } }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<h3>Export all selected rows in currect visible rows</h3>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products2 }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV={ { onlyExportSelection: true, exportAll: false } }
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable
|
||||||
|
{ ...props.baseProps }
|
||||||
|
selectRow={ selectRow }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
79
packages/react-bootstrap-table2-example/examples/csv/hide-column.js
vendored
Normal file
79
packages/react-bootstrap-table2-example/examples/csv/hide-column.js
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
csvExport: false
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
csvExport: false
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
77
packages/react-bootstrap-table2-example/examples/csv/index.js
vendored
Normal file
77
packages/react-bootstrap-table2-example/examples/csv/index.js
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const products = productsGenerator();
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||||
|
|
||||||
|
const { ExportCSVButton } = CSVExport;
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price'
|
||||||
|
}];
|
||||||
|
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
exportCSV
|
||||||
|
>
|
||||||
|
{
|
||||||
|
props => (
|
||||||
|
<div>
|
||||||
|
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||||
|
<hr />
|
||||||
|
<BootstrapTable { ...props.baseProps } />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
151
packages/react-bootstrap-table2-example/examples/data/data-change-listener.js
vendored
Normal file
151
packages/react-bootstrap-table2-example/examples/data/data-change-listener.js
vendored
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/* eslint react/no-multi-comp: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter()
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode1 = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
|
||||||
|
class Case1 extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { rowCount: products.length };
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDataChange = ({ dataSize }) => {
|
||||||
|
this.setState({ rowCount: dataSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||||
|
<BootstrapTable
|
||||||
|
onDataSizeChange={ this.handleDataChange }
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const sourceCode2 = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
|
||||||
|
class Case2 extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { rowCount: products.length };
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDataChange = ({ dataSize }) => {
|
||||||
|
this.setState({ rowCount: dataSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||||
|
<BootstrapTable
|
||||||
|
onDataSizeChange={ this.handleDataChange }
|
||||||
|
keyField="id"
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const products1 = productsGenerator(8);
|
||||||
|
class WithoutPaginationCase extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { rowCount: products1.length };
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDataChange = ({ dataSize }) => {
|
||||||
|
this.setState({ rowCount: dataSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>Without Pagination Case</h3>
|
||||||
|
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||||
|
<BootstrapTable
|
||||||
|
onDataSizeChange={ this.handleDataChange }
|
||||||
|
keyField="id"
|
||||||
|
data={ products1 }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode2 }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const products2 = productsGenerator(88);
|
||||||
|
class WithPaginationCase extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { rowCount: products2.length };
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDataChange = ({ dataSize }) => {
|
||||||
|
this.setState({ rowCount: dataSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>Without Pagination Case</h3>
|
||||||
|
<h5>Row Count:<span className="badge">{ this.state.rowCount }</span></h5>
|
||||||
|
<BootstrapTable
|
||||||
|
onDataSizeChange={ this.handleDataChange }
|
||||||
|
keyField="id"
|
||||||
|
data={ products2 }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
pagination={ paginationFactory() }
|
||||||
|
/>
|
||||||
|
<Code>{ sourceCode1 }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<WithoutPaginationCase />
|
||||||
|
<WithPaginationCase />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/* eslint react/prop-types: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
|
const ProductList = (props) => {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter({
|
||||||
|
defaultValue: '1'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
filter: textFilter()
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={ { paddingTop: '20px' } }>
|
||||||
|
<h1 className="h2">Products</h1>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ props.products }
|
||||||
|
columns={ columns }
|
||||||
|
filter={ filterFactory() }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class DataContainer extends React.Component {
|
||||||
|
state = {
|
||||||
|
products: productsGenerator(3)
|
||||||
|
};
|
||||||
|
|
||||||
|
loadData = () => {
|
||||||
|
this.setState({
|
||||||
|
products: productsGenerator(14)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
onClick={ this.loadData }
|
||||||
|
style={ {
|
||||||
|
fontSize: '20px',
|
||||||
|
position: 'absolute',
|
||||||
|
left: '200px',
|
||||||
|
top: '40px'
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
Load Data
|
||||||
|
</button>
|
||||||
|
<ProductList products={ this.state.products } />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user