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 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 CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
|
||||
|
||||
@ -94,4 +95,5 @@ storiesOf('Cell Editing', module)
|
||||
.add('Row Level Editable', () => <RowLevelEditableTable />)
|
||||
.add('Column Level Editable', () => <ColumnLevelEditableTable />)
|
||||
.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;
|
||||
|
||||
const setEditMode = () => {
|
||||
if (editMode === Const.CLICK_TO_CELL_EDIT) {
|
||||
cellAttrs.onClick = this.handleEditingCell;
|
||||
} else {
|
||||
cellAttrs.onDoubleClick = this.handleEditingCell;
|
||||
}
|
||||
};
|
||||
|
||||
if (style) {
|
||||
cellStyle = _.isFunction(style) ? style(content, row, rowIndex, columnIndex) : style;
|
||||
}
|
||||
@ -85,13 +93,8 @@ class Cell extends Component {
|
||||
if (cellClasses) cellAttrs.className = cellClasses;
|
||||
|
||||
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
|
||||
|
||||
if (editable && editMode !== Const.UNABLE_TO_CELL_EDIT) {
|
||||
if (editMode === Const.CLICK_TO_CELL_EDIT) { // click to edit
|
||||
cellAttrs.onClick = this.handleEditingCell;
|
||||
} else { // dbclick to edit
|
||||
cellAttrs.onDoubleClick = this.handleEditingCell;
|
||||
}
|
||||
setEditMode();
|
||||
}
|
||||
return (
|
||||
<td { ...cellAttrs }>{ content }</td>
|
||||
|
||||
@ -100,7 +100,7 @@ HeaderCell.propTypes = {
|
||||
align: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
||||
sort: PropTypes.bool,
|
||||
sortFunc: PropTypes.func,
|
||||
editable: PropTypes.bool,
|
||||
editable: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
|
||||
validator: PropTypes.func
|
||||
}).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>
|
||||
{
|
||||
columns.map((column, index) => {
|
||||
const { dataField } = column;
|
||||
const content = _.get(row, dataField);
|
||||
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) {
|
||||
return (
|
||||
<EditingCell
|
||||
key={ _.get(row, column.dataField) }
|
||||
key={ content }
|
||||
row={ row }
|
||||
column={ column }
|
||||
{ ...rest }
|
||||
@ -40,7 +45,7 @@ const Row = (props) => {
|
||||
}
|
||||
return (
|
||||
<Cell
|
||||
key={ _.get(row, column.dataField) }
|
||||
key={ content }
|
||||
row={ row }
|
||||
rowIndex={ rowIndex }
|
||||
columnIndex={ index }
|
||||
|
||||
@ -4,10 +4,13 @@ import sinon from 'sinon';
|
||||
import { shallow, mount } from 'enzyme';
|
||||
|
||||
import { TableRowWrapper } from './test-helpers/table-wrapper';
|
||||
import BootstrapTable from '../src/bootstrap-table';
|
||||
import EditingCell from '../src/editing-cell';
|
||||
import TextEditor from '../src/text-editor';
|
||||
import EditorIndicator from '../src/editor-indicator';
|
||||
|
||||
import { productsGenerator } from './test-helpers/productGenerator';
|
||||
import Row from '../src/row';
|
||||
import Cell from '../src/cell';
|
||||
|
||||
describe('EditingCell', () => {
|
||||
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