Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't custom input controls validation properly in Ant Design forms?

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!

like image 283
ChambreNoire Avatar asked Oct 23 '25 19:10

ChambreNoire


1 Answers

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

like image 153
ChambreNoire Avatar answered Oct 26 '25 07:10

ChambreNoire