How to disable add with condition in array input react admin - reactjs

I have an object with a Json array as a field:
{
name: "test",
field: [
{name: "field1",value: "value1"},
{name: "field2",value: "value2"}
]
}
I am using api platform as a data provider.
I am using EditGuesser of react admin as follows:
const SetsEdit = (props:any) => (
<EditGuesser {...props}>
<InputGuesser source="name" />
<ArrayInput source="field">
<SimpleFormIterator inline disableAdd={disableAdd(props)}>
<TextInput source="name" helperText={false} />
<TextInput source="value" helperText={false} />
</SimpleFormIterator>
</ArrayInput>
</EditGuesser>
);
And I'm using the edit guesser in hydra admin
<HydraAdmin
dataProvider={dataProvider(setRedirectToLogin)}
layout={MyLayout}
loginPage={LoginPage}>
<ResourceGuesser
name="sets"
edit={SetsEdit}
/>
</HydraAdmin>
What I am trying to do is I want to disable Add when field.length is >= to 4.
So I want to add a condition to the prop disableAdd based on the value of the object.
How do I pass the object value to the function to return true or false.

You have to watch for the actual form data using react-hook-form's useWatch or react-admin's <FormDataConsumer>, and use that data in your disableAdd prop.
Something like (not tested):
const SetsEdit = (props:any) => (
<EditGuesser {...props}>
<InputGuesser source="name" />
<FormDataConsumer>
{({ formData }) => (
<ArrayInput source="field">
<SimpleFormIterator inline disableAdd={disableAdd(formData)}>
<TextInput source="name" helperText={false} />
<TextInput source="value" helperText={false} />
</SimpleFormIterator>
</ArrayInput>
)}
</FormDataConsumer>
</EditGuesser>
);

Related

How to filter a list in react-admin with a parameter that is fetched asynchronously?

I am trying to filter a list in react-admin.
Basically, I have a list of classes, that I want to filter by teacherId. However, the teacherId has to be fetched asynchronously.
The code looks like this:
const activitiesFilters = [
<TextInput key="search" source="q" label="Search an Activity" alwaysOn />,
]
export const ActivityList = (props) => {
const teacher = useCurrentTeacherProfile() // This is the asynchronous call
return (
<List
filters={activitiesFilters}
filter={{ authorId: teacher?.id }} // Here I am using the teacher ID to filter my list
{...props}
exporter={false}
>
<Datagrid rowClick="edit">
<TextField source="id" />
<TextField source="title" />
<TextField source="location" />
<DateField source="dateTime" />
</Datagrid>
</List>
)
}
The above code gives me this error:
Error: ActivityList suspended while rendering, but no fallback UI was specified. Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.
I tried adding a <Suspense /> component above the <List /> but it doesn't work.
And if I add the <Suspense /> component at the root, above the <Admin /> one, it breaks the navigation.
Is there a way I can filter my list with a parameter that is fetched asynchronously?
Thanks!
I wonder if the error does not come from the "?." typescript operator in "teacher?.id" that resolves to undefined in JS before your async call resolves.
So I'd resolve the code as follow:
import { Loading } from 'react-admin';
const activitiesFilters = [
<TextInput key="search" source="q" label="Search an Activity" alwaysOn />,
]
export const ActivityList = (props) => {
const teacher = useCurrentTeacherProfile() // This is the asynchronous call
if (!teacher) return <Loading/>
return (
<List
filters={activitiesFilters}
filter={{ authorId: teacher?.id }} // Here I am using the teacher ID to filter my list
{...props}
exporter={false}
>
<Datagrid rowClick="edit">
<TextField source="id" />
<TextField source="title" />
<TextField source="location" />
<DateField source="dateTime" />
</Datagrid>
</List>
)
}

React Admin - How can I get each selected data of AutocompleteInput in ArrayInput?

Is there any way to get the full data (not only id) of each AutocompleteInput in the ArrayInput? I want to sum the total price of the items in ArrayInput. Here is the sample of item record { id: 1, name: 'item 1', price: 100}.
<ArrayInput source="items">
<SimpleFormIterator>
<ReferenceInput
label="Item"
source="id"
reference="items"
>
<AutocompleteInput
matchSuggestion={matchSuggestion}
optionText={<ItemOptionField />}
inputText={itemInputText}
/>
</ReferenceInput>
</SimpleFormIterator>
</ArrayInput>
I think FormSpy is exactly what you need.
See the answer of this post that seems to match exactly what you need ?
<SimpleForm>
<ArrayInput source="students">
<SimpleFormIterator>
<TextInput source="name" /
<NumberInput source="role" />
</SimpleFormIterator>
</ArrayInput>
<FormSpy
subscription={{ valid: true }}
onChange={props => {
setFormValues(props.values);
}}
/>
</SimpleForm>

