Compare commits

..

28 Commits

Author SHA1 Message Date
AllenFang
e251068657 Publish
- react-bootstrap-table2-example@1.0.9
 - react-bootstrap-table2-filter@1.0.2
 - react-bootstrap-table-next@1.4.0
2018-11-05 00:11:59 +08:00
Allen
e4fbb284b4 Merge pull request #647 from react-bootstrap-table/develop
20181104 release
2018-11-05 00:04:22 +08:00
Allen
a6afc9d9a8 Merge pull request #646 from react-bootstrap-table/enhance/641
Enhance/641
2018-11-04 16:44:11 +08:00
AllenFang
a0ba41c103 patch docs for #641 2018-11-04 16:32:13 +08:00
AllenFang
4a16cb314d add story for #641 2018-11-04 16:24:48 +08:00
AllenFang
98a04a5710 fix #641 2018-11-04 16:24:34 +08:00
Allen
c22a2a1d71 Merge pull request #644 from react-bootstrap-table/enhance/297
Enhance/297
2018-11-03 17:58:22 +08:00
AllenFang
9bc25c9d3e patch docs for selection control 2018-11-03 16:45:05 +08:00
AllenFang
4554db02d2 add story for advance selection contrl 2018-11-03 16:37:51 +08:00
AllenFang
b7fac973d2 fix #297 2018-11-03 16:37:02 +08:00
AllenFang
6925358631 Publish
- react-bootstrap-table2-editor@1.2.1
 - react-bootstrap-table2-example@1.0.8
 - react-bootstrap-table-next@1.3.1
