From 4d76d88e9ad84295f6b9554d32dbcbb3a2687354 Mon Sep 17 00:00:00 2001 From: Allen Date: Sat, 8 Jun 2019 13:11:49 +0800 Subject: [PATCH] fix #945 (#967) --- .../react-bootstrap-table2-editor/README.md | 45 ++++- .../src/dropdown-editor.js | 26 ++- ...pdown-editor-with-dynamic-options-table.js | 155 ++++++++++++++++++ .../stories/index.js | 2 + 4 files changed, 222 insertions(+), 6 deletions(-) create mode 100644 packages/react-bootstrap-table2-example/examples/cell-edit/dropdown-editor-with-dynamic-options-table.js diff --git a/packages/react-bootstrap-table2-editor/README.md b/packages/react-bootstrap-table2-editor/README.md index f5d98aa..b4e6b99 100644 --- a/packages/react-bootstrap-table2-editor/README.md +++ b/packages/react-bootstrap-table2-editor/README.md @@ -89,7 +89,10 @@ const columns = [ In the following, we go though all the predefined editors: ### Dropdown Editor -Dropdown editor give a select menu to choose a data from a list, the `editor.options` is required property for dropdown editor. +Dropdown editor give a select menu to choose a data from a list. When use dropdown editor, either `editor.options` or `editor.getOptions` should be required prop. + +#### editor.options +This is most simple case for assign the dropdown options data directly. ```js import { Type } from 'react-bootstrap-table2-editor'; @@ -119,6 +122,46 @@ const columns = [ }]; ``` +#### editor.getOptions +It is much flexible which accept a function and you can assign the dropdown options dynamically. + +There are two case for `getOptions`: + +* *Synchronous*: Just return the options array in `getOptions` callback function +* *Asynchronous*: Call `setOptions` function argument when you get the options from remote. + + +```js +// Synchronous + +const columns = [ + ..., { + dataField: 'type', + text: 'Job Type', + editor: { + type: Type.SELECT, + getOptions: () => [.....] + } +}]; + +// Asynchronous + +const columns = [ + ..., { + dataField: 'type', + text: 'Job Type', + editor: { + type: Type.SELECT, + getOptions: (setOptions) => { + setTimeout(() => setOptions([...]), 1500); + } + } +}]; + +``` + +[here](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Cell%20Editing&selectedStory=Dropdown%20Editor%20with%20Dynamic%20Options) is an online example. + ### Date Editor Date editor is use ``, the configuration is very simple: diff --git a/packages/react-bootstrap-table2-editor/src/dropdown-editor.js b/packages/react-bootstrap-table2-editor/src/dropdown-editor.js index 166a208..a54bc4d 100644 --- a/packages/react-bootstrap-table2-editor/src/dropdown-editor.js +++ b/packages/react-bootstrap-table2-editor/src/dropdown-editor.js @@ -4,6 +4,15 @@ import cs from 'classnames'; import PropTypes from 'prop-types'; class DropDownEditor extends Component { + constructor(props) { + super(props); + let options = props.options; + if (props.getOptions) { + options = props.getOptions(this.setOptions.bind(this)) || []; + } + this.state = { options }; + } + componentDidMount() { const { defaultValue, didMount } = this.props; this.select.value = defaultValue; @@ -11,12 +20,16 @@ class DropDownEditor extends Component { if (didMount) didMount(); } + setOptions(options) { + this.setState({ options }); + } + getValue() { return this.select.value; } render() { - const { defaultValue, didMount, className, options, ...rest } = this.props; + const { defaultValue, didMount, getOptions, className, ...rest } = this.props; const editorClass = cs('form-control editor edit-select', className); const attr = { @@ -31,7 +44,7 @@ class DropDownEditor extends Component { defaultValue={ defaultValue } > { - options.map(({ label, value }) => ( + this.state.options.map(({ label, value }) => ( )) } @@ -52,13 +65,16 @@ DropDownEditor.propTypes = { label: PropTypes.string, value: PropTypes.any })) - ]).isRequired, - didMount: PropTypes.func + ]), + didMount: PropTypes.func, + getOptions: PropTypes.func }; DropDownEditor.defaultProps = { className: '', defaultValue: '', style: {}, - didMount: undefined + options: [], + didMount: undefined, + getOptions: undefined }; export default DropDownEditor; diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/dropdown-editor-with-dynamic-options-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/dropdown-editor-with-dynamic-options-table.js new file mode 100644 index 0000000..715346b --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/cell-edit/dropdown-editor-with-dynamic-options-table.js @@ -0,0 +1,155 @@ +/* eslint react/prefer-stateless-function: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import cellEditFactory, { Type } from 'react-bootstrap-table2-editor'; +import Code from 'components/common/code-block'; +import { jobsGenerator } from 'utils/common'; + +const jobs = jobsGenerator().map(j => ({ + ...j, + type2: j.type +})); + +const columns = [{ + dataField: 'id', + text: 'Job ID' +}, { + dataField: 'name', + text: 'Job Name' +}, { + dataField: 'owner', + text: 'Job Owner' +}, { + dataField: 'type', + text: 'Job Type1', + editor: { + type: Type.SELECT, + getOptions: () => [{ + value: 'A', + label: 'A' + }, { + value: 'B', + label: 'B' + }, { + value: 'C', + label: 'C' + }, { + value: 'D', + label: 'D' + }, { + value: 'E', + label: 'E' + }] + } +}, { + dataField: 'type2', + text: 'Job Type2', + editor: { + type: Type.SELECT, + getOptions: (setOptions) => { + setTimeout(() => { + setOptions([{ + value: 'A', + label: 'A' + }, { + value: 'B', + label: 'B' + }, { + value: 'C', + label: 'C' + }, { + value: 'D', + label: 'D' + }, { + value: 'E', + label: 'E' + }]); + }, 2000); + } + } +}]; + +const sourceCode = `\ +import BootstrapTable from 'react-bootstrap-table-next'; +import cellEditFactory, { Type } from 'react-bootstrap-table2-editor'; + +const columns = [{ + dataField: 'id', + text: 'Job ID' +}, { + dataField: 'name', + text: 'Job Name' +}, { + dataField: 'owner', + text: 'Job Owner' +}, { + dataField: 'type', + text: 'Job Type1', + editor: { + type: Type.SELECT, + getOptions: () => [{ + value: 'A', + label: 'A' + }, { + value: 'B', + label: 'B' + }, { + value: 'C', + label: 'C' + }, { + value: 'D', + label: 'D' + }, { + value: 'E', + label: 'E' + }] + } +}, { + dataField: 'type2', + text: 'Job Type2', + editor: { + type: Type.SELECT, + getOptions: (setOptions) => { + setTimeout(() => { + setOptions([{ + value: 'A', + label: 'A' + }, { + value: 'B', + label: 'B' + }, { + value: 'C', + label: 'C' + }, { + value: 'D', + label: 'D' + }, { + value: 'E', + label: 'E' + }]); + }, 2000); + } + } +}]; + + +`; + +export default () => ( +
+

Dropdown Editor with Dynamic Options

+ + { sourceCode } +
+); diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index d11abfb..ef179e0 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -125,6 +125,7 @@ import EditorStyleTable from 'examples/cell-edit/editor-style-table'; import EditorClassTable from 'examples/cell-edit/editor-class-table'; import DBClickEditWithSelection from 'examples/cell-edit/dbclick-to-edit-with-selection-table'; import DropdownEditorTable from 'examples/cell-edit/dropdown-editor-table'; +import DropdownEditorWithDynamicOptionsTable from 'examples/cell-edit/dropdown-editor-with-dynamic-options-table'; import TextareaEditorTable from 'examples/cell-edit/textarea-editor-table'; import CheckboxEditorTable from 'examples/cell-edit/checkbox-editor-table'; import DateEditorTable from 'examples/cell-edit/date-editor-table'; @@ -368,6 +369,7 @@ storiesOf('Cell Editing', module) .add('Custom Editor Style', () => ) .add('DoubleClick to Edit with Selection', () => ) .add('Dropdown Editor', () => ) + .add('Dropdown Editor with Dynamic Options', () => ) .add('Textarea Editor', () => ) .add('Checkbox Editor', () => ) .add('Date Editor', () => )