Scrolling dynamically to an element in react-hook

3.4k views Asked by At

For my React hook based component(I am using Ant design framework), I have a large set of form inputs. My requirement is, whenever, user tries to submit the form without abiding the validating rule of the form, the focus will be scrolled to the first input element with such error situation. Here is what my form looks like,

 <Form onSubmit={handleSubmit}>
     <div>
         <Form.Item validateStatus={error['market-outlet'] ? 'error' : ''}
                            help={error['market-outlet'] ? error['market-outlet'] : ''}>
             <Select
                     onChange={handleSelectChange}
                     id="market-outlet"
             >
                 <Option>option 1</Option>
                 <Option>option 2</Option>
                 <Option>option 3</Option>
            </Select>
            <Form.Item validateStatus={error['manufacturer-name'] ? 'error' : ''}
                            help={error['manufacturer-name'] ? error['manufacturer-name'] : ''}>
                            <Input
                                onChange={handleDefaultChange}
                                id="manufacturer-name"
                                value={formData.manufacturer}
                            />
            </Form.Item>
            <Form.Item
                            validateStatus={error['manufacturer-contact'] ? 'error' : ''}
                            help={
                                error['manufacturer-contact'] ? error['manufacturer-contact'] : ''
                            }
                        >
                            <Tooltip title={displayIndustryContact}>
                                <Input
                                    //ref={errorInput}
                                    id="manufacturer-contact"
                                    onChange={handleContactChange}
                                    value={displayIndustryContact}
                                />
                            </Tooltip>
                        </Form.Item>
     </div>
 </Form>

For simplicity, I just added three fields from my entire form and you can see that each field has this validation. Now my question is, how to identify a particular field when user fill up that field and scroll up to that field ? Here is my function where I am checking for if form has error,

const isDataValid = () => {
    const errors = validate();
    setLoading(true);

    let valid = true;

    if (Object.values(errors).length) {
        setError(errors);
        setLoading(false);
        simpleLoadingNotification(AlertTypeEnum.ERROR, 'Error !', JSON.stringify(errors, null, ' '));
        valid = false;
        
        //scrolling upto the first element
        const firstProp = Object.keys(errors)[0];
        setFirstErrorElement(firstProp);
        
    }

    return valid;
};

I want to identify the first erroneous element from this above function and bring this element to focus. Therefore, I am setting a state depending on the element id such as,

setFirstErrorElement(firstProp);

I did then a useEffect call such as,

React.useEffect(() => {

    let elem = document.getElementById(firstErrorElement);
    //elem.scroll(0,0);
    if(firstErrorElement != ''){
        elem.scrollTo(0,0); 
    }
    
},[firstErrorElement]);

But the control is not scrolled to that particular element. I know, I can use useRef. But how to set reference dynamically for these elements through my isDataValid function ? My form component also contains nested components. Does useRef is enough to catch error scenario for nested components.

Any idea to solve this problem is very much appreciated.

0

There are 0 answers