Skip to content

Commit 94d21fe

Browse files
khaninDAllenFang
authored andcommitted
fix #66
1 parent c2e22d5 commit 94d21fe

File tree

7 files changed

+131
-12
lines changed

7 files changed

+131
-12
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* eslint no-unused-vars: 0 */
2+
import React from 'react';
3+
4+
import { BootstrapTableful } from 'react-bootstrap-table2';
5+
import Code from 'components/common/code-block';
6+
import { productsGenerator } from 'utils/common';
7+
8+
const products = productsGenerator();
9+
10+
const columns = [{
11+
dataField: 'id',
12+
text: 'Product ID'
13+
}, {
14+
dataField: 'name',
15+
text: 'Product Name'
16+
}, {
17+
dataField: 'price',
18+
text: 'Product Price',
19+
editable: (content, row, rowIndex, columnIndex) => content > 2101
20+
}];
21+
22+
const sourceCode = `\
23+
const columns = [{
24+
dataField: 'id',
25+
text: 'Product ID'
26+
}, {
27+
dataField: 'name',
28+
text: 'Product Name'
29+
}, {
30+
dataField: 'price',
31+
text: 'Product Price',
32+
editable: (content, row, rowIndex, columnIndex) => content > 2101
33+
}];
34+
35+
const cellEdit = {
36+
mode: 'click'
37+
};
38+
39+
<BootstrapTableful
40+
keyField='id'
41+
data={ products }
42+
columns={ columns }
43+
cellEdit={ cellEdit }
44+
/>
45+
`;
46+
47+
const cellEdit = {
48+
mode: 'click'
49+
};
50+
export default () => (
51+
<div>
52+
<BootstrapTableful keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
53+
<Code>{ sourceCode }</Code>
54+
</div>
55+
);

packages/react-bootstrap-table2-example/stories/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import DoubleClickToEditTable from 'examples/cell-edit/dbclick-to-edit-table';
4141
import BlurToSaveTable from 'examples/cell-edit/blur-to-save-table';
4242
import RowLevelEditableTable from 'examples/cell-edit/row-level-editable-table';
4343
import ColumnLevelEditableTable from 'examples/cell-edit/column-level-editable-table';
44+
import CellLevelEditable from 'examples/cell-edit/cell-level-editable-table';
4445
import CellEditHooks from 'examples/cell-edit/cell-edit-hooks-table';
4546
import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
4647

@@ -94,4 +95,5 @@ storiesOf('Cell Editing', module)
9495
.add('Row Level Editable', () => <RowLevelEditableTable />)
9596
.add('Column Level Editable', () => <ColumnLevelEditableTable />)
9697
.add('Rich Hook Functions', () => <CellEditHooks />)
97-
.add('Validation', () => <CellEditValidator />);
98+
.add('Validation', () => <CellEditValidator />)
99+
.add('Cell Level Editable', () => <CellLevelEditable />);

