Closed KKS1 closed 5 years ago
I have made a solution for something similar as this. I have field that fetches data from an API and populates other fields with that data. As far as I know there is not a readymade solution for this.
Simplified code below
On my form I defined a custom formContext
<Form formContext={{ updateOtherForms: this.updateOtherForms }} >
This formContext has a simple function that updates formData (I dont use local state for formData, so you have to make this one out a little bit your self)
updateOtherForms = (newContent) => {
this.props.updatePartOfStateObject('formData', newContent)
}
Then in my ui:schema
for the requested parameter I have added a custom property that maps data from the incomming API-request to other fields. By doing it this way it is simple to reuse the API-fetcher without having to modify my widget.
'url': {
'ui:field': 'fetchAPI',
'ui:options': {
'populate': {
'headline': 'title',
'text': 'lead',
'image.url': 'image.crops.16:9.80'
}
}
},
Lastly my widget runs this function when the user clicks a button to fetch data (I have also added options to use queryparameters on the populate-data as well to modify incoming data, but I have left that part out here to simplify)
handleClick = (e) => {
const fields = {...this.props.uiSchema['ui:options'].populate}
const content = []
Object.keys(fields).forEach(function (key) {
content.push({ ['content.' + key]: fields[key] })
})
this.props.formContext.updateOtherForms(content)
}
Hope this helps!
Thanks @christianeide . Appreciate the help. The way I finally resolved this, is by creating a custom Address
field, which comprises of all the widgets city
, state
, zip
etc. The Address field, then, takes object
type and updates/ persists the formData properties, to populate all the underlying widgets its rendering.
Closing this issue, but feel free to repoen it if you have any additional questions!
Thanks @christianeide . Appreciate the help. The way I finally resolved this, is by creating a custom
Address
field, which comprises of all the widgetscity
,state
,zip
etc. The Address field, then, takesobject
type and updates/ persists the formData properties, to populate all the underlying widgets its rendering.
Hi. Could you, please, provide more details about your solution? I need to solve a similar task - one widget populates many other fields (like you select a user and its email, name, age are being populated in other fields. all the data is retrieved by the 'main' widget). I understood christianeide's solution: he adds a function which updates formData to formContext and this formContext object is passed to every widget. So, when widget fires onChange it can also call that function and modify formData on global level. Your solution seems more correct to me, but I don't understand how it works:
Hi @OleksiL , here is a glimpse:
Use uiSchema
uiSchema = {
......,
'addressFieldName': {
'ui:field': 'address'
},
....
}
where we have also, provided our RJSF Form, a set of custom fields
and widgets
that you want to register. E.g. in this case (simplified version)
const customFields = {
....,
address: CustomAddress, // (this is your custom Address Field component, which will be registered within Form as `address` field),
...
}
Then,
<Form
fields={customFields}
.....
>
For schema
now, this will look like
schema = {
...,
addressFieldName: {
type: 'object',
title: ' ',
properties: {
city: {
type: 'string'
},
zip: {
type: 'string'
}
},
....
}
formData
will then contain an object addressFieldName
which will then have city
and zip
strings underneath.
Hope it helps, cheers!
-- kks1
I have made a solution for something similar as this. I have field that fetches data from an API and populates other fields with that data. As far as I know there is not a readymade solution for this.
Simplified code below
On my form I defined a custom formContext
<Form formContext={{ updateOtherForms: this.updateOtherForms }} >
This formContext has a simple function that updates formData (I dont use local state for formData, so you have to make this one out a little bit your self)
updateOtherForms = (newContent) => { this.props.updatePartOfStateObject('formData', newContent) }
Then in my
ui:schema
for the requested parameter I have added a custom property that maps data from the incomming API-request to other fields. By doing it this way it is simple to reuse the API-fetcher without having to modify my widget.'url': { 'ui:field': 'fetchAPI', 'ui:options': { 'populate': { 'headline': 'title', 'text': 'lead', 'image.url': 'image.crops.16:9.80' } } },
Lastly my widget runs this function when the user clicks a button to fetch data (I have also added options to use queryparameters on the populate-data as well to modify incoming data, but I have left that part out here to simplify)
handleClick = (e) => { const fields = {...this.props.uiSchema['ui:options'].populate} const content = [] Object.keys(fields).forEach(function (key) { content.push({ ['content.' + key]: fields[key] }) }) this.props.formContext.updateOtherForms(content) }
Hope this helps!
Hi @christianeide could you please share your code in a codepen? It would really help me, I have a similar task updating other fields with a zip code
Prerequisites
Description
Right now, a widget can update only the field it's associated with, using
prop.onChange
. I have a case, where one of the widgets is actually a google autocomplete address. This, requires emit or modify theformData
, so that other fields such ascity
,state
,zip
can also be updated informData
; and thus, to make the widgets associated with them pick the relevantformData
update, and fill in the value.Version
Latest ^1.2.0