ReferenceInput is not filing the select component

In React-admin i am trying to implement a referenceinput. I see that the list api call is made and response is availble. however the selectinput component remains empty.
I would appreciate any help.
Table source column is notes. and reference resource is notes:
<Create actions={<CoaActions />} title="New Coa" {...props}>
<SimpleForm variant="standard">
<TextInput source="code" />
<TextInput multiline source="title" />
<TextInput source="iscashbook" />
<TextInput source="isbankbook" />
<ReferenceInput label="Notes" source="notes" resource="notes" reference="notes/list">
<SelectInput optionText="name" />
</ReferenceInput>
<TextInput source="obal" />
<BooleanInput source="active" />
</SimpleForm>
</Create>
Remove the resource prop from the referenceinput

How to hide multiple fields in react-admin ShowView?

I am trying to hide a set of fields based on the value of another field but the following will not display the conditional fields ever:
export const ServiceShow = (props) => (
<ShowController {...props}>
{controllerProps =>
<ShowView component="div" {...props} {...controllerProps}>
<TabbedShowLayout>
<Tab label="General">
{controllerProps.record && controllerProps.record.maintenance &&
controllerProps.record.maintenance.active &&
<>
<Alert severity="warning">Maintenance period active</Alert>
<DateField label="Maintenance Start" src="maintenance.start" />
<DateField label="Maintenance End" srvc="maintenance.end" />
<TextField label="Maintenance Message" source="maintenance.msg" />
</>
}
</Tab>
</TabbedShowLayout>
</ShowView>
}
</ShowController>
);
The <Alert> is displayed just fine, but the Field components are not. I'm very new to React so probably a simple thing.
Note:If I put a single <TextField> as the conditional output then it will work but anything inside a React.Fragment or <div> for example, it doesn't work.
The reason why Alert shows up and Fields not is because Fields require addtional props passed by react-admin direct parent, in that case, the Tab. <> should pass such props too, but looks like it's not. And thats why a single <TextField> as child renders correctly
You can create a component that pass the props downstream to childs.
export const ServiceShow = (props) => (
<ShowController {...props}>
{controllerProps =>
<ShowView component="div" {...props} {...controllerProps}>
<TabbedShowLayout>
<Tab label="General">
<Maintenance/>
</Tab>
</TabbedShowLayout>
</ShowView>
}
</ShowController>
);
const Maintenance = props => (
{props.record && props.record.maintenance && props.record.maintenance.active &&
<>
<Alert {...props} severity="warning">Maintenance period active</Alert>
<DateField {...props} label="Maintenance Start" src="maintenance.start" />
<DateField {...props} label="Maintenance End" srvc="maintenance.end" />
<TextField {...props}label="Maintenance Message" source="maintenance.msg" />
</>
}
)

React Admin is not showing Search Bar

I am using react-admin v2.9.6 with firebase.
But it is not showing the search bar even if I added it in my code.
Seriously there is a bug which I can see in my console logs.
Here is my code and anyone who can help me contact me if you like.
const SearchFilter = props => (
<Filter {...props}>
<TextField label="Search" source="name" alwaysOn />
</Filter>
)
export const SearchList = props => (
<List {...props} filters={<SearchFilter />}>
<Datagrid>
<TextField source="name" />
<TextField source="avgRating" />
<TextField source="numReviews" />
<EditButton label="" />
<DeleteButton label="" redirect={false} />
</Datagrid>
</List>
)
I love react.js but react-admin is the first time.
Thanks. :)
In your SearchFilter component, try using <TextInput /> instead of <TextField />
Like this:
const SearchFilter = props => (
<Filter {...props}>
<TextInput label="Search" source="name" alwaysOn />
</Filter>
)
In case this issue/problem is still active for you. Doctor Agon is right, use TextInput instead of TextField as a Field only can read already defined value which comes from TextInput.

Resources