11

I have 2 <Select>'s. The values in the second are dependant on the selection made on the first. When I change the selected item in the first, the available options on the second update. But if I already have a selection made on the second, that option remains selected even if it isn't supposed to be available based on a change to the first select.

How can I reset the second select to have nothing selected when a change is made to the first select?

First Select:

<FormItem {...formTailLayout}>
    <FormTitle>Operation</FormTitle>
    {getFieldDecorator('Operation', {
    rules: [
        {
        required: true
        }
    ]
    })(
    <Select
        showSearch
        placeholder="Select an option"
        onChange={this.handleOperationChange}
    >
        {operations.map(operation => (
        <Option value={operation.operation_id}>
            {operation.operation_name}
        </Option>
        ))}
    </Select>
    )}
</FormItem>

Second Select:

<FormItem {...formTailLayout}>
    <FormTitle>Metric</FormTitle>
    {getFieldDecorator('Metric', {
    rules: [
        {
        required: true
        }
    ]
    })(
    <Select
        showSearch
        placeholder="Select an operation first"
        onChange={this.handleMetricChange}
    >
        {matrics
        .filter(
            metric => metric.operation_fk === operation_fk
        )
        .map(metric => (
            <Option value={metric.metric_name}>
            {metric.metric_name}
            </Option>
        ))}
    </Select>
    )}
</FormItem>
Kieran Quinn
  • 1,085
  • 2
  • 22
  • 49
  • Simply you can write a function to reset options of 2nd Select, and call it at end inside your `handleOperationChange` function. – Vipin Yadav Apr 26 '19 at 08:48
  • What action should that function perform though? I tried setting the value to '' and null, neither had any effect. – Kieran Quinn Apr 26 '19 at 08:57
  • That depends on how you are handling your `Select` and `Option` components. Use some custom code (A ternary operator) to check if the selected option is `empty` or `null`. As I see you not using native html elements, so can't promise this will work. Check https://reactjs.org/docs/forms.html#the-select-tag – Vipin Yadav Apr 26 '19 at 09:09

6 Answers6

11

You need to take a look at Coordinated Controls example mentioned on ant-design page. You can simply use setFieldsValue in your first onChange method to set the value of second select field.

handleOperationChange = () => {
    this.props.form.setFieldsValue({
        Metric: undefined
    })
}

I have created a sandbox demo.

Triyugi Narayan Mani
  • 3,039
  • 8
  • 36
  • 56
3

In antd, In Class Component, Using Ref, Clear or reset select list value or form item value

  1. add formRef = React.createRef(); just below class component, like:

    export default class TestClass extends Component { formRef = React.createRef(); }

  2. add ref={this.formRef} in <Form /> component like this <Form ref={this.formRef}/>

  3. add this line on btn click or in any function you want

this.formRef.current.setFieldsValue({ network: undefined });

  1. Here network in above step is the name of form item

    <Form.Item name="network" label="Network"></Form.Item>

Jefferson
  • 794
  • 10
  • 24
Lalit Garghate
  • 119
  • 1
  • 5
  • 1
    Why are you using imgur.com to write parts of the answer? Code blocks and images are supported in Stack Overflow. Please Google how to include code and images in SO. This answer should be edited. – Harshay Buradkar Sep 26 '20 at 16:25
  • 1
    Please add code, errors, and data as **text** ([using code formatting](/editing-help#code)), not images. Images: A) can't be copy-&-pasted for testing; B) don't permit searching based on the code/error/data contents; and [many more reasons](//meta.stackoverflow.com/a/285557). In general, code/errors/data in text format are much, *much* better than code/errors/data as an image, which are somewhat better than nothing. Images should only be used, in addition to text in code format, if having the image adds something significant that is not conveyed by just the text code/error/data. – Makyen Sep 26 '20 at 18:52
1

If functional component is used, then we can use Form:

const [form] = Form.useForm()

and it is possible to clear value like this:

const someMethodToClearCurrentSelection = () => {
    // ... the code is omitted for the brevity
    form.setFieldsValue({ fooProduct: undefined })
}

and our control looks like this:

<Form form={form} name="basic" onFinish={onFinish} layout="vertical">
<Form.Item
    key="fooProduct"
    name="fooProduct"
    label="Some product"
    className={s.fooContainer}
    rules={[
        {
            required: true,
            message: `Field 'Some produc' is required`,
        },
    ]}
>
    <Select
        showSearch
        optionFilterProp="children"
        filterOption={(input, option) =>
            option?.children.toLowerCase().includes(input.toLowerCase())
        }
        allowClear
        onChange={handleMarkClick}
    >
        {products.map((option) => (
            <Option key={option.id} value={option.id}>
                {option.name}
            </Option>
        ))}
    </Select>
</Form.Item>

Read more in antd docs here and examples while migrating from v3 to v4

StepUp
  • 36,391
  • 15
  • 88
  • 148
0

Inside handleOperationChange method use resetfileds, this gonna reset your second select box.

this.props.form.resetFields('Metric');
Hemanthvrm
  • 2,319
  • 1
  • 17
  • 26
0
<Select
    className="mt-3"
    style={{ width: "100%" }}
    placeholder="Select your Sub Category"
    onChange={handleChangeSubCategory}
    disabled={categoryGroup.category === null}
    value={categoryGroup.subcategory || undefined}
 >
    {subCategory.map(item => (
      <Option key={item} value={item} label={item}>
         <div>
            <Avatar style={{ background: "#10899e" }}>
               {item[0]}
            </Avatar>{" "}
                {item}
             </div>
       </Option>
       ))}
</Select>
  • 6
    Welcome Paulo to stackoverflow.com. Please provide some description of your answer. What did you do and why. Also links to some official help can be very useful for community – Anatoli Klamer May 12 '20 at 12:54
0

You can make use of the useEffect() hook. Define a useForm() custom hook fir your form. Example: const [form] = Form.useForm();` Wrap your 1st and 2nd select boxes inside the form and use <Form.Item> to define the input on the form. And whenever the first select's input is changed, clear the 2nd select values in useEffect() hook. Example:

  useEffect(() => {
    form.setFieldsValue({
      marketplace: [] //2nd select name
    });
  }, [selectedRegion]); //first select's value

This work perfect for me.