Display Field in Edit Form - react-admin

Currently, if I try to place a Field into an Edit form, the field doesn't display at all. There is no errors in the console or the terminal about why it wont.
Example:
<Edit undoable={false} {...props}>
<SimpleForm>
<FormRow>
<TextField source="id"/>
<TextField source="name"/>
</FormRow>
</SimpleForm>
</Edit>
will not display either of these on the page load, it will simply be blank.
Is there any way to use fields in the Edit form?

You need to pass in the record prop (and basePath if its a reference).
The Edit component does not get the record prop so create a form component and it will get passed the record as a prop
eg.
const ProjectEdit: FC<EditComponentProps> = props => {
const classes = useStyles();
return (
<RA.Edit {...props} title={<ProjectTitle />}>
<RA.SimpleForm>
<ProjectForm />
</RA.SimpleForm>
</RA.Edit>
);
};
export const ProjectForm = (props: any) => {
return (
<Box flex={1} mr={{ md: 0, lg: '1em' }}>
<RA.TextInput source="name" fullWidth={true} />
<Typography variant="h6" gutterBottom>
Tasks
</Typography>
<RA.TextField
source="name"
fullWidth={true}
record={props.record}
/>
<RA.ReferenceManyField
label="Tasks"
reference="Task"
target="projectId"
fullWidth={true}
record={props.record}
basePath="/Task"
>
<RA.SingleFieldList fullWidth={true}>
<RA.ChipField source="name" fullWidth={true} />
</RA.SingleFieldList>
</RA.ReferenceManyField>
</Box>
);
};

Related

How to remove "No results found" label from the list when DataGrid has empty component

const TabbedDatagrid = (props: TabbedDatagridProps) => (
<Datagrid empty={<Empty />}>
<TextField source="id" />
<TextField source="createDate" />
</Datagrid>
);
const Empty = () => {
const { basePath } = useListContext();
return (
<Box textAlign="center" m={1}>
<Typography variant="h4" paragraph>
No products available
</Typography>
<Typography variant="body1">
Create one or import from a file
</Typography>
<CreateButton basePath={basePath} />
<Button>Import</Button>
</Box>
);
};
const MyList = (props: ListProps) => (
<List
{...props}
sort={{ field: 'createDate', order: 'DESC' }}
perPage={10}
filters={orderFilters}
pagination={<PostPagination />}
>
<TabbedDatagrid />
</List>
);
In the result both are displayed, 'No results found" and Empty component
How to display only Empty component?
The <Pagination> component takes a limit prop.
From the React-Admin docs
limit: An element that is displayed if there is no data to show (default: <PaginationLimit>)
You could try passing null <PostPagination limit={null} /> to hide that default "No results found" message.
You can replace these messages with your: Translating The Empty Page

React-Admin - How to log record data to the console?

I'd like to know what are the data I'm working with, when using react-admin. (see them in the console to help debug)
For instance, when I'm working with a List:
import React from 'react';
import { Datagrid, List, TextField } from 'react-admin';
import { ListProps } from '../../types/admin/ListProps';
const ProductList = (props: ListProps): JSX.Element => {
console.log('ProductList.props', props);
return (
<List
{...props}
sort={{
field: 'titleEN',
order: 'DESC',
}}
>
<Datagrid rowClick="edit">
<TextField source="title" />
<TextField source="titleEN" label={'Title (EN)'} />
<TextField source="titleFR" label={'Title (FR)'} />
{/*<ArrayField source="images"><SingleFieldList><ChipField source="id" /></SingleFieldList></ArrayField>*/}
{/*<ReferenceArrayField source="imagesIds" reference="images"><TextField source="id" /></ReferenceArrayField>*/}
<TextField source="customer.label" label={'Customer'} />
<TextField source="price" />
</Datagrid>
</List>
);
};
export default ProductList;
How can I do that? I haven't found anything in the official doc https://marmelab.com/react-admin/List.html
This kind of logging can be displayed through the Data Provider. See https://marmelab.com/react-admin/DataProviders.html
For instance, with https://github.com/marcantoine/ra-data-graphql-prisma data provider, one such implementation could be https://github.com/UnlyEd/ra-data-graphql-prisma/commit/4031c5c3f2e97c479a9714df56da06653a908444

How to combine create and edit page in react-admin

