react-select可创建选项-添加组标签

时间:2018-11-08 10:21:20

标签: javascript reactjs react-redux react-select

我创建了一个利用react-select和可创建功能的酷沙盒。它允许您从预填充的下拉列表中进行选择,同时通过在选择字段中键入来创建自定义选项。在字段中键入后,您的选项将在选择列表中可用。

我添加了要分组的选项-预先存在的字段很好,但是我希望通过默认值将新选项分组,例如“新组”。

任何帮助将不胜感激。

https://codesandbox.io/s/p5x7m478rm

import React from "react";
import { Field, reduxForm, FieldArray } from "redux-form";
import TextField from "material-ui/TextField";
import { RadioButton, RadioButtonGroup } from "material-ui/RadioButton";
import Checkbox from "material-ui/Checkbox";
import SelectField from "material-ui/SelectField";
import MenuItem from "material-ui/MenuItem";
import asyncValidate from "./asyncValidate";
import validate from "./validate";
import CreatableSelect from "react-select/lib/Creatable";
const CustomStyle = {
  option: (base, state) => ({
    ...base,
    display: "inline",
    marginRight: "10px",
    backgroundColor: state.isSelected ? "#00285C" : "#eee",
    cursor: "pointer"
  }),
  menuList: () => ({
    padding: 10,
    display: "inline-flex"
  }),
  menu: () => ({
    position: "relative"
  })
};

const createOption = (label: string) => ({
  label,
  value: label.toLowerCase().replace(/\W/g, "")
});

const formatGroupLabel = data => (
  <div>
    <span>{data.label}</span>
  </div>
);

class LastNameSelectInput extends React.Component {
  constructor(props) {
    super(props);
  }

  state = {
    value: this.props.options[0].options,
    options: this.props.options
  };
  handleCreate = input => (inputValue: any) => {
    this.setState({ isLoading: true });
    setTimeout(() => {
      const { options, value } = this.state;
      const newOption = createOption(inputValue);
      this.setState({
        isLoading: false,
        options: [...options, newOption],
        value: newOption,
        formatGroupLabel: "new label"
      });
      input.onChange(newOption);
    }, 1000);
  };

  isValidNewOption = (inputValue, selectValue, selectOptions) => {
    if (
      inputValue.trim().length === 0 ||
      selectOptions.find(option => option.name === inputValue)
    ) {
      return false;
    }
    return true;
  };

  render() {
    const { input, options } = this.props;
    return (
      <div>
        <style>
          {`.react-select__dropdown-indicator,.react-select__indicator-separator {
          display: none;
        }`}
        </style>
        <CreatableSelect
          classNamePrefix="react-select"
          options={this.state.options}
          menuIsOpen={true}
          onChange={value => {
            let newValue = input.onChange(value);
            this.setState({ value: newValue });
          }}
          onBlur={() => input.onBlur(input.value)}
          onCreateOption={this.handleCreate(input)}
          value={this.state.value}
          styles={CustomStyle}
          isClearable
          isValidNewOption={this.isValidNewOption}
          formatGroupLabel={formatGroupLabel}
        />
      </div>
    );
  }
}

const MaterialUiForm = props => {
  const { handleSubmit, options, pristine, reset, submitting } = props;

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <Field name="option" component={LastNameSelectInput} {...props} />
      </div>
    </form>
  );
};

export default reduxForm({
  form: "MaterialUiForm", // a unique identifier for this form
  validate,
  asyncValidate
})(MaterialUiForm);

1 个答案:

答案 0 :(得分:1)

为了实现您的目标,我更改了您提供的功能handleCreateoptions道具。您可以看到一个实时示例here

MaterialUiForm.js

handleCreate = input => (inputValue: any) => {
this.setState({ isLoading: true });
setTimeout(() => {
  const { options } = this.state;
  const newOption = createOption(inputValue);
  options.map(option => {
    if (option.label === "New group") {
      return {
        label: option.label,
        options: option.options.push(newOption)
      };
    }
    return option;
  });
  this.setState({
    isLoading: false,
    options: [...options],
    value: newOption,
    formatGroupLabel: "new label"
  });
  input.onChange(newOption);
}, 1000);

index.js

<MaterialUiForm
      onSubmit={showResults}
      initialValues={{
        option: colourOptions,
        option: flavourOptions
      }}
      options={[
        {
          label: "New group",
          options: []
        },
        {
          label: "Colours",
          options: colourOptions
        },
        {
          label: "Flavours",
          options: flavourOptions
        }
      ]}
    />

有不同的方法,也许是更聪明的方法,但是逻辑是好的。