packages/react-bootstrap-table2/src/cell.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ class Cell extends Component {
6060
? classes(content, row, rowIndex, columnIndex)
6161
: classes;
6262

63+
const setEditMode = () => {
64+
if (editMode === Const.CLICK_TO_CELL_EDIT) {
65+
cellAttrs.onClick = this.handleEditingCell;
66+
} else {
67+
cellAttrs.onDoubleClick = this.handleEditingCell;
68+
}
69+
};
70+
6371
if (style) {
6472
cellStyle = _.isFunction(style) ? style(content, row, rowIndex, columnIndex) : style;
6573
}
@@ -85,13 +93,8 @@ class Cell extends Component {
8593
if (cellClasses) cellAttrs.className = cellClasses;
8694

8795
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
88-
8996
if (editable && editMode !== Const.UNABLE_TO_CELL_EDIT) {
90-
if (editMode === Const.CLICK_TO_CELL_EDIT) { // click to edit
91-
cellAttrs.onClick = this.handleEditingCell;
92-
} else { // dbclick to edit
93-
cellAttrs.onDoubleClick = this.handleEditingCell;
94-
}
97+
setEditMode();
9598
}
9699
return (
97100
<td { ...cellAttrs }>{ content }</td>

packages/react-bootstrap-table2/src/header-cell.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ HeaderCell.propTypes = {
100100
align: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
101101
sort: PropTypes.bool,
102102
sortFunc: PropTypes.func,
103-
editable: PropTypes.bool,
103+
editable: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
104104
validator: PropTypes.func
105105
}).isRequired,
106106
index: PropTypes.number.isRequired,

packages/react-bootstrap-table2/src/row.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,17 @@ const Row = (props) => {
2626
<tr>
2727
{
2828
columns.map((column, index) => {
29+
const { dataField } = column;
30+
const content = _.get(row, dataField);
2931
let editable = _.isDefined(column.editable) ? column.editable : true;
30-
if (column.dataField === keyField || !editableRow) editable = false;
32+
if (dataField === keyField || !editableRow) editable = false;
33+
if (_.isFunction(column.editable)) {
34+
editable = column.editable(content, row, rowIndex, index);
35+
}
3136
if (rowIndex === editingRowIdx && index === editingColIdx) {
3237
return (
3338
<EditingCell
34-
key={ _.get(row, column.dataField) }
39+
key={ content }
3540
row={ row }
3641
column={ column }
3742
{ ...rest }
@@ -40,7 +45,7 @@ const Row = (props) => {
4045
}
4146
return (
4247
<Cell
43-
key={ _.get(row, column.dataField) }
48+
key={ content }
4449
row={ row }
4550
rowIndex={ rowIndex }
4651
columnIndex={ index }

packages/react-bootstrap-table2/test/editing-cell.test.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import sinon from 'sinon';
44
import { shallow, mount } from 'enzyme';
55

66
import { TableRowWrapper } from './test-helpers/table-wrapper';
7+
import BootstrapTable from '../src/bootstrap-table';
78
import EditingCell from '../src/editing-cell';
89
import TextEditor from '../src/text-editor';
910
import EditorIndicator from '../src/editor-indicator';
10-
11+
import { productsGenerator } from './test-helpers/productGenerator';
12+
import Row from '../src/row';
13+
import Cell from '../src/cell';
1114

1215
describe('EditingCell', () => {
1316
let wrapper;
@@ -170,4 +173,34 @@ describe('EditingCell', () => {
170173
});
171174
});
172175
});
176+
177+
describe('when column.editable is function', () => {
178+
const products = productsGenerator();
179+
const mockFunction = jest.fn(content => content > 2102);
180+
const col = [{
181+
dataField: 'id',
182+
text: 'Product ID'
183+
}, {
184+
dataField: 'name',
185+
text: 'Product Name'
186+
}, {
187+
dataField: 'price',
188+
text: 'Product Price',
189+
editable: mockFunction
190+
}];
191+
const renderComponent = mount(<BootstrapTable keyField="id" data={ products } columns={ col } />);
192+
const rowComponent = renderComponent.find(Row);
193+
it(`column.editable function should be called ${products.length} times`, () => {
194+
expect(mockFunction).toHaveBeenCalledTimes(products.length);
195+
});
196+
it('should call callBack with right args', () => {
197+
expect(mockFunction).toHaveBeenLastCalledWith(2104, { id: 4, name: 'Item name 4', price: 2104 }, 4, 2);
198+
});
199+
it('should be "editable" === false', () => {
200+
expect(rowComponent.at(2).find(Cell).at(2).props().editable).toBeFalsy();
201+
});
202+
it('should be "editable" === true', () => {
203+
expect(rowComponent.at(3).find(Cell).at(2).props().editable).toBeTruthy();
204+
});
205+
});
173206
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* products generator for stories
3+
*
4+
* @param {Number} quantity - quantity of products
5+
* @param {Function} callback - callback func which is similiar to 'mapFunction'
6+
* aims to customize product format
7+
*
8+
* @return {Array} - products array
9+
*/
10+
export const productsGenerator = (quantity = 5, callback) => {
11+
if (callback) return Array.from({ length: quantity }, callback);
12+
13+
// if no given callback, retrun default product format.
14+
return (
15+
Array.from({ length: quantity }, (value, index) => ({
16+
id: index,
17+
name: `Item name ${index}`,
18+
price: 2100 + index
19+
}))
20+
);
21+
};

0 commit comments

Comments
 (0)