<Form
layout="vertical"
size="medium"
className="test-form"
requiredMark={false}
onFinish={onFinish}
>
<Form.Item
name="companyId"
label="Company/Customer"
rules={[{ required: true, message: "Please select Company!"}]}
>
<Select
onChange={this.handleSelectCompanyOnchange}
style={{ width: "50%" }}
name="companyId"
>
{users.map((user, index) => {
return (
<Option key={index} value={user.companyID}>
{user.companyName}
</Option>
);
})}
</Select>
</Form.Item>
<Form.Item
label="Products"
name="products"
rules={[{ required: true, message: "Please select Products!"}]}
>
<Select mode="multiple" allowClear style={{ width: "70%" }}>
{products.map((product, index) => {
if (this.state.companyId == product.companyId) {
return (
<Option key={index} value={product.id}>
{product.productName}
</Option>
);
}
})}
</Select>
</Form.Item>
</Form>
I am trying to achieve Options in Products Select element changes according to the Company Select onChange selection.
I have specified onChange in Select and calling this.handleSelectCompanyOnchange. In which I get selected companyId.
In this.state.companyId I had set companyId manually which I will remove.
I am really new to ant design and not able to figure out how to update the Products list once Company is selected.
Here, users and products are json as below.
users:
[{
companyID: 2
companyName: "TEST1"
},{
companyID: 7
companyName: "TEST2"
}]
products:
[{
companyId: 2
id: 1
productName: "TESTProduct1"
},{
companyId: 7
productName: "TESTProduct2"
id: 2
},{
companyId: 7
id: 3
productName: "TESTProduct3"
},{
companyId: 7
id: 4
productName: "TESTProduct4"
}]
However, I have tried getValueFromEvent but not able to achieve this. I am using Ant design Form and Select for this. Also I did referred to https://github.com/ant-design/ant-design/issues/4862 and how to get field value on change for FormItem in antd
Here is what you need to achieve it.
Use onValuesChange
prop of the Form
. This is the best place to perform setState when it comes to antd Form
field changes, not on Select
or Input
onChange
.
<Form onValuesChange={handleFormValuesChange}>
...
</Form>
A form instance (hook). This is optional in your case, but this is useful on setting and getting form values. See more here about it.
const [form] = Form.useForm();
<Form form={form} onValuesChange={handleFormValuesChange}>
...
</Form>
This is the product options render looks like, a combination of map
and filter
where selectedCompanyId
comes from state. Take note that don't use index as key
if the fixed length of the list is unknown, the react will confuse on this and you will get some logical error. Use some unique id.
<Form.Item label="Products" name="product">
<Select>
{products
.filter((product) => product.companyId === selectedCompanyId)
.map((product) => (
<Option key={product.id} value={product.id}>
{product.productName}
</Option>
))}
</Select>
</Form.Item>
And here is the handleFormValuesChange
const handleFormValuesChange = (changedValues) => {
const formFieldName = Object.keys(changedValues)[0];
if (formFieldName === "company") {
setSelectedCompanyId(changedValues[formFieldName]); // perform setState here
form.setFieldsValue({product: undefined}) //reset product selection
}
};
Here is the complete working code in react hooks: