React Admin is not showing Search Bar - reactjs

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.

Related

How to disable add with condition in array input react admin

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>
);

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>
)
}

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

react-admin many-to-many with junction table

Here is an example of my schema and how i've implemented it in react-admin, can you tell me if is the best way for getting data from a junction table ?
const Media = () =>
<ReferenceManyField label="Kiosks" source="id" target="media_id" reference="kiosk_media">
<SingleFieldList>
<ReferenceManyField source="kiosk_id" target="id" reference="kiosk">
<SingleFieldList>
<TextField source="name" />
</SingleFieldList>
</ReferenceManyField>
</SingleFieldList>
</ReferenceManyField>
I had the same issue, I managed it on my back end to follow this structure:
Kiosk: { id:..., ... Medias:[{id:... },{id:...},{id:...}], ... }
and then I used ArrayField to display. https://marmelab.com/react-admin/Fields.html#arrayfield
Edit 2: I figured a way to do this with the free components. You were close, but you need to use just a plain reference to the final kiosk table. This snippet would show a table of kiosk records linked to the current media record through the kiosk_media table.
<ReferenceManyField label="Kiosks" reference="kiosk_media" target="media_id">
<Datagrid>
<ReferenceField reference="kiosk" source="kiosk_id" link="show" />
</Datagrid>
</ReferenceManyField>
-- Original Answer --
You can probably use the ReferenceManyToManyField.
const AuthorShow = () => (
<Show>
<SimpleShowLayout>
<TextField source="first_name" />
<TextField source="last_name" />
<DateField source="date_of_birth" />
<ReferenceManyToManyField
reference="books"
through="book_authors"
using="author_id,book_id"
>
<Datagrid>
<TextField source="title" />
<DateField source="published_at" />
</Datagrid>
</ReferenceManyToManyField>
<EditButton />
</SimpleShowLayout>
</Show>
);
https://marmelab.com/react-admin/FieldsForRelationships.html#referencemanytomanyfield
Edit: I just realized that this is a paid Enterprise-only feature, but I'll leave this here for reference.

How do I make a SelectInput which is part of the filter to be displayed by default?

I have an admin-on-rest system that shows a page with a list, and I have 2 fields in the filter, one (q - free text search) that I want to always display, and the second one is a status-select, which I want do allow the user to remove (and then appear in the 'add filter' list) but I want it to initially be displayed (so that the inital/default view is filtered to only a specific status) with the 'x' icon next to it so that the user will be able to remove this value, or to change it to see whatever other status filtering they want
could not find the way to do so...
It's explained in the List documentation: you can add an alwaysOn prop to the filters you'd like to be always displayed.
const PostFilter = (props) => (
<Filter {...props}>
<TextInput label="Search" source="q" alwaysOn />
<TextInput label="Title" source="title" defaultValue="Hello, World!" />
</Filter>
);
export const PostList = (props) => (
<List {...props} filters={<PostFilter />}>
...
</List>
);
In order to set a default value for a filter, you also have to set the filterDefaultValues prop on the List component:
const PostFilter = (props) => (
<Filter {...props}>
<TextInput label="Search" source="q" alwaysOn />
<BooleanInput source="is_published" alwaysOn />
<TextInput source="title" defaultValue="Hello, World!" />
</Filter>
);
export const PostList = (props) => (
<List {...props} filters={<PostFilter />} filterDefaultValues={{ is_published: true }}>
...
</List>
);

Resources