Reputation: 463
I'm using Ant Design and I have the following trouble with Forms.
I have a custom component which wraps an antd AutoComplete with the code required to fetch autocomplete 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 component holding the Form, rather than have it packaged as it's own component (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!
Upvotes: 4
Views: 4027
Reputation: 463
Nevermind I figured it out!
I somehow hadn't noticed the https://ant.design/components/form/#components-form-demo-customized-form-controls section on the Ant Design website.
I simply needed to pass the custom component 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
Upvotes: 10