I'm using Ant Design and I have the following trouble with Forms.
I have a custom ponent which wraps an antd AutoComplete with the code required to fetch autoplete suggestions remotely:
const ProductComplete = () => {
const [value, setValue] = React.useState('')
const [options, setOptions] = React.useState([])
const onSearch = searchText => {
fetchProductsFromServer(searchText)
.then(options => options.map(o => ({value: o})))
.then(options => setOptions(options))
}
const onChange = data => {
setValue(data)
}
return (
<AutoComplete
value={value}
options={options}
onSearch={onSearch}
onChange={onChange}
/>
)
}
but when I use it in an antd Form :
return (
<Form
{...formLayout}
ref={this.formRef}
>
<Form.Item
name={'product'}
label={'Product'}
rules={[{
required: true
}]}
>
<ProductComplete/>
</Form.Item>
</Form>
when I trigger validation externally thus : let fieldsValue = await this.formRef.current.validateFields()
the form behaves as if there's nothing in the field and signals the user that the field is required as per the validation rule specified (even when there is text in the AutoComplete)
However, if I were to wire the AutoComplete directly into the ponent holding the Form, rather than have it packaged as it's own ponent (as above), it works fine though !
return (
<Form
{...formLayout}
ref={this.formRef}
>
<Form.Item
name={'product'}
label={'Product'}
rules={[{
required: true
}]}
>
<AutoComplete
value={this.state.product}
options={this.state.products}
onSearch={(searchText) => this.onSearchProducts(searchText)}
onChange={(value) => this.onChange(value)}
/>
</Form.Item>
</Form>
Any ideas why this may be ?
Cheers!
I'm using Ant Design and I have the following trouble with Forms.
I have a custom ponent which wraps an antd AutoComplete with the code required to fetch autoplete suggestions remotely:
const ProductComplete = () => {
const [value, setValue] = React.useState('')
const [options, setOptions] = React.useState([])
const onSearch = searchText => {
fetchProductsFromServer(searchText)
.then(options => options.map(o => ({value: o})))
.then(options => setOptions(options))
}
const onChange = data => {
setValue(data)
}
return (
<AutoComplete
value={value}
options={options}
onSearch={onSearch}
onChange={onChange}
/>
)
}
but when I use it in an antd Form :
return (
<Form
{...formLayout}
ref={this.formRef}
>
<Form.Item
name={'product'}
label={'Product'}
rules={[{
required: true
}]}
>
<ProductComplete/>
</Form.Item>
</Form>
when I trigger validation externally thus : let fieldsValue = await this.formRef.current.validateFields()
the form behaves as if there's nothing in the field and signals the user that the field is required as per the validation rule specified (even when there is text in the AutoComplete)
However, if I were to wire the AutoComplete directly into the ponent holding the Form, rather than have it packaged as it's own ponent (as above), it works fine though !
return (
<Form
{...formLayout}
ref={this.formRef}
>
<Form.Item
name={'product'}
label={'Product'}
rules={[{
required: true
}]}
>
<AutoComplete
value={this.state.product}
options={this.state.products}
onSearch={(searchText) => this.onSearchProducts(searchText)}
onChange={(value) => this.onChange(value)}
/>
</Form.Item>
</Form>
Any ideas why this may be ?
Cheers!
Share Improve this question asked May 14, 2020 at 8:46 DefenestrateDefenestrate 4632 gold badges7 silver badges15 bronze badges1 Answer
Reset to default 10Nevermind I figured it out!
I somehow hadn't noticed the https://ant.design/ponents/form/#ponents-form-demo-customized-form-controls section on the Ant Design website.
I simply needed to pass the custom ponent a controlled value
property and onChange
event thus:
const ProductComplete = ({value = '', onChange}) => {
const [products, setProducts] = React.useState([])
const onSearch = searchText => {
fakeFetch(searchText)
.then(options => options.map(o => ({value: o})))
.then(options => setProducts(options))
}
const handleChange = (value) => {
if (onChange) {
onChange(value)
}
}
return (
<AutoComplete
value={value}
options={products}
onSearch={onSearch}
onChange={handleChange}
/>
)
}
Works fine now. Pretty obvious really .
Cheers