Custom Create page with Drawer but can not display <AutocompleteInput/> - react-admin

when i custom my Create page using ,the can not display correctly. how to fix it?
you can see the following reproduce in code-sandbox.
Visit here
enter the tags list
click the create button, enter to the Create page.
see the input of post.
<Create title=" " {...props}>
<SimpleForm toolbar={<TagCreateToolbar onCancel={onCancel}
/>}>
<TextInput source="name" validate={required()} />
<ReferenceInput label="Post" source="post_id" reference="posts">
<AutocompleteInput optionText="title" />
</ReferenceInput>
</SimpleForm>
</Create>

You need to fix the file: src/tags/index.js as follows:
import TagList from './TagList';
import TagCreate from './TagCreate';
import TagEdit from './TagEdit';
export default {
list: TagList,
create: TagCreate,
edit: TagEdit
};
It's still worth updating react-admin before the last release of 2.9.6

Related

TabbedForm not highlighting which tab has an error

I have a TabbedForm with 2 tabs, each tab having a single required() field. When I submit this form and the validation fails, I expect the unfocussed tab(s) to indicate that there is an error with a field within the tab (e.g. with a red underline or red text).
This appears to be working fine in a react-admin demo (https://marmelab.com/react-admin-demo/#/products/126) however even after looking a the source code for this example (https://github.com/marmelab/react-admin/blob/master/examples/demo/src/products/ProductEdit.tsx), I cannot seem to replicate the same functionality in my project.
I have the following code:
const App = () => {
const dataProvider = jsonServerProvider(
"https://jsonplaceholder.typicode.com"
);
return (
<Admin dataProvider={dataProvider}>
<Resource name="users" list={ListGuesser} edit={EditForm} />
</Admin>
);
};
export const EditForm = (props: EditProps) => {
return (
<Edit {...props}>
<TabbedForm>
<FormTab label="Tab 1">
<TextInput source="name" validate={required()} />
</FormTab>
<FormTab label="Tab 2">
<TextInput source="username" validate={required()} />
</FormTab>
</TabbedForm>
</Edit>
);
};
Image showing Tab 2 selected and is valid and there is a validation error on Tab 1, but no highlight on Tab 1 to tell the user that this is the Tab that has the error.
There has been a similar question asked here (Show Tab Form Validation For Inputs Not Direct Children Of <FormTab>) but the resolution does not apply to my problem.
Is there something I'm missing here?
plz check the demo source code: https://github.com/marmelab/react-admin/blob/master/examples/demo/src/products/ProductEdit.tsx, it's using validate function:
<RichTextInput source="description" label="" validate={req} />
and the "req" is defined at line 86:
const req = [required()];
I've encountered same problem, and solve it by using the way (validation function) of demo source code. HTH

react-admin TypeError: Cannot read property 'save' of undefined

I'm trying to show a list of users with react-admin.
CustomerList.tsx
import React from 'react';
import {
TextField,
Datagrid,
DateInput,
DateField,
Filter,
List,
EmailField,
SearchInput,
SimpleForm,
} from 'react-admin';
import { useMediaQuery, Theme } from '#material-ui/core';
import MobileGrid from './MobileGrid';
const CustomerFilter = (props: any) => (
<Filter {...props}>
<SearchInput source='q' alwaysOn />
<DateInput source='created_at' />
</Filter>
);
const CustomerList = (props: any) => {
const isXsmall = useMediaQuery<Theme>((theme) =>
theme.breakpoints.down('xs')
);
return (
<List
{...props}
filters={<CustomerFilter />}
sort={{ field: 'created_at', order: 'desc' }}
perPage={100}
>
{isXsmall ? (
<MobileGrid />
) : (
<SimpleForm>
<Datagrid optimized rowClick='edit'>
<TextField source='id' />
<DateField source='created_at' showTime />
<DateField source='updated_at' showTime />
<EmailField source='email' />
<TextField source='status' />
</Datagrid>
</SimpleForm>
)}
</List>
);
};
export default CustomerList;
But i have an error TypeError: Cannot read property 'save' of undefined.
Something Went Wrong
A client error occurred and your request couldn't be completed.
Détails
TypeError: Cannot read property 'save' of undefined
at SaveButton (http://localhost:3000/static/js/0.chunk.js:134106:25) at div at div at Toolbar (http://localhost:3000/static/js/0.chunk.js:31314:23) at WithStyles(ForwardRef(Toolbar)) (http://localhost:3000/static/js/0.chunk.js:41921:31) at Toolbar (http://localhost:3000/static/js/0.chunk.js:140673:38) at WithWidth(Toolbar) (http://localhost:3000/static/js/0.chunk.js:37871:90) at form at SimpleFormView (http://localhost:3000/static/js/0.chunk.js:139725:21) at FormView (http://localhost:3000/static/js/0.chunk.js:108800:19) at ReactFinalForm (http://localhost:3000/static/js/0.chunk.js:189371:20) at FormWithRedirect (http://localhost:3000/static/js/0.chunk.js:108697:18) at SimpleForm at div at Paper (http://localhost:3000/static/js/0.chunk.js:20241:23) at WithStyles(ForwardRef(Paper)) (http://localhost:3000/static/js/0.chunk.js:41921:31) at Card (http://localhost:3000/static/js/0.chunk.js:5097:23) at WithStyles(ForwardRef(Card)) (http://localhost:3000/static/js/0.chunk.js:41921:31) at div at div at ListView (http://localhost:3000/static/js/0.chunk.js:150222:23) at ListContextProvider (http://localhost:3000/static/js/0.chunk.js:96869:18) at List (http://localhost:3000/static/js/0.chunk.js:149806:79) at CustomerList (http://localhost:3000/static/js/main.chunk.js:4177:91) at WithPermissions (http://localhost:3000/static/js/0.chunk.js:95243:23) at Route (http://localhost:3000/static/js/0.chunk.js:193616:29) at Switch (http://localhost:3000/static/js/0.chunk.js:193818:29) at ResourceContextProvider (http://localhost:3000/static/js/0.chunk.js:103522:21) at ResourceRoutes (http://localhost:3000/static/js/0.chunk.js:103390:17) at Resource (http://localhost:3000/static/js/0.chunk.js:103460:15) at Route (http://localhost:3000/static/js/0.chunk.js:193616:29) at Switch (http://localhost:3000/static/js/0.chunk.js:193818:29) at RoutesWithLayout (http://localhost:3000/static/js/0.chunk.js:103566:21) at div at main at div at div at LayoutWithoutTheme (http://localhost:3000/static/js/0.chunk.js:147666:24) at WithStyles(LayoutWithoutTheme) (http://localhost:3000/static/js/0.chunk.js:41921:31) at withRouter(WithStyles(LayoutWithoutTheme)) (http://localhost:3000/static/js/0.chunk.js:193873:37) at Connect(withRouter(WithStyles(LayoutWithoutTheme))) (http://localhost:3000/static/js/0.chunk.js:190558:75) at ThemeProvider (http://localhost:3000/static/js/0.chunk.js:40623:24) at Layout (http://localhost:3000/static/js/0.chunk.js:147783:26) at MyLayout (http://localhost:3000/static/js/main.chunk.js:8952:80) at Route (http://localhost:3000/static/js/0.chunk.js:193616:29) at Switch (http://localhost:3000/static/js/0.chunk.js:193818:29) at div at CoreAdminRouter (http://localhost:3000/static/js/0.chunk.js:103033:87) at Route (http://localhost:3000/static/js/0.chunk.js:193616:29) at Switch (http://localhost:3000/static/js/0.chunk.js:193818:29) at CoreAdminUI (http://localhost:3000/static/js/0.chunk.js:103242:15) at AdminUI at Router (http://localhost:3000/static/js/0.chunk.js:193251:30) at ConnectedRouter (http://localhost:3000/static/js/0.chunk.js:49787:7) at ConnectedRouterWithContext (http://localhost:3000/static/js/0.chunk.js:49892:25) at Connect(ConnectedRouterWithContext) (http://localhost:3000/static/js/0.chunk.js:190558:75) at TranslationProvider (http://localhost:3000/static/js/0.chunk.js:110397:28) at Provider (http://localhost:3000/static/js/0.chunk.js:190271:20) at CoreAdminContext (http://localhost:3000/static/js/0.chunk.js:102802:25) at AdminContext at Admin (http://localhost:3000/static/js/0.chunk.js:154193:22) at App
This is the lastest version of react-admin and all dependencies were updated.
What's wrong with the save button?
Thanks & Regards

React-Admin <SimpleForm> component doesn't trigger the "UPDATE" action in the data provider

So I'm using the ra-data-json-server as a data provider and the bult in <SimpleForm> component as a form for the <Edit> view, and I'm facing a pretty strange issue, as it says in documentation, when submitted, the <SimpleForm> forces data provider to make a PUT request to the API, but in my case it does not.
Here's my Edit view compnent:
export const UserEdit = props => {
return (
<Edit {...props}>
<SimpleForm>
<ArrayInput source="applications">
<SimpleFormIterator source="applications">
{/* some inputs */}
</SimpleFormIterator>
</ArrayInput>
</SimpleForm>
</Edit>
);
};
And the admin component itself:
export const AdminComp = () => {
return (
<Admin
loginPage={CustomLoginPage}
authProvider={authProvider}
locale="ru"
i18nProvider={i18nProvider}
dataProvider={dataProvider}
>
<Resource
name="students"
list={UserList}
edit={UserEdit}
/>
</Admin>
);
};
And everytime I get into the Edit view and hit the save button it just doesn't do anything.
I managed to make it at least call the update in data provider, but it would call it with the old form data even though it was modified already.
I also tried reinstalling react-admin to the latest version which is what some people reccomended but it didn't help.

Fetch data only the first time go to a Tab in a TabbedForm

I have a tabbed form that the second tab will retrieve a list from the backend, similar to the react-admin official demo (e.g. post has many comments). The problem is when I switch the tab, there is always a backend call for the second tab which is comment list.
How can I avoid it and just load one time?
Because I have pagination on the second tab, if I switch tab, the pagination will be changed to the first page.
Thank you in advance!
<TabbedForm>
<FormTab label="Post">
<TextInput source="name"/>
</FormTab>
<FormTab label="Comment">
{/* This tab should fetch data only once if I switch tabs */}
<ReferenceManyField
pagination={<Pagination/>}
reference="comments"
target="id"
perPage={5}
addLabel={false}
>
<Datagrid>
<TextField source="name" />
<EditButton />
<DeleteButton undoable={false}/>
</Datagrid>
</ReferenceManyField>
</FormTab>
</TabbedForm>
If you are using Hooks, you could use a combination of useState and useEffect.
useState would hold the result of your data-fetching, which you would trigger in useEffect. To make that happen just once, use an empty array as dependency-array in useEffect:
const [data, setData] = useState(null)
useEffect(() => {
setData(fetchData())
}, [])

React-Admin | Bulk-Select with ReferenceField

In our application, we're trying to use Datagrid within ReferenceField to create/modify/delete related records, as shown in https://marmelab.com/blog/2018/07/09/react-admin-tutorials-form-for-related-records.html
All the functionality shown in the tutorial works well, except the bulk-actions added in a recent react-admin update. Clicking these checkboxes gives
Uncaught TypeError: _this.props.onToggleItem is not a function
I believe this is because the onToggleItem prop is normally provided by the List component, however in this application, Datagrid doesn't have a parent List component.
Adding a List component between ReferenceManyField and Datagrid allows bulk select/delete to work after some changes to the style, however this causes another issue: the current displayed page (i.e. records 1-10, 11-20, etc) is stored per-resource in the store, and so it is possible to have a situation where the store says we're on page 2, and displays page 2, which is empty because there are only enough related items to fill one page.
Am I missing something here? Or is bulk-select inside ReferenceManyField not possible at the moment?
export const NetworksShow = (props) => (
<Show title={<NetworksTitle />} actions={<NetworksShowActions />} {...props}>
<ReferenceManyField addLabel={false} target="ipid" reference="acl-network">
<List style={{ margin: '0px -24px -16px -24px' }} {...props} actions={<NetworkACLCardActions ipid={props.id}/>} filter={{ ipid: _.has(props, 'id') ? props.id : undefined }}>
<Datagrid hasBulkActions={true}>
<ReferenceField label="Network" source="ipid" reference="networks">
<TextField source="name" />
</ReferenceField>
<TextField label="URL" source="url" />
<BWChip label="Action" source="wb" />
<EditButton />
<DeleteButton />
</Datagrid>
</List>
</ReferenceManyField>
</Show>
);
As a side-effect of https://github.com/marmelab/react-admin/pull/2365, it is now possible to use ReferenceManyField -> List -> Datagrid in the way described in the question.
For example, we're now doing the following:
<ReferenceManyField addLabel={false} target="groupid" reference="users">
<List
style={{ margin: '0px -24px -16px -24px' }}
filter={{ groupid: id }}
{...props}
>
<Datagrid hasBulkActions>
<LinkField label="Name" source="name" />
<LinkField label="Username" source="email" />
<FlexibleBooleanField label="Email" source="allowemail" />
<ACLChip label="User Access" source="aclid" />
</Datagrid>
</List>
</ReferenceManyField>
Bulk actions works with the above, and any issues with pagination are avoided as react-admin now checks and modifies pagination if nothing appears on the current page.
As I've understood from the documentation, Datagrid is just an iterator "dumb component".
It just "shows" things that the parent - usually List (connected component) or in your case ReferenceManyField - element previously has fetched.
Thus I think that BulkActions can only be functional when provided by a List element.
For the second part of your issue, Lists should be used top-level and not within other elements that's why it breaks your pagination.
I implemented "DumbList" which takes data from parent component instead of loading it itself. This solves the problem:
import React from 'react';
import { ListController } from 'ra-core';
import { ListView } from 'ra-ui-materialui/esm/list/List';
export const DumbList = props =>
<ListController {...props}>
{controllerProps => {
let { data } = props
const ids = Object.keys(data || {})
const total = ids.length
return <ListView
{...props}
// This is important, otherwise bulkActionsToolbar ends up on very top of the page
classes={{ card: 'relative' }}
{...Object.assign(controllerProps, { data, ids, total })} />
}}
</ListController>