mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2025-10-16 11:55:39 +00:00
fix #66
This commit is contained in:
parent
c2e22d5710
commit
94d21fee77
55
packages/react-bootstrap-table2-example/examples/cell-edit/cell-level-editable-table.js
vendored
Normal file
55
packages/react-bootstrap-table2-example/examples/cell-edit/cell-level-editable-table.js
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* eslint no-unused-vars: 0 */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { BootstrapTableful } from 'react-bootstrap-table2';
|
||||||
|
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',
|
||||||
|
editable: (content, row, rowIndex, columnIndex) => content > 2101
|
||||||
|
}];
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
editable: (content, row, rowIndex, columnIndex) => content > 2101
|
||||||
|
}];
|
||||||
|
|
||||||
|
const cellEdit = {
|
||||||
|
mode: 'click'
|
||||||
|
};
|
||||||
|
|
||||||
|
<BootstrapTableful
|
||||||
|
keyField='id'
|
||||||
|
data={ products }
|
||||||
|
columns={ columns }
|
||||||
|
cellEdit={ cellEdit }
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const cellEdit = {
|
||||||
|
mode: 'click'
|
||||||
|
};
|
||||||
|
export default () => (
|
||||||
|
<div>
|
||||||
|
<BootstrapTableful keyField="id" data={ products } columns={ columns } cellEdit={ cellEdit } />
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@ -41,6 +41,7 @@ import DoubleClickToEditTable from 'examples/cell-edit/dbclick-to-edit-table';
|
|||||||
import BlurToSaveTable from 'examples/cell-edit/blur-to-save-table';
|
import BlurToSaveTable from 'examples/cell-edit/blur-to-save-table';
|
||||||
import RowLevelEditableTable from 'examples/cell-edit/row-level-editable-table';
|
import RowLevelEditableTable from 'examples/cell-edit/row-level-editable-table';
|
||||||
import ColumnLevelEditableTable from 'examples/cell-edit/column-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 CellEditHooks from 'examples/cell-edit/cell-edit-hooks-table';
|
||||||
import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
|
import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
|
||||||
|
|
||||||
@ -94,4 +95,5 @@ storiesOf('Cell Editing', module)
|
|||||||
.add('Row Level Editable', () => <RowLevelEditableTable />)
|
.add('Row Level Editable', () => <RowLevelEditableTable />)
|
||||||
.add('Column Level Editable', () => <ColumnLevelEditableTable />)
|
.add('Column Level Editable', () => <ColumnLevelEditableTable />)
|
||||||
.add('Rich Hook Functions', () => <CellEditHooks />)
|
.add('Rich Hook Functions', () => <CellEditHooks />)
|
||||||
.add('Validation', () => <CellEditValidator />);
|
.add('Validation', () => <CellEditValidator />)
|
||||||
|
.add('Cell Level Editable', () => <CellLevelEditable />);
|
||||||
|
|||||||
15
packages/react-bootstrap-table2/src/cell.js
vendored
15
packages/react-bootstrap-table2/src/cell.js
vendored
@ -60,6 +60,14 @@ class Cell extends Component {
|
|||||||
? classes(content, row, rowIndex, columnIndex)
|
? classes(content, row, rowIndex, columnIndex)
|
||||||
: classes;
|
: classes;
|
||||||
|
|
||||||
|
const setEditMode = () => {
|
||||||
|
if (editMode === Const.CLICK_TO_CELL_EDIT) {
|
||||||
|
cellAttrs.onClick = this.handleEditingCell;
|
||||||
|
} else {
|
||||||
|
cellAttrs.onDoubleClick = this.handleEditingCell;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (style) {
|
if (style) {
|
||||||
cellStyle = _.isFunction(style) ? style(content, row, rowIndex, columnIndex) : style;
|
cellStyle = _.isFunction(style) ? style(content, row, rowIndex, columnIndex) : style;
|
||||||
}
|
}
|
||||||
@ -85,13 +93,8 @@ class Cell extends Component {
|
|||||||
if (cellClasses) cellAttrs.className = cellClasses;
|
if (cellClasses) cellAttrs.className = cellClasses;
|
||||||
|
|
||||||
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
|
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
|
||||||
|
|
||||||
if (editable && editMode !== Const.UNABLE_TO_CELL_EDIT) {
|
if (editable && editMode !== Const.UNABLE_TO_CELL_EDIT) {
|
||||||
if (editMode === Const.CLICK_TO_CELL_EDIT) { // click to edit
|
setEditMode();
|
||||||
cellAttrs.onClick = this.handleEditingCell;
|
|
||||||
} else { // dbclick to edit
|
|
||||||
cellAttrs.onDoubleClick = this.handleEditingCell;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<td { ...cellAttrs }>{ content }</td>
|
<td { ...cellAttrs }>{ content }</td>
|
||||||
|
|||||||
@ -100,7 +100,7 @@ HeaderCell.propTypes = {
|
|||||||
align: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
align: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
||||||
sort: PropTypes.bool,
|
sort: PropTypes.bool,
|
||||||
sortFunc: PropTypes.func,
|
sortFunc: PropTypes.func,
|
||||||
editable: PropTypes.bool,
|
editable: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
||||||
validator: PropTypes.func
|
validator: PropTypes.func
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
index: PropTypes.number.isRequired,
|
index: PropTypes.number.isRequired,
|
||||||
|
|||||||
11
packages/react-bootstrap-table2/src/row.js
vendored
11
packages/react-bootstrap-table2/src/row.js
vendored
@ -26,12 +26,17 @@ const Row = (props) => {
|
|||||||
<tr>
|
<tr>
|
||||||
{
|
{
|
||||||
columns.map((column, index) => {
|
columns.map((column, index) => {
|
||||||
|
const { dataField } = column;
|
||||||
|
const content = _.get(row, dataField);
|
||||||
let editable = _.isDefined(column.editable) ? column.editable : true;
|
let editable = _.isDefined(column.editable) ? column.editable : true;
|
||||||
if (column.dataField === keyField || !editableRow) editable = false;
|
if (dataField === keyField || !editableRow) editable = false;
|
||||||
|
if (_.isFunction(column.editable)) {
|
||||||
|
editable = column.editable(content, row, rowIndex, index);
|
||||||
|
}
|
||||||
if (rowIndex === editingRowIdx && index === editingColIdx) {
|
if (rowIndex === editingRowIdx && index === editingColIdx) {
|
||||||
return (
|
return (
|
||||||
<EditingCell
|
<EditingCell
|
||||||
key={ _.get(row, column.dataField) }
|
key={ content }
|
||||||
row={ row }
|
row={ row }
|
||||||
column={ column }
|
column={ column }
|
||||||
{ ...rest }
|
{ ...rest }
|
||||||
@ -40,7 +45,7 @@ const Row = (props) => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Cell
|
<Cell
|
||||||
key={ _.get(row, column.dataField) }
|
key={ content }
|
||||||
row={ row }
|
row={ row }
|
||||||
rowIndex={ rowIndex }
|
rowIndex={ rowIndex }
|
||||||
columnIndex={ index }
|
columnIndex={ index }
|
||||||
|
|||||||
@ -4,10 +4,13 @@ import sinon from 'sinon';
|
|||||||
import { shallow, mount } from 'enzyme';
|
import { shallow, mount } from 'enzyme';
|
||||||
|
|
||||||
import { TableRowWrapper } from './test-helpers/table-wrapper';
|
import { TableRowWrapper } from './test-helpers/table-wrapper';
|
||||||
|
import BootstrapTable from '../src/bootstrap-table';
|
||||||
import EditingCell from '../src/editing-cell';
|
import EditingCell from '../src/editing-cell';
|
||||||
import TextEditor from '../src/text-editor';
|
import TextEditor from '../src/text-editor';
|
||||||
import EditorIndicator from '../src/editor-indicator';
|
import EditorIndicator from '../src/editor-indicator';
|
||||||
|
import { productsGenerator } from './test-helpers/productGenerator';
|
||||||
|
import Row from '../src/row';
|
||||||
|
import Cell from '../src/cell';
|
||||||
|
|
||||||
describe('EditingCell', () => {
|
describe('EditingCell', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
@ -170,4 +173,34 @@ describe('EditingCell', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when column.editable is function', () => {
|
||||||
|
const products = productsGenerator();
|
||||||
|
const mockFunction = jest.fn(content => content > 2102);
|
||||||
|
const col = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}, {
|
||||||
|
dataField: 'price',
|
||||||
|
text: 'Product Price',
|
||||||
|
editable: mockFunction
|
||||||
|
}];
|
||||||
|
const renderComponent = mount(<BootstrapTable keyField="id" data={ products } columns={ col } />);
|
||||||
|
const rowComponent = renderComponent.find(Row);
|
||||||
|
it(`column.editable function should be called ${products.length} times`, () => {
|
||||||
|
expect(mockFunction).toHaveBeenCalledTimes(products.length);
|
||||||
|
});
|
||||||
|
it('should call callBack with right args', () => {
|
||||||
|
expect(mockFunction).toHaveBeenLastCalledWith(2104, { id: 4, name: 'Item name 4', price: 2104 }, 4, 2);
|
||||||
|
});
|
||||||
|
it('should be "editable" === false', () => {
|
||||||
|
expect(rowComponent.at(2).find(Cell).at(2).props().editable).toBeFalsy();
|
||||||
|
});
|
||||||
|
it('should be "editable" === true', () => {
|
||||||
|
expect(rowComponent.at(3).find(Cell).at(2).props().editable).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
21
packages/react-bootstrap-table2/test/test-helpers/productGenerator.js
vendored
Normal file
21
packages/react-bootstrap-table2/test/test-helpers/productGenerator.js
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* products generator for stories
|
||||||
|
*
|
||||||
|
* @param {Number} quantity - quantity of products
|
||||||
|
* @param {Function} callback - callback func which is similiar to 'mapFunction'
|
||||||
|
* aims to customize product format
|
||||||
|
*
|
||||||
|
* @return {Array} - products array
|
||||||
|
*/
|
||||||
|
export const productsGenerator = (quantity = 5, callback) => {
|
||||||
|
if (callback) return Array.from({ length: quantity }, callback);
|
||||||
|
|
||||||
|
// if no given callback, retrun default product format.
|
||||||
|
return (
|
||||||
|
Array.from({ length: quantity }, (value, index) => ({
|
||||||
|
id: index,
|
||||||
|
name: `Item name ${index}`,
|
||||||
|
price: 2100 + index
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user