React Admin - how can I autofill (update) field values on change - react-admin

I have a Google places autocomplete input and need to populate address related fields based on selected place as below:
<GPAutocompleteInput
source="address_full"
placeholder="Find address"
onPlaceSelected={onPlaceSelected}
gaOptions={{ types: ["address"] }}
/>
<TextInput source="address_street" disabled label="Ulica" />
<TextInput source="address_postcode" disabled label="Kod pocztowy" />
<TextInput source="address_city" disabled label="Miasto" />
Now I would like the 3 disabled inputs to be filled in with the address components from the selected place but can't figure out how to do this.
I've tried providing initialValues to the SimpleForm component and this works ok in the create view but not in the edit because those fields already have a value the values are not being updated.

react-final-form provides a simple hook allowing me to change values
import { useForm } from "react-final-form";
const form = useForm();
form.change("address_city", components?.address_city);
There may be a better way as this requires building a custom component to use form context required by the hook.

Related

Add item to list with dynamic icon

When user adds new data to the list I want to add icon dynamically(social icons commonly) in react native. For example,when user adds item that has name facebook then facebook icon should be added in background to the list(item name may be face,fcb etc) How can I achieve this logic ?
Your question is quite vague but I'm guessing you're looking for what's called "conditional rendering".
<View>
{someCondition &&
<FacebookIcon />
}
</View>
The FacebookIcon component will only be rendered if someCondition is true.
So in your case, you probably wanna have a variable that is true or false based on whether your "list" contains the data you want, and use that variable to determine whether to show the icon.
If you want the icon to be dynamic (eg, be able to have Facebook, Insta, Whatsapp), you have another variable that holds the social network you've identified, and pass that as a prop to the icon component:
const listSocialNetwork = 'facebook' // or whatever you find in your list
const showIcon = !!listSocialNetwork // true if a social network was found in the list
// in your render
<View>
{showIcon &&
<SocialIcon socialNetwork={listSocialNetwork} />
}
</View>

How to change the default text shown when no option is selected?

By default when the react-select is rendered i see "Select..." on the component. I want to see "Search ...".
Looking at the docs, I am assuming I need to use the noOptionsMessage prop, which is documented as:
noOptionsMessage function = () => undefined
Text to display when there are no options
({
inputValue string required
}) => One of<
react.Node,
null
>
I did not really understand that bit of the docs. E.g. this prop seems to be a function. So, I have been trying variations including following without success:
<AsyncSelect
cacheOptions
defaultOptions={[]}
loadOptions={handleLoadOptions}
onChange={handleChange}
noOptionsMessage={()=> "Search..."}
/>
So, what is the solution?
Add placeholder to the AsyncSelect.
<AsyncSelect
cacheOptions
defaultOptions={[]}
loadOptions={handleLoadOptions}
onChange={handleChange}
placeholder='Search...'
/>
Common props you may want to specify include:
autoFocus - focus the control when it mounts
className - apply a className to the control
classNamePrefix - apply classNames to inner elements with the given prefix
isDisabled - disable the control
isMulti - allow the user to select multiple values
isSearchable - allow the user to search for matching options
name - generate an HTML input with this name, containing the current value
onChange - subscribe to change events
options - specify the options the user can select from
placeholder - change the text displayed when no option is selected
value - control the current value

React-Admin: How to make <Filter> mandatory with "alwaysOn" using "list"

I couldn't find a way to ONLY FETCH or LIST resources, when a user fills in the <SelectInput> (as rendered by <ReferenceInput>).
Due to a domain restriction,I need to ask the user to choose some Customer in order to query the Orders.
Is that possible? How can I pull it off?
To be clear, in their Demo project, the "Orders" can be listed using "Customer" as a <Filter>. (see image below)
A workaround could be also valid. Thanks.
Ok, this is an interesting scenario.
Let's closely look at the resource, and how it routes to various components.In this case, our interest is within the <list> and what exactly it renders:
// Set up the filter
const CustomerFilter = (props) => (
<Filter {...props}>
// setup your `ReferenceInput` and `SelectInput`
</Filter>
);
// Within your rendered component (OrderList)
<List {...props} filters={<CustomerFilter />}>
<Datagrid>
{console.log(props)} // Look out for the `match.params` prop
// ...
// Check for "customer_name" param within your props (verbose)
{match.params.customer &&
<TextField label="Customer" source="customer_name" />
}
</Datagrid>
</List>
Please note: don't just copy/paste this code. It's a verbose version.
The implication is that you can render customer name (or whatever) within your list depending on a passed parameter.

loop and get all TextInput value in a component/screen

I know that the practice of react native is to use onChangeText for change value as follow.
<TextInput
onChangeText = {(text)=> this.setState({myText: text})}
value = {this.state.myText}
/>
However, I wonder if i could do something like this. To summarise, I want to loop through all the TextInput and get the ref and value. I just want to do things in javascript way as follow. Is that possible to be done?
<TextInput id="id1" ref={ref => (this.remark = ref)} />
<TextInput id="id2" ref={ref => (this.remark1 = ref)} />
onSubmit = () => {
forEach(TextInput in component) {
console.log(TextInput.id) <- note id is custom property
console.log(TextInput.refName)
console.log(TextInput.value)
}
}
Yes, but I wouldn't recommend this approach. You could simply create an array of refs and loop through it in your onSubmit function.
forEach(TextInput in component) {
This is not possible in any javascript environment (not only because forEach and for..in syntax is different but also you can't expect to be able to loop over component elements by type (?) and get them)
What you want to do is not javascript way but old style browser way:
there are no ids in react-native
technically you could get uncontrolled TextInput's value like you would do in plain react in browser environment (via this.textInputRef._lastNativeText) but it's discouraged in react-native, most likely because because instead of DOM react native has to render to native views which all differ depending on the platform (iOS, Android, Windows, etc) but have to work the same
So it's not only impossible in react native but in plain react as well. It looks to me like you want to create a form, and sooner or later you will find out that you want validation or transformation on your inputs and switch back to controlled components anyway

How to do a custom api call in a custom field?

I'm new in react-admin and I need to create a custom field.
I want to get from an endpoint a list of information (for instance 3 objects).
Then I need to create on my custom Field (a component) 3 NumberInput (based on the list)
const CustomInput = () => (
<div>
<NumberInput source="foo" label="bar" />
<NumberInput source="foo2" label="bar2" />
<NumberInput source="foo3" label="bar3" />
</div>
);
I'd like to replace this 3 NumberInput to render them dynamically from my endpoint list.
How to do that with react-admin:
Call my endpoint to get the list
Use the list to loop and create NumberInput dynamically
Thanks ;)
react-admin is just a bunch of react components. You can do this like you would in any react applications. Call fetch on your API in your componentDidMount method for example.