diff --git a/examples/js/cell-edit/custom-cell-edit-table.js b/examples/js/cell-edit/custom-cell-edit-table.js new file mode 100644 index 000000000..d645136eb --- /dev/null +++ b/examples/js/cell-edit/custom-cell-edit-table.js @@ -0,0 +1,148 @@ +/* eslint max-len: 0 */ +/* eslint no-alert: 0 */ +/* eslint guard-for-in: 0 */ +/* eslint no-unused-vars: 0 */ +import React from 'react'; +import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table'; + + +const products = []; + +const currencies = [ 'USD', 'GBP', 'EUR' ]; +const regions = [ 'North', 'South', 'East', 'West' ]; + +function addProducts(quantity) { + const startId = products.length; + for (let i = 0; i < quantity; i++) { + const id = startId + i; + products.push({ + id: id, + name: 'Item name ' + id, + price: { + amount: 2100 + i, + currency: currencies[i % currencies.length] + }, + regions: regions.slice(0, (i % regions.length) + 1) + }); + } +} + +addProducts(5); + +const cellEditProp = { + mode: 'click' +}; + +class PriceEditor extends React.Component { + constructor(props) { + super(props); + this.updateData = this.updateData.bind(this); + this.state = { amount: props.defaultValue.amount, currency: props.defaultValue.currency }; + } + focus() { + this.refs.inputRef.focus(); + } + updateData() { + this.props.onUpdate({ amount: this.state.amount, currency: this.state.currency }); + } + render() { + return ( + + { this.setState({ amount: parseInt(ev.currentTarget.value, 10) }); } } /> + + + + ); + } +} + +class RegionsEditor extends React.Component { + constructor(props) { + super(props); + this.updateData = this.updateData.bind(this); + this.state = { regions: props.defaultValue }; + this.onToggleRegion = this.onToggleRegion.bind(this); + } + focus() { + } + onToggleRegion(event) { + const region = event.currentTarget.name; + if (this.state.regions.indexOf(region) < 0) { + this.setState({ regions: this.state.regions.concat([ region ]) }); + } else { + this.setState({ regions: this.state.regions.filter(r => r !== region) }); + } + } + updateData() { + this.props.onUpdate(this.state.regions); + } + render() { + const regionCheckBoxes = regions.map(region => ( + + -1 } + onChange={ this.onToggleRegion } /> + + + )); + return ( + + { regionCheckBoxes } + + + ); + } +} + +function priceFormatter(cell, row) { + return ` ${cell.amount}`; +} + +const regionsFormatter = (cell, row) => ({ (cell || []).join(',') }); + +const createPriceEditor = (onUpdate, props) => (); +const createRegionsEditor = (onUpdate, props) => (); + +export default class CustomCellEditTable extends React.Component { + render() { + return ( + + Product ID + Product Name + + Product Price + + + Regions + + + ); + } +} diff --git a/examples/js/cell-edit/demo.js b/examples/js/cell-edit/demo.js index 22611e98a..7d2eff9fc 100644 --- a/examples/js/cell-edit/demo.js +++ b/examples/js/cell-edit/demo.js @@ -5,6 +5,7 @@ import DbClickToEditTable from './dbclick-to-edit-table'; import BlurToSaveTable from './blur-to-save-table'; import CellEditHookTable from './cell-edit-hook-table'; import NonEditableTable from './non-editable-table'; +import CustomCellEditTable from './custom-cell-edit-table'; class Demo extends React.Component { render() { @@ -59,6 +60,15 @@ class Demo extends React.Component { +
+
+
Custom Cell Editor Example
+
+
Source in /examples/js/cell-edit/custom-cell-edit-table.js
+ +
+
+
); } diff --git a/src/BootstrapTable.js b/src/BootstrapTable.js index b422cc7fe..cb5187a89 100644 --- a/src/BootstrapTable.js +++ b/src/BootstrapTable.js @@ -124,6 +124,7 @@ class BootstrapTable extends Component { formatExtraData: column.props.formatExtraData, filterFormatted: column.props.filterFormatted, editable: column.props.editable, + customEditor: column.props.customEditor, hidden: column.props.hidden, hiddenOnInsert: column.props.hiddenOnInsert, searchable: column.props.searchable, diff --git a/src/TableBody.js b/src/TableBody.js index 6467f1cbc..844d818cb 100644 --- a/src/TableBody.js +++ b/src/TableBody.js @@ -52,13 +52,13 @@ class TableBody extends Component { completeEdit={ this.handleCompleteEditCell } // add by bluespring for column editor customize editable={ editable } + customEditor={ column.customEditor } format={ column.format ? format : false } key={ i } blurToSave={ this.props.cellEdit.blurToSave } rowIndex={ r } - colIndex={ i }> - { fieldValue } - + colIndex={ i } + fieldValue={ fieldValue } /> ); } else { // add by bluespring for className customize diff --git a/src/TableEditColumn.js b/src/TableEditColumn.js index 13803eddb..5848e4483 100644 --- a/src/TableEditColumn.js +++ b/src/TableEditColumn.js @@ -48,6 +48,10 @@ class TableEditColumn extends Component { } } + handleCustomUpdate = value => { + this.props.completeEdit(value, this.props.rowIndex, this.props.colIndex); + } + validator(value) { const ts = this; if (ts.props.editable.validator) { @@ -82,7 +86,7 @@ class TableEditColumn extends Component { } render() { - const { editable, format, children } = this.props; + const { editable, format, fieldValue, customEditor } = this.props; const { shakeEditor } = this.state; const attr = { ref: 'inputRef', @@ -93,9 +97,21 @@ class TableEditColumn extends Component { editable.placeholder && (attr.placeholder = editable.placeholder); const editorClass = classSet({ 'animated': shakeEditor, 'shake': shakeEditor }); + let cellEditor; + if (customEditor) { + const customEditorProps = { + ...attr, + defaultValue: fieldValue || '', + ...customEditor.customEditorParameters + }; + cellEditor = customEditor.getElement(this.handleCustomUpdate, customEditorProps); + } else { + cellEditor = editor(editable, attr, format, editorClass, fieldValue || ''); + } + return ( - { editor(editable, attr, format, editorClass, children || '') } + { cellEditor } ); @@ -116,7 +132,13 @@ TableEditColumn.propTypes = { blurToSave: PropTypes.bool, editable: PropTypes.oneOfType([ PropTypes.bool, PropTypes.object ]), format: PropTypes.oneOfType([ PropTypes.bool, PropTypes.func ]), - children: PropTypes.node + fieldValue: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.bool, + PropTypes.number, + PropTypes.array, + PropTypes.object + ]) };