mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-07-01 06:30:11 +00:00
@@ -417,9 +417,20 @@ A new `Object` will be the result of element headerAttrs.
|
||||
> Same as [column.attrs](#attrs), it has lower priority and will be
|
||||
> overwrited when other props related to HTML attributes were given.
|
||||
|
||||
## <a name='editable'>column.editable - [Bool]</a>
|
||||
## <a name='editable'>column.editable - [Bool | Function]</a>
|
||||
`column.editable` default is true, means every column is editable if you configure [`cellEdit`](./README.md#cellEdit). But you can disable some columns editable via setting `false`.
|
||||
|
||||
If a callback function given, you can control the editable level as cell level:
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
editable: (cell, row, rowIndex, colIndex) => {
|
||||
// return true or false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## <a name='validator'>column.validator - [Function]</a>
|
||||
`column.validator` used for validate the data when cell on updating. it's should accept a callback function with following argument:
|
||||
`newValue`, `row` and `column`:
|
||||
|
||||
@@ -94,6 +94,6 @@ storiesOf('Cell Editing', module)
|
||||
.add('Blur to Save Cell', () => <BlurToSaveTable />)
|
||||
.add('Row Level Editable', () => <RowLevelEditableTable />)
|
||||
.add('Column Level Editable', () => <ColumnLevelEditableTable />)
|
||||
.add('Cell Level Editable', () => <CellLevelEditable />)
|
||||
.add('Rich Hook Functions', () => <CellEditHooks />)
|
||||
.add('Validation', () => <CellEditValidator />)
|
||||
.add('Cell Level Editable', () => <CellLevelEditable />);
|
||||
.add('Validation', () => <CellEditValidator />);
|
||||
|
||||
14
packages/react-bootstrap-table2/src/cell.js
vendored
14
packages/react-bootstrap-table2/src/cell.js
vendored
@@ -60,14 +60,6 @@ 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;
|
||||
}
|
||||
@@ -94,7 +86,11 @@ class Cell extends Component {
|
||||
|
||||
if (!_.isEmptyObject(cellStyle)) cellAttrs.style = cellStyle;
|
||||
if (editable && editMode !== Const.UNABLE_TO_CELL_EDIT) {
|
||||
setEditMode();
|
||||
if (editMode === Const.CLICK_TO_CELL_EDIT) {
|
||||
cellAttrs.onClick = this.handleEditingCell;
|
||||
} else {
|
||||
cellAttrs.onDoubleClick = this.handleEditingCell;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<td { ...cellAttrs }>{ content }</td>
|
||||
|
||||
@@ -4,13 +4,9 @@ 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;
|
||||
@@ -173,34 +169,4 @@ 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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -86,7 +86,7 @@ describe('Row', () => {
|
||||
}
|
||||
});
|
||||
|
||||
describe('when have column.editable defined false', () => {
|
||||
describe('and column.editable defined false', () => {
|
||||
const nonEditableColIndex = 1;
|
||||
beforeEach(() => {
|
||||
columns[nonEditableColIndex].editable = false;
|
||||
@@ -101,7 +101,7 @@ describe('Row', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Cell component should receive correct editMode props', () => {
|
||||
it('Cell component should receive correct editable props', () => {
|
||||
expect(wrapper.length).toBe(1);
|
||||
for (let i = 0; i < columns.length; i += 1) {
|
||||
const column = columns[i];
|
||||
@@ -114,6 +114,79 @@ describe('Row', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('and column.editable defined as function', () => {
|
||||
const nonEditableColIndex = 1;
|
||||
let editableCallBack;
|
||||
|
||||
afterEach(() => {
|
||||
editableCallBack.reset();
|
||||
});
|
||||
|
||||
describe('which return false', () => {
|
||||
beforeEach(() => {
|
||||
editableCallBack = sinon.stub().returns(false);
|
||||
columns[nonEditableColIndex].editable = editableCallBack;
|
||||
wrapper = shallow(
|
||||
<Row
|
||||
row={ row }
|
||||
rowIndex={ rowIndex }
|
||||
columns={ columns }
|
||||
keyField={ keyField }
|
||||
cellEdit={ cellEdit }
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
it('column.editable callback function should be called once', () => {
|
||||
expect(editableCallBack.callCount).toBe(1);
|
||||
});
|
||||
|
||||
it('Cell component should receive correct editable props', () => {
|
||||
expect(wrapper.length).toBe(1);
|
||||
for (let i = 0; i < columns.length; i += 1) {
|
||||
const column = columns[i];
|
||||
if (i === nonEditableColIndex || column.dataField === keyField) {
|
||||
expect(wrapper.find(Cell).get(i).props.editable).toBeFalsy();
|
||||
} else {
|
||||
expect(wrapper.find(Cell).get(i).props.editable).toBeTruthy();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('which return true', () => {
|
||||
beforeEach(() => {
|
||||
editableCallBack = sinon.stub().returns(true);
|
||||
columns[nonEditableColIndex].editable = editableCallBack;
|
||||
wrapper = shallow(
|
||||
<Row
|
||||
row={ row }
|
||||
rowIndex={ rowIndex }
|
||||
columns={ columns }
|
||||
keyField={ keyField }
|
||||
cellEdit={ cellEdit }
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
it('column.editable callback function should be called once', () => {
|
||||
expect(editableCallBack.callCount).toBe(1);
|
||||
});
|
||||
|
||||
it('Cell component should receive correct editable props', () => {
|
||||
expect(wrapper.length).toBe(1);
|
||||
for (let i = 0; i < columns.length; i += 1) {
|
||||
const column = columns[i];
|
||||
if (column.dataField === keyField) {
|
||||
expect(wrapper.find(Cell).get(i).props.editable).toBeFalsy();
|
||||
} else {
|
||||
expect(wrapper.find(Cell).get(i).props.editable).toBeTruthy();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Means user defined cellEdit.nonEditableRows
|
||||
// and some rows will be treated as noneditable by this rules
|
||||
describe('when editable prop is false', () => {
|
||||
|
||||
Reference in New Issue
Block a user