Skip to content

Commit 92f1449

Browse files
committed
fix #1004
1 parent 46258b0 commit 92f1449

File tree

9 files changed

+169
-7
lines changed

9 files changed

+169
-7
lines changed

docs/columns.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Available properties in a column object:
1111
* [hidden](#hidden)
1212
* [formatter](#formatter)
1313
* [formatExtraData](#formatExtraData)
14+
* [type](#type)
1415
* [sort](#sort)
1516
* [sortFunc](#sortFunc)
1617
* [sortCaret](#sortCaret)
@@ -132,6 +133,10 @@ The third argument: `components` have following specified properties:
132133
## <a name='formatExtraData'>column.formatExtraData - [Any]</a>
133134
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.
134135

136+
## <a name='type'>column.type - [String]</a>
137+
Specify the data type on column. Available value so far is `string`, `number`, `bool` and `date`. Default is `string`.
138+
`column.type` can be used when you enable the cell editing and want to save your cell data with correct data type.
139+
135140
## <a name='sort'>column.sort - [Bool]</a>
136141
Enable the column sort via a `true` value given.
137142

packages/react-bootstrap-table2-editor/src/context.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,21 @@ export default (
5656
}
5757

5858
handleCellUpdate(row, column, newValue) {
59+
const newValueWithType = dataOperator.typeConvert(column.type, newValue);
5960
const { cellEdit } = this.props;
6061
const { beforeSaveCell } = cellEdit.options;
6162
const oldValue = _.get(row, column.dataField);
6263
const beforeSaveCellDone = (result = true) => {
6364
if (result) {
64-
this.doUpdate(row, column, newValue);
65+
this.doUpdate(row, column, newValueWithType);
6566
} else {
6667
this.escapeEditing();
6768
}
6869
};
6970
if (_.isFunction(beforeSaveCell)) {
7071
const result = beforeSaveCell(
7172
oldValue,
72-
newValue,
73+
newValueWithType,
7374
row,
7475
column,
7576
beforeSaveCellDone
@@ -78,7 +79,7 @@ export default (
7879
return;
7980
}
8081
}
81-
this.doUpdate(row, column, newValue);
82+
this.doUpdate(row, column, newValueWithType);
8283
}
8384

8485
doUpdate(row, column, newValue) {
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/* eslint prefer-template: 0 */
2+
import React from 'react';
3+
import BootstrapTable from 'react-bootstrap-table-next';
4+
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
5+
import Code from 'components/common/code-block';
6+
import { stockGenerator } from 'utils/common';
7+
8+
const products = stockGenerator();
9+
10+
const columns = [{
11+
dataField: 'id',
12+
text: 'Stock ID'
13+
}, {
14+
dataField: 'name',
15+
text: 'Stock Name'
16+
}, {
17+
dataField: 'price',
18+
text: 'Price',
19+
type: 'number'
20+
}, {
21+
dataField: 'visible',
22+
text: 'Visible?',
23+
type: 'bool',
24+
editor: {
25+
type: Type.CHECKBOX,
26+
value: 'true:false'
27+
}
28+
}, {
29+
dataField: 'inStockDate',
30+
text: 'Stock Date',
31+
type: 'date',
32+
formatter: (cell) => {
33+
let dateObj = cell;
34+
if (typeof cell !== 'object') {
35+
dateObj = new Date(cell);
36+
}
37+
return `${('0' + dateObj.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
38+
},
39+
editor: {
40+
type: Type.DATE
41+
}
42+
}];
43+
44+
const sourceCode = `\
45+
import BootstrapTable from 'react-bootstrap-table-next';
46+
import cellEditFactory from 'react-bootstrap-table2-editor';
47+
48+
const columns = [{
49+
dataField: 'id',
50+
text: 'Stock ID'
51+
}, {
52+
dataField: 'name',
53+
text: 'Stock Name'
54+
}, {
55+
dataField: 'price',
56+
text: 'Price',
57+
type: 'number'
58+
}, {
59+
dataField: 'visible',
60+
text: 'Visible?',
61+
type: 'bool',
62+
editor: {
63+
type: Type.CHECKBOX,
64+
value: 'true:false'
65+
}
66+
}, {
67+
dataField: 'inStockDate',
68+
text: 'Stock Date',
69+
type: 'date',
70+
formatter: (cell) => {
71+
let dateObj = cell;
72+
if (typeof cell !== 'object') {
73+
dateObj = new Date(cell);
74+
}
75+
return \`$\{('0' + dateObj.getUTCDate()).slice(-2)}/$\{('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/$\{dateObj.getUTCFullYear()}\`;
76+
},
77+
editor: {
78+
type: Type.DATE
79+
}
80+
}];
81+
82+
function afterSaveCell(oldValue, newValue) {
83+
console.log('--after save cell--');
84+
console.log('New Value was apply as');
85+
console.log(newValue);
86+
console.log(\`and the type is $\{typeof newValue}\`);
87+
}
88+
89+
<BootstrapTable
90+
keyField="id"
91+
data={ products }
92+
columns={ columns }
93+
cellEdit={ cellEditFactory({
94+
mode: 'click',
95+
blurToSave: true,
96+
afterSaveCell
97+
}) }
98+
/>
99+
`;
100+
101+
function afterSaveCell(oldValue, newValue) {
102+
console.log('--after save cell--');
103+
console.log('New Value was apply as');
104+
console.log(newValue);
105+
console.log(`and the type is ${typeof newValue}`);
106+
}
107+
108+
export default () => (
109+
<div>
110+
<h3>Save Cell Value with Specified Data Type</h3>
111+
<BootstrapTable
112+
keyField="id"
113+
data={ products }
114+
columns={ columns }
115+
cellEdit={ cellEditFactory({
116+
mode: 'click',
117+
blurToSave: true,
118+
afterSaveCell
119+
}) }
120+
/>
121+
<Code>{ sourceCode }</Code>
122+
</div>
123+
);

packages/react-bootstrap-table2-example/src/utils/common.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ const endDate = new Date();
6969
export const stockGenerator = (quantity = 5) =>
7070
Array.from({ length: quantity }, (value, index) => ({
7171
id: index,
72-
name: `Todo item ${index}`,
72+
name: `Stock Name ${index}`,
7373
price: Math.floor((Math.random() * 2) + 1),
74+
visible: Math.random() > 0.5,
7475
inStockDate:
7576
new Date(startDate.getTime() + Math.random() * (endDate.getTime() - startDate.getTime()))
7677
}));

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ import TextareaEditorTable from 'examples/cell-edit/textarea-editor-table';
131131
import CheckboxEditorTable from 'examples/cell-edit/checkbox-editor-table';
132132
import DateEditorTable from 'examples/cell-edit/date-editor-table';
133133
import CustomEditorTable from 'examples/cell-edit/custom-editor-table';
134+
import CellEditorWithDataType from 'examples/cell-edit/cell-edit-with-data-type';
134135

135136
// work on row selection
136137
import SingleSelectionTable from 'examples/row-selection/single-selection';
@@ -377,7 +378,8 @@ storiesOf('Cell Editing', module)
377378
.add('Textarea Editor', () => <TextareaEditorTable />)
378379
.add('Checkbox Editor', () => <CheckboxEditorTable />)
379380
.add('Date Editor', () => <DateEditorTable />)
380-
.add('Custom Editor', () => <CustomEditorTable />);
381+
.add('Custom Editor', () => <CustomEditorTable />)
382+
.add('Cell Editor with Data Type', () => <CellEditorWithDataType />);
381383

382384
storiesOf('Row Selection', module)
383385
.addDecorator(bootstrapStyle())

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,9 @@ export default {
88
CHECKBOX_STATUS_INDETERMINATE: 'indeterminate',
99
CHECKBOX_STATUS_UNCHECKED: 'unchecked',
1010
INDICATOR_POSITION_LEFT: 'left',
11-
INDICATOR_POSITION_RIGHT: 'right'
11+
INDICATOR_POSITION_RIGHT: 'right',
12+
TYPE_STRING: 'string',
13+
TYPE_NUMBER: 'number',
14+
TYPE_BOOLEAN: 'bool',
15+
TYPE_DATE: 'date'
1216
};

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ HeaderCell.propTypes = {
117117
column: PropTypes.shape({
118118
dataField: PropTypes.string.isRequired,
119119
text: PropTypes.string.isRequired,
120+
type: PropTypes.oneOf([
121+
Const.TYPE_STRING,
122+
Const.TYPE_NUMBER,
123+
Const.TYPE_BOOLEAN,
124+
Const.TYPE_DATE
125+
]),
120126
isDummyField: PropTypes.bool,
121127
hidden: PropTypes.bool,
122128
headerFormatter: PropTypes.func,

packages/react-bootstrap-table2/src/store/operators.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ import * as selection from './selection';
33
import * as expand from './expand';
44
import * as mutate from './mutate';
55
import * as sort from './sort';
6+
import * as type from './type';
67

78
export default {
89
...rows,
910
...selection,
1011
...expand,
1112
...mutate,
12-
...sort
13+
...sort,
14+
...type
1315
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Const from '../const';
2+
3+
export const typeConvert = (type, value) => {
4+
if (!type || type === Const.TYPE_STRING) {
5+
return String(value);
6+
} else if (type === Const.TYPE_NUMBER) {
7+
return Number(value);
8+
} else if (type === Const.TYPE_BOOLEAN) {
9+
if (typeof value === 'boolean') {
10+
return value;
11+
}
12+
return value === 'true';
13+
} else if (type === Const.TYPE_DATE) {
14+
return new Date(value);
15+
}
16+
return value;
17+
};
18+

0 commit comments

Comments
 (0)