2018-10-30 00:01:35 +08:00
Allen
27c3cdab29 Merge pull request #635 from react-bootstrap-table/develop
20181028 release
2018-10-29 23:59:30 +08:00
AllenFang
bc0c048735 try to fix #620 2018-10-28 17:35:16 +08:00
Allen
a4c1090a0f Merge pull request #634 from react-bootstrap-table/feat/583
Feat/583
2018-10-28 17:16:51 +08:00
AllenFang
5fac4540a1 patch test for #583 2018-10-28 16:59:44 +08:00
AllenFang
f7a06401ae patch docs and story for #583 2018-10-28 16:51:36 +08:00
AllenFang
858ad9543b fix #583 2018-10-28 16:51:13 +08:00
AllenFang
abf618ce6d Merge branch 'develop' of https://github.com/react-bootstrap-table/react-bootstrap-table2 into develop 2018-10-28 16:04:41 +08:00
AllenFang
ea6cb78302 patch docs for #604 2018-10-28 16:04:25 +08:00
Allen
bacbfdbbf0 Merge pull request #633 from react-bootstrap-table/feat/604
Feat/604
2018-10-28 16:01:14 +08:00
AllenFang
465212ff35 patch story 2018-10-28 15:51:45 +08:00
AllenFang
2a58f99a97 add story for #604 2018-10-28 15:50:56 +08:00
AllenFang
7bda61f5be fix #604 2018-10-28 15:50:43 +08:00
Allen
7220b2d073 Merge pull request #632 from react-bootstrap-table/enhance/621
Enhance/621
2018-10-28 14:49:09 +08:00
AllenFang
f7a1c91904 patch story for #621 2018-10-28 14:32:39 +08:00
AllenFang
ea827bfeb5 patch docs for #621 2018-10-28 14:32:28 +08:00
AllenFang
f1f4bd784d fix #621 2018-10-28 14:32:11 +08:00
Ryan Waskiewicz
569c22ba49 Update development.md with git clone directory (#605)
* Update development.md

- Update directory name that's created after cloning the project
- Remove lerna bootstrap step (appears to be run as a postinstall step in npm scripts)

* Update development.md
2018-10-21 14:45:25 +08:00
24 changed files with 640 additions and 67 deletions

View File

@@ -62,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 accep 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>
This callback function will be called after updating cell.

View File

@@ -379,17 +379,27 @@ A new `String` will be the result of element headerAlign.
## <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
{
// omit...
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>
`headerEvents` same as [`column.events`](#events) but this is for header column.
@@ -543,6 +553,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>
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:

View File

@@ -3,7 +3,7 @@
### Setup
```bash
$ git clone https://github.com/react-bootstrap-table/react-bootstrap-table2.git
$ cd react-bootstrap-table
$ cd react-bootstrap-table2
$ npm install
$ lerna bootstrap # ./node_modules/.bin/lerna bootstrap
```

View File

@@ -211,18 +211,44 @@ const selectRow = {
};
```
> 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>
This callback function will be called when select/unselect all and it only work when you configure [`selectRow.mode`](#mode) as `checkbox`.
```js
const selectRow = {
mode: 'checkbox',
onSelectAll: (isSelect, results, e) => {
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='hideSelectColumn'>selectRow.hideSelectColumn - [Bool]</a>
Default is `false`, if you don't want to have a selection column, give this prop as `true`

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-editor",
"version": "1.2.0",
"version": "1.2.1",
"description": "it's the editor addon for react-bootstrap-table2",
"main": "./lib/index.js",
"scripts": {

View File

@@ -31,6 +31,7 @@ export default (
constructor(props) {
super(props);
this.doUpdate = this.doUpdate.bind(this);
this.startEditing = this.startEditing.bind(this);
this.escapeEditing = this.escapeEditing.bind(this);
this.completeEditing = this.completeEditing.bind(this);
@@ -55,11 +56,36 @@ export default (
}
handleCellUpdate(row, column, newValue) {
const { keyField, cellEdit, data } = this.props;
const { beforeSaveCell, afterSaveCell } = cellEdit.options;
const { cellEdit } = this.props;
const { beforeSaveCell } = cellEdit.options;
const oldValue = _.get(row, column.dataField);
const beforeSaveCellDone = (result = true) => {
if (result) {
this.doUpdate(row, column, newValue);
} else {
this.escapeEditing();
}
};
if (_.isFunction(beforeSaveCell)) {
const result = beforeSaveCell(
oldValue,
newValue,
row,
column,
beforeSaveCellDone
);
if (_.isObject(result) && result.async) {
return;
}
}
this.doUpdate(row, column, newValue);
}
doUpdate(row, column, newValue) {
const { keyField, cellEdit, data } = this.props;
const { afterSaveCell } = cellEdit.options;
const rowId = _.get(row, keyField);
if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
const oldValue = _.get(row, column.dataField);
if (isRemoteCellEdit()) {
handleCellChange(rowId, column.dataField, newValue);
} else {

View File

@@ -44,6 +44,8 @@ export default (_, onStartEdit) =>
this.handleClick = this.handleClick.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.beforeComplete = this.beforeComplete.bind(this);
this.asyncbeforeCompete = this.asyncbeforeCompete.bind(this);
this.displayErrorMessage = this.displayErrorMessage.bind(this);
this.state = {
invalidMessage: null
};
@@ -79,16 +81,41 @@ export default (_, onStartEdit) =>
}, timeToCloseMessage);
}
displayErrorMessage(message) {
this.setState(() => ({
invalidMessage: message
}));
this.createTimer();
}
asyncbeforeCompete(newValue) {
return (result = { valid: true }) => {
const { valid, message } = result;
const { onUpdate, row, column } = this.props;
if (!valid) {
this.displayErrorMessage(message);
return;
}
onUpdate(row, column, newValue);
};
}
beforeComplete(newValue) {
const { onUpdate, row, column } = this.props;
if (_.isFunction(column.validator)) {
const validateForm = column.validator(newValue, row, column);
if (_.isObject(validateForm) && !validateForm.valid) {
this.setState(() => ({
invalidMessage: validateForm.message
}));
this.createTimer();
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);

View File

@@ -235,7 +235,8 @@ describe('CellEditContext', () => {
it('should call cellEdit.beforeSaveCell correctly', () => {
expect(beforeSaveCell).toHaveBeenCalledTimes(1);
expect(beforeSaveCell).toHaveBeenCalledWith(oldValue, newValue, row, column);
expect(beforeSaveCell)
.toHaveBeenCalledWith(oldValue, newValue, row, column, expect.anything());
});
});

View 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>
);

View 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>
);

View File

@@ -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 = [
{ label: 0, value: 'good' },
{ label: 1, value: 'Bad' },
{ label: 2, value: 'unknown' }
];
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions.find(opt => opt.label === cell).value,
filter: selectFilter({
options: selectOptions
})
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { selectFilter } from 'react-bootstrap-table2-filter';
const selectOptions = [
{ label: 0, value: 'good' },
{ label: 1, value: 'Bad' },
{ label: 2, value: 'unknown' }
];
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions.find(opt => opt.label === cell).value,
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>
);

View File

@@ -1,5 +1,6 @@
/* eslint no-unused-vars: 0 */
/* eslint no-alert: 0 */
/* eslint no-console: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
@@ -12,7 +13,22 @@ const columns = [{
dataField: 'id',
text: 'Product ID',
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',
@@ -29,7 +45,22 @@ const columns = [{
dataField: 'id',
text: 'Product ID',
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',
@@ -44,7 +75,7 @@ const columns = [{
export default () => (
<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 } />
<Code>{ sourceCode }</Code>
</div>

View File

@@ -0,0 +1,88 @@
/* eslint no-alert: 0 */
/* eslint consistent-return: 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'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price'
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
class AdvSelectionManagment extends React.Component {
handleOnSelect = (row, isSelect) => {
if (isSelect && row.id < 3) {
alert('Oops, You can not select Product ID which less than 3');
return false; // return false to deny current select action
}
return true; // return true or dont return to approve current select action
}
handleOnSelectAll = (isSelect, rows) => {
if (isSelect) {
return rows.filter(r => r.id >= 3).map(r => r.id);
}
}
render() {
const selectRow = {
mode: 'checkbox',
clickToSelect: true,
onSelect: this.handleOnSelect,
onSelectAll: this.handleOnSelectAll
};
return (
<div>
<h3>You can not select Product ID less than 3</h3>
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow } />
<Code>{ sourceCode }</Code>
</div>
);
}
}
`;
export default class AdvSelectionManagment extends React.Component {
handleOnSelect = (row, isSelect) => {
if (isSelect && row.id < 3) {
alert('Oops, You can not select Product ID which less than 3');
return false; // return false to deny current select action
}
return true; // return true or dont return to approve current select action
}
handleOnSelectAll = (isSelect, rows) => {
if (isSelect) {
return rows.filter(r => r.id >= 3).map(r => r.id);
}
}
render() {
const selectRow = {
mode: 'checkbox',
clickToSelect: true,
onSelect: this.handleOnSelect,
onSelectAll: this.handleOnSelectAll
};
return (
<div>
<h3>You can not select Product ID less than 3</h3>
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow } />
<Code>{ sourceCode }</Code>
</div>
);
}
}

View File

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

View File

@@ -55,6 +55,7 @@ import CustomFilterValue from 'examples/column-filter/custom-filter-value';
import SelectFilter from 'examples/column-filter/select-filter';
import SelectFilterWithDefaultValue from 'examples/column-filter/select-filter-default-value';
import SelectFilterComparator from 'examples/column-filter/select-filter-like-comparator';
import SelectFilterWithPreservedOptionsOrder from 'examples/column-filter/select-filter-preserve-option-order';
import CustomSelectFilter from 'examples/column-filter/custom-select-filter';
import MultiSelectFilter from 'examples/column-filter/multi-select-filter';
import MultiSelectFilterDefaultValue from 'examples/column-filter/multi-select-filter-default-value';
@@ -97,7 +98,9 @@ import RowLevelEditableTable from 'examples/cell-edit/row-level-editable-table';
import ColumnLevelEditableTable from 'examples/cell-edit/column-level-editable-table';
import CellLevelEditable from 'examples/cell-edit/cell-level-editable-table';
import CellEditHooks from 'examples/cell-edit/cell-edit-hooks-table';
import AsyncCellEditHooks from 'examples/cell-edit/cell-edit-async-hooks-table';
import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
import AsyncCellEditValidator from 'examples/cell-edit/cell-edit-async-validator-table';
import CellEditStyleTable from 'examples/cell-edit/cell-edit-style-table';
import CellEditClassTable from 'examples/cell-edit/cell-edit-class-table';
import AutoSelectTextInput from 'examples/cell-edit/auto-select-text-input-table';
@@ -116,6 +119,7 @@ import MultipleSelectionTable from 'examples/row-selection/multiple-selection';
import ClickToSelectTable from 'examples/row-selection/click-to-select';
import DefaultSelectTable from 'examples/row-selection/default-select';
import SelectionManagement from 'examples/row-selection/selection-management';
import AdvanceSelectionManagement from 'examples/row-selection/selection-advance-management';
import ClickToSelectWithCellEditTable from 'examples/row-selection/click-to-select-with-cell-edit';
import SelectionWithExpansionTable from 'examples/row-selection/selection-with-expansion';
import SelectionNoDataTable from 'examples/row-selection/selection-no-data';
@@ -260,6 +264,7 @@ storiesOf('Column Filter', module)
.add('Programmatically Multi Select Filter', () => <ProgrammaticallyMultiSelectFilter />)
.add('Custom Filter', () => <CustomFilter />)
.add('Advance Custom Filter', () => <AdvanceCustomFilter />)
.add('Preserved Option Order on Select Filter', () => <SelectFilterWithPreservedOptionsOrder />)
.add('Clear All Filters', () => <ClearAllFilters />);
storiesOf('Work on Rows', module)
@@ -288,7 +293,9 @@ storiesOf('Cell Editing', module)
.add('Column Level Editable', () => <ColumnLevelEditableTable />)
.add('Cell Level Editable', () => <CellLevelEditable />)
.add('Rich Hook Functions', () => <CellEditHooks />)
.add('Async Hook Functions', () => <AsyncCellEditHooks />)
.add('Validation', () => <CellEditValidator />)
.add('Async Validation', () => <AsyncCellEditValidator />)
.add('Auto Select Text Input', () => <AutoSelectTextInput />)
.add('Custom Cell Style', () => <CellEditStyleTable />)
.add('Custom Cell Classes', () => <CellEditClassTable />)
@@ -308,6 +315,7 @@ storiesOf('Row Selection', module)
.add('Click to Select', () => <ClickToSelectTable />)
.add('Default Select', () => <DefaultSelectTable />)
.add('Selection Management', () => <SelectionManagement />)
.add('Advance Selection Management', () => <AdvanceSelectionManagement />)
.add('Click to Select and Edit Cell', () => <ClickToSelectWithCellEditTable />)
.add('Row Select and Expand', () => <SelectionWithExpansionTable />)
.add('Selection without Data', () => <SelectionNoDataTable />)

View File

@@ -115,6 +115,27 @@ const qualityFilter = selectFilter({
// omit...
```
> Note, the selectOptions can be an array also:
```js
const selectOptions = [
{ label: 0, value: 'good' },
{ label: 1, value: 'Bad' },
{ label: 2, value: 'unknown' }
];
const columns = [
..., {
dataField: 'quality',
text: 'Product Quailty',
formatter: cell => selectOptions.find(opt => opt.label === cell).value,
filter: selectFilter({
options: selectOptions
})
}];
```
The benifit is `react-bootstrap-table2` will render the select options by the order of array.
## MultiSelect Filter
A quick example:

View File

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

View File

@@ -7,6 +7,14 @@ import { LIKE, EQ } from '../comparison';
import { FILTER_TYPE } from '../const';
function optionsEquals(currOpts, prevOpts) {
if (Array.isArray(currOpts)) {
for (let i = 0; i < currOpts.length; i += 1) {
if (currOpts[i].label !== prevOpts[i].label) {
return false;
}
}
return currOpts.length === prevOpts.length;
}
const keys = Object.keys(currOpts);
for (let i = 0; i < keys.length; i += 1) {
if (currOpts[keys[i]] !== prevOpts[keys[i]]) {
@@ -16,11 +24,21 @@ function optionsEquals(currOpts, prevOpts) {
return Object.keys(currOpts).length === Object.keys(prevOpts).length;
}
function getOptionValue(options, key) {
if (Array.isArray(options)) {
const result = options
.filter(({ label }) => label === key)
.map(({ value }) => value);
return result[0];
}
return options[key];
}
class SelectFilter extends Component {
constructor(props) {
super(props);
this.filter = this.filter.bind(this);
const isSelected = props.options[props.defaultValue] !== undefined;
const isSelected = getOptionValue(props.options, props.defaultValue) !== undefined;
this.state = { isSelected };
}
@@ -66,9 +84,14 @@ class SelectFilter extends Component {
<option key="-1" value="">{ placeholder || `Select ${column.text}...` }</option>
));
}
if (Array.isArray(options)) {
options.forEach(({ value, label }) =>
optionTags.push(<option key={ label } value={ label }>{ value }</option>));
} else {
Object.keys(options).forEach(key =>
optionTags.push(<option key={ key } value={ key }>{ options[key] }</option>)
);
}
return optionTags;
}
@@ -128,7 +151,7 @@ class SelectFilter extends Component {
SelectFilter.propTypes = {
onFilter: PropTypes.func.isRequired,
column: PropTypes.object.isRequired,
options: PropTypes.object.isRequired,
options: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
comparator: PropTypes.oneOf([LIKE, EQ]),
placeholder: PropTypes.string,
style: PropTypes.object,

View File

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

View File

@@ -15,13 +15,12 @@ class BootstrapTable extends PropsBaseResolver(Component) {
super(props);
this.validateProps();
if (props.registerExposedAPI) {
const getData = () => this.getData();
props.registerExposedAPI(getData);
props.registerExposedAPI(this.getData);
}
}
// Exposed APIs
getData = () => {
getData() {
return this.props.data;
}

View File

@@ -7,17 +7,16 @@ const events = [
];
export default ExtendBase =>
class RowEventDelegater extends ExtendBase {
class CellEventDelegater extends ExtendBase {
constructor(props) {
super(props);
this.clickNum = 0;
this.createDefaultEventHandler = this.createDefaultEventHandler.bind(this);
}
createDefaultEventHandler(cb) {
return (e) => {
const { row, rowIndex } = this.props;
cb(e, row, rowIndex);
const { column, columnIndex } = this.props;
cb(e, column, columnIndex);
};
}

View File

@@ -2,9 +2,10 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import eventDelegater from './cell-event-delegater';
import _ from './utils';
class Cell extends Component {
class Cell extends eventDelegater(Component) {
constructor(props) {
super(props);
this.handleEditingCell = this.handleEditingCell.bind(this);
@@ -73,7 +74,7 @@ class Cell extends Component {
formatter,
formatExtraData
} = column;
const attrs = { ...rest };
const attrs = this.delegate({ ...rest });
let content = column.isDummyField ? null : _.get(row, dataField);
if (formatter) {

View File

@@ -43,6 +43,13 @@ class SelectionProvider extends React.Component {
let currSelected = [...this.state.selected];
this.setState(() => {
let result = true;
if (onSelect) {
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
result = onSelect(row, checked, rowIndex, e);
}
if (result === true || result === undefined) {
if (mode === ROW_SELECT_SINGLE) { // when select mode is radio
currSelected = [rowKey];
} else if (checked) { // when select mode is checkbox
@@ -50,13 +57,9 @@ class SelectionProvider extends React.Component {
} else {
currSelected = currSelected.filter(value => value !== rowKey);
}
if (onSelect) {
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
onSelect(row, checked, rowIndex, e);
}
this.setState(() => ({ selected: currSelected }));
return { selected: currSelected };
});
}
handleAllRowsSelect = (e, isUnSelect) => {
@@ -78,8 +81,10 @@ class SelectionProvider extends React.Component {
currSelected = selected.filter(s => typeof data.find(d => d[keyField] === s) === 'undefined');
}
this.setState(() => {
let result;
if (onSelectAll) {
onSelectAll(
result = onSelectAll(
!isUnSelect,
dataOperator.getSelectedRows(
data,
@@ -88,9 +93,12 @@ class SelectionProvider extends React.Component {
),
e
);
if (Array.isArray(result)) {
currSelected = result;
}
this.setState(() => ({ selected: currSelected }));
}
return { selected: currSelected };
});
}
render() {

View File

@@ -50,13 +50,21 @@ export default class RowPureContent extends React.Component {
// render cell
let cellTitle;
let cellStyle = {};
const cellAttrs = {
let cellAttrs = {
..._.isFunction(column.attrs)
? column.attrs(content, row, rowIndex, index)
: column.attrs,
...column.events
: column.attrs
};
if (column.events) {
const events = Object.assign({}, column.events);
Object.keys(Object.assign({}, column.events)).forEach((key) => {
const originFn = events[key];
events[key] = (...rest) => originFn(...rest, row, rowIndex);
});
cellAttrs = { ...cellAttrs, ...events };
}
const cellClasses = _.isFunction(column.classes)
? column.classes(content, row, rowIndex, index)
: column.classes;