Hawkzey
Hawkzey

Reputation: 1153

rjsf Form is scrolling back to top and un-focusing input field on button press inside custom widget

I need a custom widget because depending on the value of a different property linkType I want to render a different input type ( select, textarea )

I try to store the state from the form locally so that I can pass it as a prop into my widget however, when I do this the form scrolls back to the top on every keypress inside the input and also unfocused the input ( possible re-rendering the entire form ) even though only the link Action value has changed.

Form Component:

export const PageEditModalForm: FC<PageEditModalFormProps> = ({ onUpdate, onError, onCancel }) => {
const { currentFormData, currentSchema } = usePageContext();
const [formData, setFormData] = useState(currentFormData);

const customWidgets = useMemo(() => ({
    LinkTypeWidget
}), []);

const uiSchema: UiSchema = useMemo(() => ({
    'ui:submitButtonOptions': {
        norender: true
    },
    "ui:title": "",
    "links": {
        "items": {
            "linkAction": {
                "ui:widget": "LinkTypeWidget",
            },
            // "linkType": {
            //     "ui:widget": "LinkTypeOptionsWidget",
            // }
        }
    },
    "html": {
        "ui:widget": "textarea"
    },
}), []);

return (
    <ModalBox className="bb-edit-page-modal">
        {currentSchema &&
            <>
                {/*title is disabled in schema so can style it here */}
                <h2>{currentSchema.title}</h2>
                <Form
                    id={currentSchema.title}
                    schema={{ ...currentSchema }}
                    onChange={(e) => setFormData(e.formData)}
                    formData={{ ...formData }}
                    validator={validatorAjv8}
                    onError={onError}
                    widgets={customWidgets}
                    onSubmit={onUpdate}
                    uiSchema={uiSchema}
                >
                    <Grid container spacing={1} className="bb-flex bb-fixed">
                        <Grid item>
                            <Button onClick={onCancel} variant="text">
                                Cancel
                            </Button>
                        </Grid>
                        <Grid item className="bb-ml-auto">
                            <Button variant="contained" type="submit">
                                Update
                            </Button>
                        </Grid>
                    </Grid>
                </Form>
            </>
        }
    </ModalBox>
);

};

Custom Widget:

import React, { useCallback } from 'react';

import { TextField } from '@mui/material';

const LinkTypeWidget = (props: any) => { console.log("props", props); console.log("formContext", props.registry.formContext);

const handleChange = useCallback((event: any) => {
    const newValue = event.target.value;
    props.onChange(newValue);
}, [props]);

return (
    <TextField
        id={props.id}
        label="Outlined"
        variant="outlined"
        value={props.value}
        onChange={handleChange}
    />
);

};

export { LinkTypeWidget };

Upvotes: 0

Views: 24

Answers (1)

Hawkzey
Hawkzey

Reputation: 1153

Turns out {currentSchema && was causing re-rendering issues removing this fixed all my problems

Upvotes: 1

Related Questions