react-jsonschema-form
react-jsonschema-form copied to clipboard
Set parent formdata from custom ArrayFieldTemplate
Prerequisites
- [X] I have read the documentation
What theme are you using?
mui
What is your question?
Hi 👋🏼
(I created an issues 2 weeks ago https://github.com/rjsf-team/react-jsonschema-form/issues/3143 but I saw later that somehow I didn't use a template, so posting it again and closing the other one)
I'm trying to create a custom view for specifically string based arrays. I would like to use the MUI-5 autocomplete component with tags as it would save a lot of real estate for our use case (https://mui.com/material-ui/react-autocomplete/#multiple-values)
I got quite far with the code snippet below in my custom ArrayFieldTemplate
.
{props.schema.items.type === 'string' ? (
<Autocomplete
multiple
freeSolo
options={[]}
onChange={(_, values, reason, details) => {
props.formData.splice(0, props.formData.length)
for (let i = 0; i < values.length; i++) {
props.formData[i] = values[i]
}
console.log('custom ArrayFieldTemplate props.formData', props.formData)
}}
renderInput={(params) => (
<TextField {...params} label={props.title} />
)}
renderTags={(value: readonly string[], getTagProps) =>
value.map((option: string, index: number) =>
(<Chip variant="outlined" label={option} {...getTagProps({index})} />))
}
/>
)
it looks like this
But sadly the changes to props.formData are not propagated to the parent formData, as shown in the screenshot below (I'm assuming a readonly copy is sent to children?)

Anyways, my question is if there is a way to update the actual formdata from a custom template? Or is this a feature you see value in?
The challenge is that the ArrayFieldTemplate is not really designed to do what you want since it does not have access to the onChange
method which the Form
uses to update the formData
. Your best bet is to either override the ArrayField
itself or implementing a custom widget for the string array items, via the uiSchema
.
To implement the custom array field, you will probably want something like:
import { getDefaultRegistry } from '@rjsf/core';
import { FieldProps } from '@rjsf/utils`;
const { ArrayField } = getDefaultRegistry().fields;
export default function CustomArrayField(props: FieldProps) {
const { onChange, schema, formData } = props;
if ({props.schema.items.type === 'string') {
const handleChange = (_, values, reason, details) => {
const newFormData = { ...formData };
newFormData.splice(0, newFormData.length)
for (let i = 0; i < values.length; i++) {
newFormData[i] = values[i]
}
onChange(newFormData);
}
return ( // The rest of your implementation ... );
}
// Fall through to the default
return <ArrayField {...props} />;
}
Hi @heath-freenome , thanks for the response :)
I would like to apply this as the default for all string based arrays, would that be possible with uiSchema?
If you updated the above array field to detect the string based arrays and do the custom onChange
only for them, then you could just use the template without needing the uiSchema
, by passing your CustomArrayField template AS the ArrayField
template to the Form
as follows:
<Form {...otherProps} templates={{ ArrayFieldTemplate: CustomArrayField }} />
This issue has been automatically marked as possibly close because it has not had recent activity. It will be closed if no further activity occurs. Please leave a comment if this is still an issue for you. Thank you.
This issue was closed because of lack of recent activity. Reopen if you still need assistance.