I am new for the react and react-admin, but I am now using it in our project, everything is good, but there is one thing I don't know how to make it. in our application. the create and edit page almost same, the only difference is some fields are disabled in edit view, so I want to combine create and edit, is there any document about it. I searched it but it seems not an easy way to do it, it's appreciated if can get some sample code. thank you !!!
Hi #Mads, thank you for your answer, I update the question here. what I mean is last time, i also create a separate form like what you did and I insert the component directly as below (e.g. <Form/>). it will get an error: the invalid value for prop ‘save’ on tag
I am just curious what's the difference with this way ({form('edit')})
<Edit {...props} undoable={false} style={{width: '100%'}}> <Form/> </Edit>
You can do something like this:
const form = type => (
<SimpleForm>
<TextInput source="name"/>
{type === 'create' ? <TextInput source="created_at"/> : ''}
</SimpleForm>
);
export const EditView = ({classes, ...props}) => {
return (
<Edit {...props} undoable={false} style={{width: '100%'}}>
{form('edit')}
</Edit>
);
};
export const CreateView = ({classes, ...props}) => {
return (
<Edit {...props} undoable={false} style={{width: '100%'}}>
{form('create')}
</Edit>
);
};
I had a similar struggle and this is what I ended up doing:
// This is the reusable form component
const CategoryForm = (props) => (
<SimpleForm {...props}>
<TextInput source="name" label="Nome" />
{props.type === "edit" && <p>This element only shows in edit mode</p>}
</SimpleForm>
);
// Edit View Component
export const CategoryEdit = (props) => (
<Edit {...props}>
{/* Reusable form component with type prop set to 'edit' */}
<CategoryForm type="edit" />
</Edit>
);
// Create View Component
export const CategoryCreate = (props) => (
<Create {...props}>
{/* Reusable form component with type prop set to 'create' */}
<CategoryForm type="create" />
</Create>
);

React-native Input HOC for redux-form loses focus after type a symbol

I'm trying to use redux-form, but, as I read, I need HOC for Input field to replace onTextChange to onChange. I have:
import React from 'react';
import {Input} from 'native-base';
export default function InputField(props) {
const { input, ...inputProps } = props;
return (
<Input
{...inputProps}
onChangeText={input.onChange}
onBlur={input.onBlur}
onFocus={input.onFocus}
value={input.value}
/>
);
};
and use it in my form:
<Item style={{marginTop: 10, width: "100%"}}>
<Field name="login" component={(props) => {
return (
<InputField {...props} keyboardType="email-address" placeholder='E-mail' />
)
}}/>
</Item>
But every time I type key, the field loses focus. Some "experts" recommend use focus() function. But what if I edit text in the middle of it?
Any solutions? Or maybe native-base have compatible textfield component?
It is strange, but it works ))
function InputFieldEmail(props) {
return <InputField {...props} keyboardType="email-address" placeholder='E-mail' />;
}
and use it instead arrow functions
<Field name="login" component={InputFieldEmail}/>
I think it's strange )
You must provide the InputField component as a prop so that its value is constant or put it outside the Item component, when it is inside another, every time the state of the upper level is updated, the lower level is forced to return. to start.
If your Input is inside an Item you are probably using a FlatList and your goal is to put it in the header.
You can try something like this:
<View style={{marginTop: 10, width: "100%"}}>
<Field name="login" component={(props) => {
return (
<InputField {...props} keyboardType="email-address" placeholder='E-mail' />
)
}}/>
</View>
<FlatList
ListHeaderComponent={() => {
<Item>
</Item>
}}
/>
Remember to put the styles that were in Item in View.

How do you conditionally show fields in "Show" component in react-admin?

Some fields I want to only show if they have a value. I would expect to do this like so:
<Show {...props} >
<SimpleShowLayout>
{ props.record.id ? <TextField source="id" />: null }
</SimpleShowLayout>
</Show>
But that doesn't work. I can make it somewhat work by making each field a higher order component, but I wanted to do something cleaner. Here's the HOC method I have:
const exists = WrappedComponent => props => props.record[props.source] ?
<WrappedComponent {...props} />: null;
const ExistsTextField = exists(TextField);
// then in the component:
<Show {...props} >
<SimpleShowLayout>
<ExistsTextField source="id" />
</SimpleShowLayout>
</Show>
This correctly shows the value, but strips the label.
We need to update our documentation about this. In the mean time, you can find informations about how to achieve that in the upgrade guide: https://github.com/marmelab/react-admin/blob/master/UPGRADE.md#aor-dependent-input-was-removed
Here's an example:
import { ShowController, ShowView, SimpleShowLayout, TextField } from 'react-admin';
const UserShow = props => (
<ShowController {...props}>
{controllerProps =>
<ShowView {...props} {...controllerProps}>
<SimpleShowLayout>
<TextField source="username" />
{controllerProps.record && controllerProps.record.hasEmail &&
<TextField source="email" />
}
</SimpleShowLayout>
</ShowView>
}
</ShowController>
);
Maybe this way can be useful
import { FormDataConsumer } from 'react-admin'
<FormDataConsumer>
{
({ formData, ...rest}) => formData.id &&
<>
<ExistsTextField source="id" />
</>
}
</FormDataConsumer>