diff --git a/docs/cell-edit.md b/docs/cell-edit.md
index 051dde8..06968c7 100644
--- a/docs/cell-edit.md
+++ b/docs/cell-edit.md
@@ -1,3 +1,10 @@
+# Cell Editing
+Before start to use cell edit, please remember to install `react-bootstrap-table2-editor`
+
+```sh
+$ npm install react-bootstrap-table2-editor --save
+```
+
# Properties on cellEdit prop
* [mode (**required**)](#mode)
* [blurToSave](#blurToSave)
diff --git a/packages/react-bootstrap-table2-editor/package.json b/packages/react-bootstrap-table2-editor/package.json
new file mode 100644
index 0000000..8b7aab8
--- /dev/null
+++ b/packages/react-bootstrap-table2-editor/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "react-bootstrap-table2-editor",
+ "version": "0.0.1",
+ "description": "it's the editor addon for react-bootstrap-table2",
+ "main": "src/index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC"
+}
diff --git a/packages/react-bootstrap-table2-editor/src/const.js b/packages/react-bootstrap-table2-editor/src/const.js
new file mode 100644
index 0000000..acbef9d
--- /dev/null
+++ b/packages/react-bootstrap-table2-editor/src/const.js
@@ -0,0 +1,4 @@
+export const TIME_TO_CLOSE_MESSAGE = 3000;
+export const DELAY_FOR_DBCLICK = 200;
+export const CLICK_TO_CELL_EDIT = 'click';
+export const DBCLICK_TO_CELL_EDIT = 'dbclick';
diff --git a/packages/react-bootstrap-table2-editor/src/editing-cell.js b/packages/react-bootstrap-table2-editor/src/editing-cell.js
new file mode 100644
index 0000000..5e54984
--- /dev/null
+++ b/packages/react-bootstrap-table2-editor/src/editing-cell.js
@@ -0,0 +1,153 @@
+/* eslint react/prop-types: 0 */
+/* eslint no-return-assign: 0 */
+/* eslint class-methods-use-this: 0 */
+/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
+import React, { Component } from 'react';
+import cs from 'classnames';
+import PropTypes from 'prop-types';
+
+import TextEditor from './text-editor';
+import EditorIndicator from './editor-indicator';
+import { TIME_TO_CLOSE_MESSAGE } from './const';
+
+export default _ =>
+ class EditingCell extends Component {
+ static propTypes = {
+ row: PropTypes.object.isRequired,
+ column: PropTypes.object.isRequired,
+ onUpdate: PropTypes.func.isRequired,
+ onEscape: PropTypes.func.isRequired,
+ timeToCloseMessage: PropTypes.number,
+ className: PropTypes.string,
+ style: PropTypes.object
+ }
+
+ static defaultProps = {
+ timeToCloseMessage: TIME_TO_CLOSE_MESSAGE,
+ className: null,
+ style: {}
+ }
+
+ constructor(props) {
+ super(props);
+ this.indicatorTimer = null;
+ this.clearTimer = this.clearTimer.bind(this);
+ this.handleBlur = this.handleBlur.bind(this);
+ this.handleClick = this.handleClick.bind(this);
+ this.handleKeyDown = this.handleKeyDown.bind(this);
+ this.beforeComplete = this.beforeComplete.bind(this);
+ this.state = {
+ invalidMessage: null
+ };
+ }
+
+ componentWillReceiveProps({ message }) {
+ if (_.isDefined(message)) {
+ this.createTimer();
+ this.setState(() => ({
+ invalidMessage: message
+ }));
+ }
+ }
+
+ componentWillUnmount() {
+ this.clearTimer();
+ }
+
+ clearTimer() {
+ if (this.indicatorTimer) {
+ clearTimeout(this.indicatorTimer);
+ }
+ }
+
+ createTimer() {
+ this.clearTimer();
+ const { timeToCloseMessage, onErrorMessageDisappear } = this.props;
+ this.indicatorTimer = _.sleep(() => {
+ this.setState(() => ({
+ invalidMessage: null
+ }));
+ if (_.isFunction(onErrorMessageDisappear)) onErrorMessageDisappear();
+ }, timeToCloseMessage);
+ }
+
+ beforeComplete(row, column, newValue) {
+ const { onUpdate } = this.props;
+ if (_.isFunction(column.validator)) {
+ const validateForm = column.validator(newValue, row, column);
+ if (_.isObject(validateForm) && !validateForm.valid) {
+ this.setState(() => ({
+ invalidMessage: validateForm.message
+ }));
+ this.createTimer();
+ return;
+ }
+ }
+ onUpdate(row, column, newValue);
+ }
+
+ handleBlur() {
+ const { onEscape, blurToSave, row, column } = this.props;
+ if (blurToSave) {
+ const value = this.editor.text.value;
+ if (!_.isDefined(value)) {
+ // TODO: for other custom or embed editor
+ }
+ this.beforeComplete(row, column, value);
+ } else {
+ onEscape();
+ }
+ }
+
+ handleKeyDown(e) {
+ const { onEscape, row, column } = this.props;
+ if (e.keyCode === 27) { // ESC
+ onEscape();
+ } else if (e.keyCode === 13) { // ENTER
+ const value = e.currentTarget.value;
+ if (!_.isDefined(value)) {
+ // TODO: for other custom or embed editor
+ }
+ this.beforeComplete(row, column, value);
+ }
+ }
+
+ handleClick(e) {
+ if (e.target.tagName !== 'TD') {
+ // To avoid the row selection event be triggered,
+ // When user define selectRow.clickToSelect and selectRow.clickToEdit
+ // We shouldn't trigger selection event even if user click on the cell editor(input)
+ e.stopPropagation();
+ }
+ }
+
+ render() {
+ const { invalidMessage } = this.state;
+ const { row, column, className, style } = this.props;
+ const { dataField } = column;
+
+ const value = _.get(row, dataField);
+ const editorAttrs = {
+ onKeyDown: this.handleKeyDown,
+ onBlur: this.handleBlur
+ };
+
+ const hasError = _.isDefined(invalidMessage);
+ const editorClass = hasError ? cs('animated', 'shake') : null;
+ return (
+
+ this.editor = node }
+ defaultValue={ value }
+ className={ editorClass }
+ { ...editorAttrs }
+ />
+ { hasError ? : null }
+ |
+ );
+ }
+ };
diff --git a/packages/react-bootstrap-table2/src/cell-edit/editor-indicator.js b/packages/react-bootstrap-table2-editor/src/editor-indicator.js
similarity index 100%
rename from packages/react-bootstrap-table2/src/cell-edit/editor-indicator.js
rename to packages/react-bootstrap-table2-editor/src/editor-indicator.js
diff --git a/packages/react-bootstrap-table2-editor/src/index.js b/packages/react-bootstrap-table2-editor/src/index.js
new file mode 100644
index 0000000..0d8be80
--- /dev/null
+++ b/packages/react-bootstrap-table2-editor/src/index.js
@@ -0,0 +1,16 @@
+import wrapperFactory from './wrapper';
+import editingCellFactory from './editing-cell';
+import {
+ CLICK_TO_CELL_EDIT,
+ DBCLICK_TO_CELL_EDIT,
+ DELAY_FOR_DBCLICK
+} from './const';
+
+export default (options = {}) => ({
+ wrapperFactory,
+ editingCellFactory,
+ CLICK_TO_CELL_EDIT,
+ DBCLICK_TO_CELL_EDIT,
+ DELAY_FOR_DBCLICK,
+ options
+});
diff --git a/packages/react-bootstrap-table2/src/cell-edit/text-editor.js b/packages/react-bootstrap-table2-editor/src/text-editor.js
similarity index 100%
rename from packages/react-bootstrap-table2/src/cell-edit/text-editor.js
rename to packages/react-bootstrap-table2-editor/src/text-editor.js
diff --git a/packages/react-bootstrap-table2/src/cell-edit/wrapper.js b/packages/react-bootstrap-table2-editor/src/wrapper.js
similarity index 59%
rename from packages/react-bootstrap-table2/src/cell-edit/wrapper.js
rename to packages/react-bootstrap-table2-editor/src/wrapper.js
index 7f21e53..97138d4 100644
--- a/packages/react-bootstrap-table2/src/cell-edit/wrapper.js
+++ b/packages/react-bootstrap-table2-editor/src/wrapper.js
@@ -1,12 +1,31 @@
/* eslint react/prop-types: 0 */
import React, { Component } from 'react';
-import _ from '../utils';
-import remoteResolver from '../props-resolver/remote-resolver';
+import PropTypes from 'prop-types';
+
+import { CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT } from './const';
+
+export default (
+ Base,
+ { _, remoteResolver }
+) => {
+ let EditingCell;
+ return class CellEditWrapper extends remoteResolver(Component) {
+ static propTypes = {
+ options: PropTypes.shape({
+ mode: PropTypes.oneOf([CLICK_TO_CELL_EDIT, DBCLICK_TO_CELL_EDIT]).isRequired,
+ onErrorMessageDisappear: PropTypes.func,
+ blurToSave: PropTypes.bool,
+ beforeSaveCell: PropTypes.func,
+ afterSaveCell: PropTypes.func,
+ nonEditableRows: PropTypes.func,
+ timeToCloseMessage: PropTypes.number,
+ errorMessage: PropTypes.string
+ })
+ }
-export default Base =>
- class CellEditWrapper extends remoteResolver(Component) {
constructor(props) {
super(props);
+ EditingCell = props.cellEdit.editingCellFactory(_);
this.startEditing = this.startEditing.bind(this);
this.escapeEditing = this.escapeEditing.bind(this);
this.completeEditing = this.completeEditing.bind(this);
@@ -21,10 +40,10 @@ export default Base =>
componentWillReceiveProps(nextProps) {
if (nextProps.cellEdit && this.isRemoteCellEdit()) {
- if (nextProps.cellEdit.errorMessage) {
+ if (nextProps.cellEdit.options.errorMessage) {
this.setState(() => ({
isDataChanged: false,
- message: nextProps.cellEdit.errorMessage
+ message: nextProps.cellEdit.options.errorMessage
}));
} else {
this.setState(() => ({
@@ -41,7 +60,7 @@ export default Base =>
handleCellUpdate(row, column, newValue) {
const { keyField, cellEdit, store } = this.props;
- const { beforeSaveCell, afterSaveCell } = cellEdit;
+ const { beforeSaveCell, afterSaveCell } = cellEdit.options;
const oldValue = _.get(row, column.dataField);
const rowId = _.get(row, keyField);
if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
@@ -84,17 +103,33 @@ export default Base =>
}
render() {
- const { isDataChanged, ...rest } = this.state;
+ const { isDataChanged, ...stateRest } = this.state;
+ const {
+ cellEdit: {
+ options: { nonEditableRows, errorMessage, ...optionsRest },
+ editingCellFactory,
+ ...cellEditRest
+ }
+ } = this.props;
+ const newCellEdit = {
+ ...optionsRest,
+ ...cellEditRest,
+ ...stateRest,
+ EditingCell,
+ nonEditableRows: _.isDefined(nonEditableRows) ? nonEditableRows() : [],
+ onStart: this.startEditing,
+ onEscape: this.escapeEditing,
+ onUpdate: this.handleCellUpdate
+ };
+
return (
);
}
};
+};
diff --git a/packages/react-bootstrap-table2/test/cell-edit/editing-cell.test.js b/packages/react-bootstrap-table2-editor/test/editing-cell.test.js
similarity index 94%
rename from packages/react-bootstrap-table2/test/cell-edit/editing-cell.test.js
rename to packages/react-bootstrap-table2-editor/test/editing-cell.test.js
index 190d759..5eda210 100644
--- a/packages/react-bootstrap-table2/test/cell-edit/editing-cell.test.js
+++ b/packages/react-bootstrap-table2-editor/test/editing-cell.test.js
@@ -1,12 +1,23 @@
+/* eslint react/prop-types: 0 */
import 'jsdom-global/register';
import React from 'react';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
-import { TableRowWrapper } from '../test-helpers/table-wrapper';
-import EditingCell from '../../src/cell-edit/editing-cell';
-import TextEditor from '../../src/cell-edit/text-editor';
-import EditorIndicator from '../../src/cell-edit/editor-indicator';
+import _ from 'react-bootstrap-table2/src/utils';
+import editingCellFactory from '../src/editing-cell';
+import TextEditor from '../src/text-editor';
+import EditorIndicator from '../src/editor-indicator';
+
+const EditingCell = editingCellFactory(_);
+const TableRowWrapper = props => (
+
+
+ { props.children }
+
+
+);
+
describe('EditingCell', () => {
let wrapper;
diff --git a/packages/react-bootstrap-table2/test/cell-edit/text-editor.test.js b/packages/react-bootstrap-table2-editor/test/text-editor.test.js
similarity index 94%
rename from packages/react-bootstrap-table2/test/cell-edit/text-editor.test.js
rename to packages/react-bootstrap-table2-editor/test/text-editor.test.js
index e9d9119..845d788 100644
--- a/packages/react-bootstrap-table2/test/cell-edit/text-editor.test.js
+++ b/packages/react-bootstrap-table2-editor/test/text-editor.test.js
@@ -2,7 +2,7 @@ import 'jsdom-global/register';
import React from 'react';
import { mount } from 'enzyme';
-import TextEditor from '../../src/cell-edit/text-editor';
+import TextEditor from '../src/text-editor';
describe('TextEditor', () => {
let wrapper;
diff --git a/packages/react-bootstrap-table2-editor/test/wrapper.test.js b/packages/react-bootstrap-table2-editor/test/wrapper.test.js
new file mode 100644
index 0000000..4e2426e
--- /dev/null
+++ b/packages/react-bootstrap-table2-editor/test/wrapper.test.js
@@ -0,0 +1,330 @@
+import React from 'react';
+import sinon from 'sinon';
+import { shallow } from 'enzyme';
+
+import _ from 'react-bootstrap-table2/src/utils';
+import remoteResolver from 'react-bootstrap-table2/src/props-resolver/remote-resolver';
+import Store from 'react-bootstrap-table2/src/store';
+import BootstrapTable from 'react-bootstrap-table2/src/bootstrap-table';
+import cellEditFactory from '../src';
+import * as Const from '../src/const';
+import wrapperFactory from '../src/wrapper';
+
+describe('CellEditWrapper', () => {
+ let wrapper;
+ let instance;
+ const onTableChangeCB = sinon.stub();
+ const columns = [{
+ dataField: 'id',
+ text: 'ID'
+ }, {
+ dataField: 'name',
+ text: 'Name'
+ }];
+ const data = [{
+ id: 1,
+ name: 'A'
+ }, {
+ id: 2,
+ name: 'B'
+ }];
+
+ const createTableProps = (props = {}) => {
+ const { cellEdit, ...rest } = props;
+ const tableProps = {
+ keyField: 'id',
+ columns,
+ data,
+ _,
+ store: new Store('id'),
+ cellEdit: cellEditFactory(cellEdit),
+ onTableChange: onTableChangeCB,
+ ...rest
+ };
+ tableProps.store.data = data;
+ return tableProps;
+ };
+
+ const CellEditWrapper = wrapperFactory(BootstrapTable, {
+ _,
+ remoteResolver
+ });
+
+ const createCellEditWrapper = (props, renderFragment = true) => {
+ wrapper = shallow();
+ instance = wrapper.instance();
+ if (renderFragment) {
+ const fragment = instance.render();
+ wrapper = shallow({ fragment }
);
+ }
+ };
+
+ afterEach(() => {
+ onTableChangeCB.reset();
+ });
+
+ beforeEach(() => {
+ const props = createTableProps({
+ cellEdit: { mode: Const.CLICK_TO_CELL_EDIT }
+ });
+ createCellEditWrapper(props);
+ });
+
+ it('should render CellEditWrapper correctly', () => {
+ expect(wrapper.length).toBe(1);
+ expect(wrapper.find(BootstrapTable)).toBeDefined();
+ });
+
+ it('should have correct state', () => {
+ expect(instance.state.ridx).toBeNull();
+ expect(instance.state.cidx).toBeNull();
+ expect(instance.state.message).toBeNull();
+ expect(instance.state.isDataChanged).toBeFalsy();
+ });
+
+ it('should inject correct props to base component', () => {
+ const base = wrapper.find(BootstrapTable);
+ expect(base.props().cellEdit).toBeDefined();
+ expect(base.props().cellEdit.onStart).toBeDefined();
+ expect(base.props().cellEdit.onEscape).toBeDefined();
+ expect(base.props().cellEdit.onUpdate).toBeDefined();
+ expect(base.props().cellEdit.EditingCell).toBeDefined();
+ expect(base.props().cellEdit.ridx).toBeNull();
+ expect(base.props().cellEdit.cidx).toBeNull();
+ expect(base.props().cellEdit.message).toBeNull();
+ expect(base.props().isDataChanged).toBe(instance.state.isDataChanged);
+ });
+
+ describe('when receive new cellEdit prop', () => {
+ const spy = jest.spyOn(CellEditWrapper.prototype, 'escapeEditing');
+
+ describe('and cellEdit is not work on remote', () => {
+ beforeEach(() => {
+ const props = createTableProps({
+ cellEdit: { mode: Const.CLICK_TO_CELL_EDIT }
+ });
+ createCellEditWrapper(props);
+ wrapper.setProps({ cellEdit: props.cellEdit });
+ });
+
+ it('should always setting state.isDataChanged as false', () => {
+ expect(instance.state.isDataChanged).toBeFalsy();
+ });
+ });
+
+ describe('and cellEdit is work on remote', () => {
+ let errorMessage;
+ let props;
+ beforeEach(() => {
+ props = createTableProps({
+ cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
+ remote: true
+ });
+ });
+
+ describe('and cellEdit.errorMessage is defined', () => {
+ beforeEach(() => {
+ createCellEditWrapper(props, false);
+ errorMessage = 'test';
+ const newCellEdit = {
+ ...props.cellEdit,
+ options: { ...props.cellEdit.options, errorMessage }
+ };
+ wrapper.setProps({ cellEdit: newCellEdit });
+ });
+
+ it('should setting correct state', () => {
+ expect(instance.state.isDataChanged).toBeFalsy();
+ expect(instance.state.message).toEqual(errorMessage);
+ });
+ });
+
+ describe('and cellEdit.errorMessage is undefined', () => {
+ beforeEach(() => {
+ errorMessage = null;
+ createCellEditWrapper(props, false);
+ const newCellEdit = {
+ ...props.cellEdit,
+ options: { ...props.cellEdit.options, errorMessage }
+ };
+ wrapper.setProps({ cellEdit: newCellEdit });
+ });
+
+ it('should setting correct state', () => {
+ expect(wrapper.state().isDataChanged).toBeTruthy();
+ });
+
+ it('should escape current editing', () => {
+ expect(spy).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+
+ describe('call escapeEditing function', () => {
+ it('should set state correctly', () => {
+ instance.escapeEditing();
+ expect(instance.state.ridx).toBeNull();
+ expect(instance.state.cidx).toBeNull();
+ });
+ });
+
+ describe('call startEditing function', () => {
+ const ridx = 1;
+ const cidx = 3;
+
+ it('should set state correctly', () => {
+ instance.startEditing(ridx, cidx);
+ expect(instance.state.ridx).toEqual(ridx);
+ expect(instance.state.cidx).toEqual(cidx);
+ expect(instance.state.isDataChanged).toBeFalsy();
+ });
+
+ describe('if selectRow.clickToSelect is defined', () => {
+ beforeEach(() => {
+ const selectRow = { mode: 'checkbox', clickToSelect: true };
+ const props = createTableProps({
+ cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
+ selectRow
+ });
+ createCellEditWrapper(props);
+ });
+
+ it('should not set state', () => {
+ instance.startEditing(ridx, cidx);
+ expect(instance.state.ridx).toBeNull();
+ expect(instance.state.cidx).toBeDefined();
+ });
+ });
+
+ describe('if selectRow.clickToSelect and selectRow.clickToEdit is defined', () => {
+ beforeEach(() => {
+ const selectRow = { mode: 'checkbox', clickToSelect: true, clickToEdit: true };
+ const props = createTableProps({
+ cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
+ selectRow
+ });
+ createCellEditWrapper(props);
+ });
+
+ it('should set state correctly', () => {
+ instance.startEditing(ridx, cidx);
+ expect(instance.state.ridx).toEqual(ridx);
+ expect(instance.state.cidx).toEqual(cidx);
+ });
+ });
+ });
+
+ describe('call completeEditing function', () => {
+ it('should set state correctly', () => {
+ instance.completeEditing();
+ expect(instance.state.ridx).toBeNull();
+ expect(instance.state.cidx).toBeNull();
+ expect(instance.state.message).toBeNull();
+ expect(instance.state.isDataChanged).toBeTruthy();
+ });
+ });
+
+ describe('call handleCellUpdate function', () => {
+ let props;
+ const row = data[0];
+ const column = columns[1];
+ const newValue = 'new name';
+
+ describe('when cell edit is work on remote', () => {
+ const spy = jest.spyOn(CellEditWrapper.prototype, 'handleCellChange');
+
+ beforeEach(() => {
+ props = createTableProps({
+ cellEdit: { mode: Const.CLICK_TO_CELL_EDIT },
+ remote: true
+ });
+ createCellEditWrapper(props);
+ instance.handleCellUpdate(row, column, newValue);
+ });
+
+ it('should calling handleCellChange correctly', () => {
+ expect(spy).toHaveBeenCalled();
+ expect(spy.mock.calls).toHaveLength(1);
+ expect(spy.mock.calls[0]).toHaveLength(3);
+ expect(spy.mock.calls[0][0]).toEqual(row.id);
+ expect(spy.mock.calls[0][1]).toEqual(column.dataField);
+ expect(spy.mock.calls[0][2]).toEqual(newValue);
+ });
+ });
+
+ describe('when cell edit is not work on remote', () => {
+ const spyOnCompleteEditing = jest.spyOn(CellEditWrapper.prototype, 'completeEditing');
+ const spyOnStoreEdit = jest.spyOn(Store.prototype, 'edit');
+
+ beforeEach(() => {
+ props = createTableProps({
+ cellEdit: { mode: Const.CLICK_TO_CELL_EDIT }
+ });
+ createCellEditWrapper(props);
+ instance.handleCellUpdate(row, column, newValue);
+ });
+
+ afterEach(() => {
+ spyOnStoreEdit.mockReset();
+ spyOnCompleteEditing.mockReset();
+ });
+
+ it('should calling props.store.edit', () => {
+ expect(spyOnStoreEdit).toHaveBeenCalled();
+ expect(spyOnStoreEdit.mock.calls).toHaveLength(1);
+ expect(spyOnStoreEdit.mock.calls[0]).toHaveLength(3);
+ expect(spyOnStoreEdit.mock.calls[0][0]).toEqual(row.id);
+ expect(spyOnStoreEdit.mock.calls[0][1]).toEqual(column.dataField);
+ expect(spyOnStoreEdit.mock.calls[0][2]).toEqual(newValue);
+ });
+
+ it('should calling completeEditing function', () => {
+ expect(spyOnCompleteEditing).toHaveBeenCalled();
+ });
+
+ describe('if cellEdit.afterSaveCell prop defined', () => {
+ const aftereSaveCellCallBack = sinon.stub();
+
+ beforeEach(() => {
+ props = createTableProps({
+ cellEdit: {
+ mode: Const.CLICK_TO_CELL_EDIT,
+ afterSaveCell: aftereSaveCellCallBack
+ }
+ });
+ createCellEditWrapper(props);
+ instance.handleCellUpdate(row, column, newValue);
+ });
+
+ it('should calling cellEdit.afterSaveCell correctly', () => {
+ expect(aftereSaveCellCallBack.callCount).toBe(1);
+ expect(aftereSaveCellCallBack.calledWith(
+ row[column.dataField], newValue, row, column)
+ ).toBe(true);
+ });
+ });
+ });
+
+ describe('if cellEdit.beforeSaveCell prop defined', () => {
+ const beforeSaveCellCallBack = sinon.stub();
+ beforeEach(() => {
+ props = createTableProps({
+ cellEdit: {
+ mode: Const.CLICK_TO_CELL_EDIT,
+ beforeSaveCell: beforeSaveCellCallBack
+ }
+ });
+ createCellEditWrapper(props);
+ instance.handleCellUpdate(row, column, newValue);
+ });
+
+ it('should calling cellEdit.beforeSaveCell correctly', () => {
+ expect(beforeSaveCellCallBack.callCount).toBe(1);
+ expect(beforeSaveCellCallBack.calledWith(
+ row[column.dataField], newValue, row, column)
+ ).toBe(true);
+ });
+ });
+ });
+});
diff --git a/packages/react-bootstrap-table2-example/.storybook/webpack.config.js b/packages/react-bootstrap-table2-example/.storybook/webpack.config.js
index 25f09d8..3cbe327 100644
--- a/packages/react-bootstrap-table2-example/.storybook/webpack.config.js
+++ b/packages/react-bootstrap-table2-example/.storybook/webpack.config.js
@@ -4,6 +4,7 @@ const sourcePath = path.join(__dirname, '../../react-bootstrap-table2/src');
const paginationSourcePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/src');
const overlaySourcePath = path.join(__dirname, '../../react-bootstrap-table2-overlay/src');
const filterSourcePath = path.join(__dirname, '../../react-bootstrap-table2-filter/src');
+const editorSourcePath = path.join(__dirname, '../../react-bootstrap-table2-editor/src');
const sourceStylePath = path.join(__dirname, '../../react-bootstrap-table2/style');
const paginationStylePath = path.join(__dirname, '../../react-bootstrap-table2-paginator/style');
const storyPath = path.join(__dirname, '../stories');
@@ -27,7 +28,7 @@ const loaders = [{
test: /\.js?$/,
use: ['babel-loader'],
exclude: /node_modules/,
- include: [sourcePath, paginationSourcePath, overlaySourcePath, filterSourcePath, storyPath],
+ include: [sourcePath, paginationSourcePath, overlaySourcePath, filterSourcePath, editorSourcePath, storyPath],
}, {
test: /\.css$/,
use: ['style-loader', 'css-loader'],
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/blur-to-save-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/blur-to-save-table.js
index db6818c..ebd875b 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/blur-to-save-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/blur-to-save-table.js
@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +19,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,26 +32,28 @@ const columns = [{
text: 'Product Price'
}];
-const cellEdit = {
- mode: 'click',
- blurToSave: true
-};
-
`;
-const cellEdit = {
- mode: 'click',
- blurToSave: true
-};
export default () => (
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-class-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-class-table.js
index 3486700..39d6862 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-class-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-class-table.js
@@ -2,6 +2,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -22,6 +23,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -36,24 +39,22 @@ const columns = [{
(cell > 2101 ? 'editing-price-bigger-than-2101' : 'editing-price-small-than-2101')
}];
-const cellEdit = {
- mode: 'click'
-};
-
`;
-const cellEdit = {
- mode: 'click'
-};
export default () => (
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-hooks-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-hooks-table.js
index 24779fc..f7aa30f 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-hooks-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-hooks-table.js
@@ -3,6 +3,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +21,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -31,28 +34,30 @@ const columns = [{
text: 'Product Price'
}];
-const cellEdit = {
- mode: 'click',
- beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
- afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
-};
-
{ console.log('Before Saving Cell!!'); },
+ afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
+ }) }
/>
`;
-const cellEdit = {
- mode: 'click',
- beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
- afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
-};
export default () => (
-
+ { console.log('Before Saving Cell!!'); },
+ afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
+ }) }
+ />
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-style-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-style-table.js
index 2101bd3..28ea32f 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-style-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-style-table.js
@@ -2,6 +2,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -26,6 +27,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -44,24 +47,22 @@ const columns = [{
}
}];
-const cellEdit = {
- mode: 'click'
-};
-
`;
-const cellEdit = {
- mode: 'click'
-};
export default () => (
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-validator-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-validator-table.js
index 6b31c5d..c49823b 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-validator-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-validator-table.js
@@ -1,6 +1,7 @@
-import React from 'react';
/* eslint no-unused-vars: 0 */
+import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -33,6 +34,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -59,27 +62,29 @@ const columns = [{
}
}];
-const cellEdit = {
- mode: 'click',
- blurToSave: true
-};
-
`;
-const cellEdit = {
- mode: 'click',
- blurToSave: true
-};
export default () => (
Product Price should bigger than $2000
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-level-editable-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-level-editable-table.js
index 331792a..89e7947 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-level-editable-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-level-editable-table.js
@@ -2,6 +2,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -20,6 +21,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -32,24 +35,22 @@ const columns = [{
editable: (content, row, rowIndex, columnIndex) => content > 2101
}];
-const cellEdit = {
- mode: 'click'
-};
-
`;
-const cellEdit = {
- mode: 'click'
-};
export default () => (
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/click-to-edit-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/click-to-edit-table.js
index f48e6e4..5055918 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/click-to-edit-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/click-to-edit-table.js
@@ -1,6 +1,8 @@
+/* eslint react/prefer-stateless-function: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +20,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,24 +33,22 @@ const columns = [{
text: 'Product Price'
}];
-const cellEdit = {
- mode: 'click'
-};
-
`;
-const cellEdit = {
- mode: 'click'
-};
export default () => (
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/column-level-editable-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/column-level-editable-table.js
index 0242911..f344f9f 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/column-level-editable-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/column-level-editable-table.js
@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -19,6 +20,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -32,26 +35,28 @@ const columns = [{
text: 'Product Price'
}];
-const cellEdit = {
- mode: 'click',
- blurToSave: true
-};
-
`;
-const cellEdit = {
- mode: 'click',
- blurToSave: true
-};
export default () => (
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/dbclick-to-edit-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/dbclick-to-edit-table.js
index c51a155..76eab20 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/dbclick-to-edit-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/dbclick-to-edit-table.js
@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +19,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,24 +32,22 @@ const columns = [{
text: 'Product Price'
}];
-const cellEdit = {
- mode: 'dbclick'
-};
-
`;
-const cellEdit = {
- mode: 'dbclick'
-};
export default () => (
-
+
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/row-level-editable-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/row-level-editable-table.js
index 99f177a..c141d8b 100644
--- a/packages/react-bootstrap-table2-example/examples/cell-edit/row-level-editable-table.js
+++ b/packages/react-bootstrap-table2-example/examples/cell-edit/row-level-editable-table.js
@@ -1,6 +1,7 @@
import React from 'react';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +19,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const columns = [{
dataField: 'id',
text: 'Product ID'
@@ -29,29 +32,29 @@ const columns = [{
text: 'Product Price'
}];
-const cellEdit = {
- mode: 'click',
- blurToSave: true,
- // Product ID: 0, 3 will be non-editable
- nonEditableRows: () => [0, 3]
-};
-
[0, 3]
+ }) }
/>
`;
-
-const cellEdit = {
- mode: 'click',
- blurToSave: true,
- nonEditableRows: () => [0, 3]
-};
export default () => (
-
+ [0, 3]
+ }) }
+ />
{ sourceCode }
);
diff --git a/packages/react-bootstrap-table2-example/examples/remote/remote-celledit.js b/packages/react-bootstrap-table2-example/examples/remote/remote-celledit.js
index 312c81e..ed8f564 100644
--- a/packages/react-bootstrap-table2-example/examples/remote/remote-celledit.js
+++ b/packages/react-bootstrap-table2-example/examples/remote/remote-celledit.js
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import BootstrapTable from 'react-bootstrap-table2';
+import cellEditFactory from 'react-bootstrap-table2-editor';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
@@ -18,6 +19,8 @@ const columns = [{
}];
const sourceCode = `\
+import cellEditFactory from 'react-bootstrap-table2-editor';
+// ...
const RemoteCellEdit = (props) => {
const cellEdit = {
mode: 'click',
@@ -31,7 +34,7 @@ const RemoteCellEdit = (props) => {
keyField="id"
data={ props.data }
columns={ columns }
- cellEdit={ cellEdit }
+ cellEdit={ cellEditFactory(cellEdit) }
onTableChange={ props.onTableChange }
/>
{ sourceCode }
@@ -104,7 +107,7 @@ const RemoteCellEdit = (props) => {
keyField="id"
data={ props.data }
columns={ columns }
- cellEdit={ cellEdit }
+ cellEdit={ cellEditFactory(cellEdit) }
onTableChange={ props.onTableChange }
/>
{ sourceCode }
diff --git a/packages/react-bootstrap-table2-example/package.json b/packages/react-bootstrap-table2-example/package.json
index 419f884..7f85d30 100644
--- a/packages/react-bootstrap-table2-example/package.json
+++ b/packages/react-bootstrap-table2-example/package.json
@@ -18,6 +18,7 @@
"dependencies": {
"bootstrap": "^3.3.7",
"react-bootstrap-table2": "0.0.1",
+ "react-bootstrap-table2-editor": "0.0.1",
"react-bootstrap-table2-paginator": "0.0.1",
"react-bootstrap-table2-overlay": "0.0.1",
"react-bootstrap-table2-filter": "0.0.1"
diff --git a/packages/react-bootstrap-table2/src/body.js b/packages/react-bootstrap-table2/src/body.js
index b0182da..9ee9e89 100644
--- a/packages/react-bootstrap-table2/src/body.js
+++ b/packages/react-bootstrap-table2/src/body.js
@@ -37,10 +37,10 @@ const Body = (props) => {
const indication = _.isFunction(noDataIndication) ? noDataIndication() : noDataIndication;
content = ;
} else {
+ const nonEditableRows = cellEdit.nonEditableRows || [];
content = data.map((row, index) => {
const key = _.get(row, keyField);
- const editable = !(cellEdit.mode !== Const.UNABLE_TO_CELL_EDIT &&
- cellEdit.nonEditableRows.indexOf(key) > -1);
+ const editable = !(nonEditableRows.length > 0 && nonEditableRows.indexOf(key) > -1);
const selected = selectRow.mode !== Const.ROW_SELECT_DISABLED
? selectedRowKeys.includes(key)
diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js
index aeed455..4834ec0 100644
--- a/packages/react-bootstrap-table2/src/bootstrap-table.js
+++ b/packages/react-bootstrap-table2/src/bootstrap-table.js
@@ -60,13 +60,6 @@ class BootstrapTable extends PropsBaseResolver(Component) {
'table-condensed': condensed
});
- const cellEditInfo = this.resolveCellEditProps({
- onStart: this.props.onStartEditing,
- onEscape: this.props.onEscapeEditing,
- onUpdate: this.props.onCellUpdate,
- currEditCell: this.props.currEditCell
- });
-
const cellSelectionInfo = this.resolveSelectRowProps({
onRowSelect: this.props.onRowSelect
});
@@ -96,7 +89,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
isEmpty={ this.isEmpty() }
visibleColumnSize={ this.visibleColumnSize() }
noDataIndication={ noDataIndication }
- cellEdit={ cellEditInfo }
+ cellEdit={ this.props.cellEdit || {} }
selectRow={ cellSelectionInfo }
selectedRowKeys={ store.selected }
rowStyle={ rowStyle }
@@ -128,24 +121,7 @@ BootstrapTable.propTypes = {
]),
pagination: PropTypes.object,
filter: PropTypes.object,
- cellEdit: PropTypes.shape({
- mode: PropTypes.oneOf([Const.CLICK_TO_CELL_EDIT, Const.DBCLICK_TO_CELL_EDIT]).isRequired,
- onErrorMessageDisappear: PropTypes.func,
- blurToSave: PropTypes.bool,
- beforeSaveCell: PropTypes.func,
- afterSaveCell: PropTypes.func,
- nonEditableRows: PropTypes.func,
- timeToCloseMessage: PropTypes.number,
- errorMessage: PropTypes.string
- }),
- onCellUpdate: PropTypes.func,
- onStartEditing: PropTypes.func,
- onEscapeEditing: PropTypes.func,
- currEditCell: PropTypes.shape({
- ridx: PropTypes.number,
- cidx: PropTypes.number,
- message: PropTypes.string
- }),
+ cellEdit: PropTypes.object,
selectRow: PropTypes.shape({
mode: PropTypes.oneOf([Const.ROW_SELECT_SINGLE, Const.ROW_SELECT_MULTIPLE]).isRequired,
clickToSelect: PropTypes.bool,
diff --git a/packages/react-bootstrap-table2/src/cell-edit/editing-cell.js b/packages/react-bootstrap-table2/src/cell-edit/editing-cell.js
deleted file mode 100644
index d353960..0000000
--- a/packages/react-bootstrap-table2/src/cell-edit/editing-cell.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/* eslint arrow-body-style: 0 */
-/* eslint react/prop-types: 0 */
-/* eslint no-return-assign: 0 */
-/* eslint class-methods-use-this: 0 */
-/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
-import React, { Component } from 'react';
-import cs from 'classnames';
-import PropTypes from 'prop-types';
-
-import _ from '../utils';
-import Const from '../const';
-import TextEditor from './text-editor';
-import EditorIndicator from './editor-indicator';
-
-class EditingCell extends Component {
- constructor(props) {
- super(props);
- this.indicatorTimer = null;
- this.clearTimer = this.clearTimer.bind(this);
- this.handleBlur = this.handleBlur.bind(this);
- this.handleClick = this.handleClick.bind(this);
- this.handleKeyDown = this.handleKeyDown.bind(this);
- this.beforeComplete = this.beforeComplete.bind(this);
- this.state = {
- invalidMessage: null
- };
- }
-
- componentWillReceiveProps({ message }) {
- if (_.isDefined(message)) {
- this.createTimer();
- this.setState(() => {
- return { invalidMessage: message };
- });
- }
- }
-
- componentWillUnmount() {
- this.clearTimer();
- }
-
- clearTimer() {
- if (this.indicatorTimer) {
- clearTimeout(this.indicatorTimer);
- }
- }
-
- createTimer() {
- this.clearTimer();
- const { timeToCloseMessage, onErrorMessageDisappear } = this.props;
- this.indicatorTimer = _.sleep(() => {
- this.setState(() => {
- return { invalidMessage: null };
- });
- if (_.isFunction(onErrorMessageDisappear)) onErrorMessageDisappear();
- }, timeToCloseMessage);
- }
-
- beforeComplete(row, column, newValue) {
- const { onUpdate } = this.props;
- if (_.isFunction(column.validator)) {
- const validateForm = column.validator(newValue, row, column);
- if (_.isObject(validateForm) && !validateForm.valid) {
- this.setState(() => {
- return { invalidMessage: validateForm.message };
- });
- this.createTimer();
- return;
- }
- }
- onUpdate(row, column, newValue);
- }
-
- handleBlur() {
- const { onEscape, blurToSave, row, column } = this.props;
- if (blurToSave) {
- const value = this.editor.text.value;
- if (!_.isDefined(value)) {
- // TODO: for other custom or embed editor
- }
- this.beforeComplete(row, column, value);
- } else {
- onEscape();
- }
- }
-
- handleKeyDown(e) {
- const { onEscape, row, column } = this.props;
- if (e.keyCode === 27) { // ESC
- onEscape();
- } else if (e.keyCode === 13) { // ENTER
- const value = e.currentTarget.value;
- if (!_.isDefined(value)) {
- // TODO: for other custom or embed editor
- }
- this.beforeComplete(row, column, value);
- }
- }
-
- handleClick(e) {
- if (e.target.tagName !== 'TD') {
- // To avoid the row selection event be triggered,
- // When user define selectRow.clickToSelect and selectRow.clickToEdit
- // We shouldn't trigger selection event even if user click on the cell editor(input)
- e.stopPropagation();
- }
- }
-
- render() {
- const { invalidMessage } = this.state;
- const { row, column, className, style } = this.props;
- const { dataField } = column;
-
- const value = _.get(row, dataField);
- const editorAttrs = {
- onKeyDown: this.handleKeyDown,
- onBlur: this.handleBlur
- };
-
- const hasError = _.isDefined(invalidMessage);
- const editorClass = hasError ? cs('animated', 'shake') : null;
- return (
-
- this.editor = node }
- defaultValue={ value }
- className={ editorClass }
- { ...editorAttrs }
- />
- { hasError ? : null }
- |
- );
- }
-}
-
-EditingCell.propTypes = {
- row: PropTypes.object.isRequired,
- column: PropTypes.object.isRequired,
- onUpdate: PropTypes.func.isRequired,
- onEscape: PropTypes.func.isRequired,
- timeToCloseMessage: PropTypes.number,
- className: PropTypes.string,
- style: PropTypes.object
-};
-
-EditingCell.defaultProps = {
- timeToCloseMessage: Const.TIME_TO_CLOSE_MESSAGE,
- className: null,
- style: {}
-};
-
-export default EditingCell;
diff --git a/packages/react-bootstrap-table2/src/cell.js b/packages/react-bootstrap-table2/src/cell.js
index add0f58..d50eeb4 100644
--- a/packages/react-bootstrap-table2/src/cell.js
+++ b/packages/react-bootstrap-table2/src/cell.js
@@ -2,7 +2,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import Const from './const';
import _ from './utils';
class Cell extends Component {
@@ -12,18 +11,20 @@ class Cell extends Component {
}
handleEditingCell(e) {
- const { editMode, column, onStart, rowIndex, columnIndex } = this.props;
+ const { column, onStart, rowIndex, columnIndex, clickToEdit, dbclickToEdit } = this.props;
const { events } = column;
if (events) {
- if (editMode === Const.CLICK_TO_CELL_EDIT) {
+ if (clickToEdit) {
const customClick = events.onClick;
if (_.isFunction(customClick)) customClick(e);
- } else {
+ } else if (dbclickToEdit) {
const customDbClick = events.onDoubleClick;
if (_.isFunction(customDbClick)) customDbClick(e);
}
}
- onStart(rowIndex, columnIndex);
+ if (onStart) {
+ onStart(rowIndex, columnIndex);
+ }
}
render() {
@@ -32,8 +33,9 @@ class Cell extends Component {
rowIndex,
column,
columnIndex,
- editMode,
- editable
+ editable,
+ clickToEdit,
+ dbclickToEdit
} = this.props;
const {
dataField,
@@ -85,12 +87,10 @@ 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) {
- cellAttrs.onClick = this.handleEditingCell;
- } else {
- cellAttrs.onDoubleClick = this.handleEditingCell;
- }
+ if (clickToEdit && editable) {
+ cellAttrs.onClick = this.handleEditingCell;
+ } else if (dbclickToEdit && editable) {
+ cellAttrs.onDoubleClick = this.handleEditingCell;
}
return (
{ content } |
diff --git a/packages/react-bootstrap-table2/src/const.js b/packages/react-bootstrap-table2/src/const.js
index e9ebaa6..6c47b1c 100644
--- a/packages/react-bootstrap-table2/src/const.js
+++ b/packages/react-bootstrap-table2/src/const.js
@@ -1,15 +1,10 @@
export default {
SORT_ASC: 'asc',
SORT_DESC: 'desc',
- UNABLE_TO_CELL_EDIT: 'none',
- CLICK_TO_CELL_EDIT: 'click',
- DBCLICK_TO_CELL_EDIT: 'dbclick',
- TIME_TO_CLOSE_MESSAGE: 3000,
ROW_SELECT_SINGLE: 'radio',
ROW_SELECT_MULTIPLE: 'checkbox',
ROW_SELECT_DISABLED: 'ROW_SELECT_DISABLED',
CHECKBOX_STATUS_CHECKED: 'checked',
CHECKBOX_STATUS_INDETERMINATE: 'indeterminate',
- CHECKBOX_STATUS_UNCHECKED: 'unchecked',
- DELAY_FOR_DBCLICK: 200
+ CHECKBOX_STATUS_UNCHECKED: 'unchecked'
};
diff --git a/packages/react-bootstrap-table2/src/container.js b/packages/react-bootstrap-table2/src/container.js
index 30fe195..195ef25 100644
--- a/packages/react-bootstrap-table2/src/container.js
+++ b/packages/react-bootstrap-table2/src/container.js
@@ -3,7 +3,6 @@
import React, { Component } from 'react';
import Store from './store';
import withSort from './sort/wrapper';
-import withCellEdit from './cell-edit/wrapper';
import withSelection from './row-selection/wrapper';
import remoteResolver from './props-resolver/remote-resolver';
@@ -45,7 +44,11 @@ const withDataStore = Base =>
}
if (cellEdit) {
- this.BaseComponent = withCellEdit(this.BaseComponent);
+ const { wrapperFactory } = cellEdit;
+ this.BaseComponent = wrapperFactory(this.BaseComponent, {
+ _,
+ remoteResolver
+ });
}
if (selectRow) {
diff --git a/packages/react-bootstrap-table2/src/props-resolver/index.js b/packages/react-bootstrap-table2/src/props-resolver/index.js
index 1aedc64..4871e2d 100644
--- a/packages/react-bootstrap-table2/src/props-resolver/index.js
+++ b/packages/react-bootstrap-table2/src/props-resolver/index.js
@@ -18,28 +18,6 @@ export default ExtendBase =>
return this.props.data.length === 0;
}
- resolveCellEditProps(options = { currEditCell: null }) {
- const { cellEdit } = this.props;
- const nonEditableRows =
- (cellEdit && _.isFunction(cellEdit.nonEditableRows)) ? cellEdit.nonEditableRows() : [];
- const cellEditInfo = {
- ...options.currEditCell,
- nonEditableRows
- };
-
- if (_.isDefined(cellEdit)) {
- return {
- ...cellEdit,
- ...cellEditInfo,
- ...options
- };
- }
- return {
- mode: Const.UNABLE_TO_CELL_EDIT,
- ...cellEditInfo
- };
- }
-
/**
* props resolver for cell selection
* @param {Object} options - addtional options like callback which are about to merge into props
diff --git a/packages/react-bootstrap-table2/src/row.js b/packages/react-bootstrap-table2/src/row.js
index b1dea9c..24f443a 100644
--- a/packages/react-bootstrap-table2/src/row.js
+++ b/packages/react-bootstrap-table2/src/row.js
@@ -5,7 +5,6 @@ import PropTypes from 'prop-types';
import _ from './utils';
import Cell from './cell';
import SelectionCell from './row-selection/selection-cell';
-import EditingCell from './cell-edit/editing-cell';
import Const from './const';
class Row extends Component {
@@ -26,7 +25,11 @@ class Row extends Component {
onRowSelect,
clickToEdit
},
- cellEdit: { mode },
+ cellEdit: {
+ mode,
+ DBCLICK_TO_CELL_EDIT,
+ DELAY_FOR_DBCLICK
+ },
attrs
} = this.props;
@@ -40,14 +43,14 @@ class Row extends Component {
}
};
- if (mode === Const.DBCLICK_TO_CELL_EDIT && clickToEdit) {
+ if (mode === DBCLICK_TO_CELL_EDIT && clickToEdit) {
this.clickNum += 1;
_.debounce(() => {
if (this.clickNum === 1) {
clickFn();
}
this.clickNum = 0;
- }, Const.DELAY_FOR_DBCLICK)();
+ }, DELAY_FOR_DBCLICK)();
} else {
clickFn();
}
@@ -72,8 +75,11 @@ class Row extends Component {
const {
mode,
onStart,
+ EditingCell,
ridx: editingRowIdx,
cidx: editingColIdx,
+ CLICK_TO_CELL_EDIT,
+ DBCLICK_TO_CELL_EDIT,
...rest
} = cellEdit;
@@ -136,9 +142,10 @@ class Row extends Component {
rowIndex={ rowIndex }
columnIndex={ index }
column={ column }
- editMode={ mode }
- editable={ editable }
onStart={ onStart }
+ editable={ editable }
+ clickToEdit={ mode === CLICK_TO_CELL_EDIT }
+ dbclickToEdit={ mode === DBCLICK_TO_CELL_EDIT }
/>
);
})
diff --git a/packages/react-bootstrap-table2/test/bootstrap-table.test.js b/packages/react-bootstrap-table2/test/bootstrap-table.test.js
index 458f456..3e5e0e1 100644
--- a/packages/react-bootstrap-table2/test/bootstrap-table.test.js
+++ b/packages/react-bootstrap-table2/test/bootstrap-table.test.js
@@ -1,5 +1,4 @@
import React from 'react';
-import sinon from 'sinon';
import { shallow } from 'enzyme';
import Caption from '../src/caption';
@@ -7,7 +6,6 @@ import Store from '../src/store';
import Header from '../src/header';
import Body from '../src/body';
import BootstrapTable from '../src/bootstrap-table';
-import Const from '../src/const';
describe('BootstrapTable', () => {
let wrapper;
@@ -116,49 +114,4 @@ describe('BootstrapTable', () => {
expect(wrapper.find('.table-caption').length).toBe(1);
});
});
-
- describe('when cellEdit props is defined', () => {
- const nonEditableRows = [data[1].id];
- const currEditCell = {
- ridx: 1,
- cidx: 2,
- message: null,
- editing: false
- };
- const cellEdit = {
- mode: Const.CLICK_TO_CELL_EDIT,
- onEditing: sinon.stub(),
- nonEditableRows: () => nonEditableRows
- };
-
- beforeEach(() => {
- wrapper = shallow(
-
- );
- });
-
- it('should resolve correct cellEdit object to Body component', () => {
- const body = wrapper.find(Body);
- expect(body.length).toBe(1);
- expect(body.props().cellEdit.nonEditableRows).toEqual(nonEditableRows);
- expect(body.props().cellEdit.ridx).toEqual(currEditCell.ridx);
- expect(body.props().cellEdit.cidx).toEqual(currEditCell.cidx);
- expect(body.props().cellEdit.message).toEqual(currEditCell.message);
- expect(body.props().cellEdit.editing).toEqual(currEditCell.editing);
- expect(body.props().cellEdit.onStart).toBeDefined();
- expect(body.props().cellEdit.onEscape).toBeDefined();
- expect(body.props().cellEdit.onUpdate).toBeDefined();
- });
- });
});
diff --git a/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js b/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js
deleted file mode 100644
index c195b16..0000000
--- a/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js
+++ /dev/null
@@ -1,346 +0,0 @@
-import React from 'react';
-import sinon from 'sinon';
-import { shallow } from 'enzyme';
-
-import Store from '../../src/store';
-import Container from '../../src';
-import BootstrapTable from '../../src/bootstrap-table';
-import wrapperFactory from '../../src/cell-edit/wrapper';
-
-describe('CellEditWrapper', () => {
- let wrapper;
-
- const columns = [{
- dataField: 'id',
- text: 'ID'
- }, {
- dataField: 'name',
- text: 'Name'
- }];
-
- const data = [{
- id: 1,
- name: 'A'
- }, {
- id: 2,
- name: 'B'
- }];
-
- const cellEdit = {
- mode: 'click'
- };
-
- const keyField = 'id';
- const store = new Store(keyField);
- store.data = data;
-
- const CellEditWrapper = wrapperFactory(Container);
-
- beforeEach(() => {
- wrapper = shallow(
-
- );
- });
-
- it('should render CellEditWrapper correctly', () => {
- expect(wrapper.length).toBe(1);
- expect(wrapper.find(BootstrapTable)).toBeDefined();
- });
-
- it('should have correct state', () => {
- expect(wrapper.state().ridx).toBeNull();
- expect(wrapper.state().cidx).toBeNull();
- expect(wrapper.state().message).toBeNull();
- expect(wrapper.state().isDataChanged).toBeFalsy();
- });
-
- it('should inject correct props to base component', () => {
- expect(wrapper.props().onCellUpdate).toBeDefined();
- expect(wrapper.props().onStartEditing).toBeDefined();
- expect(wrapper.props().onEscapeEditing).toBeDefined();
- expect(wrapper.props().isDataChanged).toBe(wrapper.state().isDataChanged);
- expect(wrapper.props().currEditCell).toBeDefined();
- expect(wrapper.props().currEditCell.ridx).toBeNull();
- expect(wrapper.props().currEditCell.cidx).toBeNull();
- expect(wrapper.props().currEditCell.message).toBeNull();
- });
-
- describe('when receive new cellEdit prop', () => {
- const spy = jest.spyOn(CellEditWrapper.prototype, 'escapeEditing');
-
- describe('and cellEdit is not work on remote', () => {
- beforeEach(() => {
- wrapper = shallow(
-
- );
- wrapper.setProps({ cellEdit: { ...cellEdit } });
- });
-
- it('should always setting state.isDataChanged as false', () => {
- expect(wrapper.state().isDataChanged).toBeFalsy();
- });
- });
-
- describe('and cellEdit is work on remote', () => {
- let errorMessage;
- const ridx = 1;
- const cidx = 2;
-
- describe('and cellEdit.errorMessage is defined', () => {
- beforeEach(() => {
- wrapper = shallow(
-
- );
- errorMessage = 'test';
- wrapper.setState({ ridx, cidx });
- wrapper.setProps({ cellEdit: { ...cellEdit, errorMessage } });
- });
-
- it('should setting correct state', () => {
- expect(wrapper.state().ridx).toEqual(ridx);
- expect(wrapper.state().cidx).toEqual(cidx);
- expect(wrapper.state().isDataChanged).toBeFalsy();
- expect(wrapper.state().message).toEqual(errorMessage);
- });
- });
-
- describe('and cellEdit.errorMessage is undefined', () => {
- beforeEach(() => {
- wrapper = shallow(
-
- );
- errorMessage = null;
- wrapper.setState({ ridx, cidx });
- wrapper.setProps({ cellEdit: { ...cellEdit, errorMessage } });
- });
-
- it('should setting correct state', () => {
- expect(wrapper.state().isDataChanged).toBeTruthy();
- });
-
- it('should escape current editing', () => {
- expect(spy).toHaveBeenCalled();
- });
- });
- });
- });
-
- describe('call escapeEditing function', () => {
- it('should set state correctly', () => {
- wrapper.instance().escapeEditing();
- expect(wrapper.state().ridx).toBeNull();
- expect(wrapper.state().cidx).toBeNull();
- });
- });
-
- describe('call startEditing function', () => {
- const ridx = 1;
- const cidx = 3;
- it('should set state correctly', () => {
- wrapper.instance().startEditing(ridx, cidx);
- expect(wrapper.state().ridx).toEqual(ridx);
- expect(wrapper.state().cidx).toEqual(cidx);
- expect(wrapper.state().isDataChanged).toBeFalsy();
- });
-
- describe('if selectRow.clickToSelect is defined', () => {
- beforeEach(() => {
- const selectRow = { mode: 'checkbox', clickToSelect: true };
- wrapper = shallow(
-
- );
- });
-
- it('should not set state', () => {
- wrapper.instance().startEditing(ridx, cidx);
- expect(wrapper.state().ridx).toBeNull();
- expect(wrapper.state().cidx).toBeDefined();
- });
- });
-
- describe('if selectRow.clickToSelect and selectRow.clickToEdit is defined', () => {
- beforeEach(() => {
- const selectRow = { mode: 'checkbox', clickToSelect: true, clickToEdit: true };
- wrapper = shallow(
-
- );
- });
-
- it('should set state correctly', () => {
- wrapper.instance().startEditing(ridx, cidx);
- expect(wrapper.state().ridx).toEqual(ridx);
- expect(wrapper.state().cidx).toEqual(cidx);
- });
- });
- });
-
- describe('call completeEditing function', () => {
- it('should set state correctly', () => {
- wrapper.instance().completeEditing();
- expect(wrapper.state().ridx).toBeNull();
- expect(wrapper.state().cidx).toBeNull();
- expect(wrapper.state().message).toBeNull();
- expect(wrapper.state().isDataChanged).toBeTruthy();
- });
- });
-
- describe('call handleCellUpdate function', () => {
- const row = data[0];
- const column = columns[1];
- const newValue = 'new name';
-
- describe('when cell edit is work on remote', () => {
- const spy = jest.spyOn(CellEditWrapper.prototype, 'handleCellChange');
- const onTableChangeCB = jest.fn();
-
- beforeEach(() => {
- wrapper = shallow(
-
- );
- wrapper.instance().handleCellUpdate(row, column, newValue);
- });
-
- it('should calling handleCellChange correctly', () => {
- expect(spy).toHaveBeenCalled();
- expect(spy.mock.calls).toHaveLength(1);
- expect(spy.mock.calls[0]).toHaveLength(3);
- expect(spy.mock.calls[0][0]).toEqual(row[keyField]);
- expect(spy.mock.calls[0][1]).toEqual(column.dataField);
- expect(spy.mock.calls[0][2]).toEqual(newValue);
- });
- });
-
- describe('when cell edit is not work on remote', () => {
- const spyOnCompleteEditing = jest.spyOn(CellEditWrapper.prototype, 'completeEditing');
- const spyOnStoreEdit = jest.spyOn(Store.prototype, 'edit');
-
- beforeEach(() => {
- wrapper = shallow(
-
- );
- wrapper.instance().handleCellUpdate(row, column, newValue);
- });
-
- afterEach(() => {
- spyOnStoreEdit.mockReset();
- spyOnCompleteEditing.mockReset();
- });
-
- it('should calling props.store.edit', () => {
- expect(spyOnStoreEdit).toHaveBeenCalled();
- expect(spyOnStoreEdit.mock.calls).toHaveLength(1);
- expect(spyOnStoreEdit.mock.calls[0]).toHaveLength(3);
- expect(spyOnStoreEdit.mock.calls[0][0]).toEqual(row[keyField]);
- expect(spyOnStoreEdit.mock.calls[0][1]).toEqual(column.dataField);
- expect(spyOnStoreEdit.mock.calls[0][2]).toEqual(newValue);
- });
-
- it('should calling completeEditing function', () => {
- expect(spyOnCompleteEditing).toHaveBeenCalled();
- });
-
- describe('if cellEdit.afterSaveCell prop defined', () => {
- const aftereSaveCellCallBack = sinon.stub();
-
- beforeEach(() => {
- cellEdit.afterSaveCell = aftereSaveCellCallBack;
- wrapper = shallow(
-
- );
- wrapper.instance().handleCellUpdate(row, column, newValue);
- });
-
- it('should calling cellEdit.afterSaveCell correctly', () => {
- expect(aftereSaveCellCallBack.callCount).toBe(1);
- expect(aftereSaveCellCallBack.calledWith(
- row[column.dataField], newValue, row, column)
- ).toBe(true);
- });
- });
- });
-
- describe('if cellEdit.beforeSaveCell prop defined', () => {
- const beforeSaveCellCallBack = sinon.stub();
- beforeEach(() => {
- cellEdit.beforeSaveCell = beforeSaveCellCallBack;
- wrapper = shallow(
-
- );
- wrapper.instance().handleCellUpdate(row, column, newValue);
- });
-
- it('should calling cellEdit.beforeSaveCell correctly', () => {
- expect(beforeSaveCellCallBack.callCount).toBe(1);
- expect(beforeSaveCellCallBack.calledWith(
- row[column.dataField], newValue, row, column)
- ).toBe(true);
- });
- });
- });
-});
diff --git a/packages/react-bootstrap-table2/test/cell.test.js b/packages/react-bootstrap-table2/test/cell.test.js
index 49d9458..b83bcc9 100644
--- a/packages/react-bootstrap-table2/test/cell.test.js
+++ b/packages/react-bootstrap-table2/test/cell.test.js
@@ -2,7 +2,6 @@ import React from 'react';
import sinon from 'sinon';
import { shallow } from 'enzyme';
-import Const from '../src/const';
import Cell from '../src/cell';
describe('Cell', () => {
@@ -462,7 +461,7 @@ describe('Cell', () => {
onStartCallBack = sinon.stub().withArgs(rowIndex, columnIndex);
});
- describe(`and editMode is ${Const.CLICK_TO_CELL_EDIT}`, () => {
+ describe('and clickToEdit is true', () => {
beforeEach(() => {
wrapper = shallow(
{
column={ column }
columnIndex={ columnIndex }
editable
- editMode={ Const.CLICK_TO_CELL_EDIT }
+ clickToEdit
onStart={ onStartCallBack }
/>
);
@@ -502,7 +501,7 @@ describe('Cell', () => {
});
});
- describe(`and editMode is ${Const.DBCLICK_TO_CELL_EDIT}`, () => {
+ describe('and dbclickToEdit is true', () => {
beforeEach(() => {
wrapper = shallow(
{
column={ column }
columnIndex={ 1 }
editable
- editMode={ Const.DBCLICK_TO_CELL_EDIT }
+ dbclickToEdit
onStart={ onStartCallBack }
/>
);
diff --git a/packages/react-bootstrap-table2/test/container.test.js b/packages/react-bootstrap-table2/test/container.test.js
index 066a948..291e4cc 100644
--- a/packages/react-bootstrap-table2/test/container.test.js
+++ b/packages/react-bootstrap-table2/test/container.test.js
@@ -51,8 +51,15 @@ describe('container', () => {
});
describe('when cellEdit prop is defined', () => {
+ const wrapperFactory = Base => class CellEditWrapper extends React.Component {
+ render() { return ; }
+ };
+
const cellEdit = {
- mode: 'click'
+ wrapperFactory,
+ options: {
+ mode: 'click'
+ }
};
beforeEach(() => {
diff --git a/packages/react-bootstrap-table2/test/props-resolver/index.test.js b/packages/react-bootstrap-table2/test/props-resolver/index.test.js
index 7f4cf59..1b6bf8c 100644
--- a/packages/react-bootstrap-table2/test/props-resolver/index.test.js
+++ b/packages/react-bootstrap-table2/test/props-resolver/index.test.js
@@ -72,64 +72,6 @@ describe('TableResolver', () => {
});
});
- describe('resolveCellEditProps', () => {
- describe('if cellEdit prop not defined', () => {
- beforeEach(() => {
- const mockElement = React.createElement(BootstrapTableMock, {
- data, keyField, columns
- }, null);
- wrapper = shallow(mockElement);
- });
-
- it('should resolve a default cellEdit instance', () => {
- const cellEdit = wrapper.instance().resolveCellEditProps();
- expect(cellEdit).toBeDefined();
- expect(cellEdit.mode).toEqual(Const.UNABLE_TO_CELL_EDIT);
- expect(cellEdit.nonEditableRows.length).toEqual(0);
- });
- });
-
- describe('if cellEdit prop defined', () => {
- const expectNonEditableRows = [1, 2];
- const cellEdit = {
- mode: Const.DBCLICK_TO_CELL_EDIT,
- blurToSave: true,
- beforeSaveCell: sinon.stub(),
- afterSaveCell: sinon.stub(),
- nonEditableRows: sinon.stub().returns(expectNonEditableRows)
- };
-
- beforeEach(() => {
- const mockElement = React.createElement(BootstrapTableMock, {
- data, keyField, columns, cellEdit
- }, null);
- wrapper = shallow(mockElement);
- });
-
- it('should resolve a cellEdit correctly', () => {
- const cellEditInfo = wrapper.instance().resolveCellEditProps();
- expect(cellEditInfo).toBeDefined();
- expect(cellEditInfo.mode).toEqual(cellEdit.mode);
- expect(cellEditInfo.onUpdate).toEqual(cellEdit.onUpdate);
- expect(cellEditInfo.blurToSave).toEqual(cellEdit.blurToSave);
- expect(cellEditInfo.beforeSaveCell).toEqual(cellEdit.beforeSaveCell);
- expect(cellEditInfo.afterSaveCell).toEqual(cellEdit.afterSaveCell);
- expect(cellEditInfo.nonEditableRows).toEqual(expectNonEditableRows);
- });
-
- it('should attach options to cellEdit props', () => {
- const something = {
- test: 1,
- cb: sinon.stub()
- };
- const cellEditInfo = wrapper.instance().resolveCellEditProps(something);
- expect(cellEditInfo).toBeDefined();
- expect(cellEditInfo.test).toEqual(something.test);
- expect(cellEditInfo.cb).toEqual(something.cb);
- });
- });
- });
-
describe('resolveSelectRowProps', () => {
let cellSelectionInfo;
let selectRow;
diff --git a/packages/react-bootstrap-table2/test/row.test.js b/packages/react-bootstrap-table2/test/row.test.js
index a44e52f..955a421 100644
--- a/packages/react-bootstrap-table2/test/row.test.js
+++ b/packages/react-bootstrap-table2/test/row.test.js
@@ -5,7 +5,6 @@ import { shallow } from 'enzyme';
import Cell from '../src/cell';
import Row from '../src/row';
import Const from '../src/const';
-import EditingCell from '../src/cell-edit/editing-cell';
import SelectionCell from '../src//row-selection/selection-cell';
import mockBodyResolvedProps from './test-helpers/mock/body-resolved-props';
@@ -97,7 +96,9 @@ describe('Row', () => {
beforeEach(() => {
columns = defaultColumns;
cellEdit = {
- mode: Const.CLICK_TO_CELL_EDIT
+ mode: 'click',
+ CLICK_TO_CELL_EDIT: 'click',
+ DBCLICK_TO_CELL_EDIT: 'dbclick'
};
wrapper = shallow(
{
}
});
- it('Cell component should receive correct editMode props', () => {
+ it('Cell component should receive correct clickToEdit props', () => {
expect(wrapper.length).toBe(1);
for (let i = 0; i < columns.length; i += 1) {
- expect(wrapper.find(Cell).get(i).props.editMode).toEqual(cellEdit.mode);
+ expect(wrapper.find(Cell).get(i).props.clickToEdit).toBeTruthy();
}
});
+ it('Cell component should receive correct dbclickToEdit props', () => {
+ expect(wrapper.length).toBe(1);
+ for (let i = 0; i < columns.length; i += 1) {
+ expect(wrapper.find(Cell).get(i).props.dbclickToEdit).toBeFalsy();
+ }
+ });
+
+ describe('when props.cellEdit.mode is dbclick', () => {
+ beforeEach(() => {
+ cellEdit.mode = cellEdit.DBCLICK_TO_CELL_EDIT;
+ wrapper = shallow(
+
+ );
+ });
+
+ it('Cell component should receive correct clickToEdit props', () => {
+ expect(wrapper.length).toBe(1);
+ for (let i = 0; i < columns.length; i += 1) {
+ expect(wrapper.find(Cell).get(i).props.clickToEdit).toBeFalsy();
+ }
+ });
+
+ it('Cell component should receive correct dbclickToEdit props', () => {
+ expect(wrapper.length).toBe(1);
+ for (let i = 0; i < columns.length; i += 1) {
+ expect(wrapper.find(Cell).get(i).props.dbclickToEdit).toBeTruthy();
+ }
+ });
+ });
+
describe('and column.editable defined false', () => {
const nonEditableColIndex = 1;
beforeEach(() => {
@@ -266,6 +304,7 @@ describe('Row', () => {
// Means a cell now is undering editing
describe('when cellEdit.ridx and cellEdit.cidx is defined', () => {
+ const EditingCell = () => null;
describe('and cellEdit.ridx is match to current row index', () => {
const editingColIndex = 1;
beforeEach(() => {
@@ -273,6 +312,7 @@ describe('Row', () => {
cellEdit.cidx = editingColIndex;
cellEdit.onUpdate = sinon.stub();
cellEdit.onEscape = sinon.stub();
+ cellEdit.EditingCell = EditingCell;
wrapper = shallow(
(
-
-
- { props.children }
-
-
-);
-
| |