I have a OneToOne relation between a Place and an Address resource; everything works fine with the Create :
<Create { ...props } title="Place > add">
<TabbedForm>
...
<FormTab label="Address">
<TextInput source="address.streetAddress" label="Street Address" />
<TextInput source="address.postalCode" label="Postal code" />
...
</FormTab>
...
</TabbedForm>
</Create>
When i submit, the Place is created as well as the related Address. But when i do the same with Edit, the Address fields are not populated :
<Edit { ...props } title="Place > edit">
<TabbedForm>
...
<FormTab label="Address">
<TextInput source="address.streetAddress" label="Street Address" /> <- empty
<TextInput source="address.postalCode" label="Postal code" /> <- empty
...
</FormTab>
...
</TabbedForm>
</Edit>
How to populate the fields with the related values ?
Note 1 : the Address is well retrieved by the api
Note 2 : the api will take care of the new values sent by the form
Note 3 : i am using api-platform and the hydra client for react admin, could it be related ?
Related
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
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.
I am working on react native application where using Formik and Yup for forms. I want to update one state value depending on the form's value while submitting a form.
Issue Description::
It works fine if there is no validation error, but there is one address field and depending on that field I have added a hidden field "zipcode". I want to show zipcode input text field if my address is empty.
Code::
const validationSchema = Yup.object().shape({
address: Yup.string()
.required('Address should not be empty'),
zipcode: Yup.string()
.required(errMgs.emptyText)
.matches(regExp, errMgs.specialCharNotAllowed),
apt: Yup.string()
.matches(regExp, errMgs.specialCharNotAllowed)
});
Inside render function::
<Formik
initialValues={this.initialValues}
onSubmit={(data) => this.onSubmitForm(data)}
ref={el => (this.form = el)}
validationSchema={validationSchema}
render={({ handleSubmit, values, setValues, setFieldValue, errors, touched, ...props }) => {
return (
<Form>
<GooglePlacesInput
onPress={(data, detail) => this.onPressOfAddress(data, detail)}
address={values.address}
name="address"
onChangeText={(value) => setFieldValue('address', value)}
/>
{errors.address && touched.address && <ErrorText message={errors.address} />}
{isZipCode &&
<>
<TextInput placeholder="Zipcode" textContentType="postalCode" name="zipcode" type="text" onValueChange={(value) => this.onChangeZipcode(value)} />
{errors.zipcode && touched.zipcode && <ErrorText message={errors.address} />}
</>
}
<TextInput placeholder="apt" textContentType="streetAddressLine1" name="apt" type="text" onValueChange={(value) => setFieldValue('apt', value)} />
<Button onPress={handleSubmit} block large variant="success">SAVE</Button>
<Button onPress={() => popScreen(this.props.componentId)} block large variant="danger">CANCEL</Button>
</Form>
);
}}
/>
I want to show zip code input with error when my address is empty on submission, means when there is a validation error in the form. How can I do this?
I want to show zipcode input text field if my address is empty.
You can have 2 cases:
1 - Check for address errors and only display the zipCode if address is not valid
To do that, you should get the error of the address field.
Instead of {isZipCode && (...)} you should do {errors.address && touched.address && (...)}, which is when the adress field is empty.
2 - After the first submit, if address is not valid, always show zipCode
Other solution is to manually trigger validation with validateForm the will come from the render function.
e.g.
<button type="button" onClick={() => validateForm().then(() => {
console.log('Check for errors and Update State of isZipCode')
})}>
Submit Button
</button>
You can also validate only one field with validateField('fieldName'), so maybe only check for address and set the state depending on the errors.
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
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>