How to edit only by click EditButton - reactjs

React admin - A frontend Framework for building data-driven applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Material Design. Open sourced and maintained by marmelab.
Clicking on any part of the row in PostList will open the editing form, how to make it possible to edit only by click the EditButton.
I make example for demonstration this behaviour codesandbox
posts.tsx
export const PostList = () => (
<List>
<Datagrid rowClick="edit">
<TextField source="id" />
<ReferenceField source="userId" reference="users">
<TextField source="name" />
</ReferenceField>
<TextField source="title" />
<EditButton />
</Datagrid>
</List>
);
App.tsx
const App = () => (
<Admin dataProvider={dataProvider}>
<Resource name="posts" list={PostList} edit={PostEdit} />
<Resource name="users" list={UserList} />
</Admin>
);
if i comment edit={PostList} edit button do not work
const App = () => (
<Admin dataProvider={dataProvider}>
<Resource name="posts" list={PostList} /*edit={PostEdit}*/ />
<Resource name="users" list={UserList} />
</Admin>
);
I want edit post only by click Edit Button

You need to remove rowClick="edit" from datagrid
export const PostList = () => (
<List>
<Datagrid> // remove rowClick="edit"
<TextField source="id" />
<ReferenceField source="userId" reference="users">
<TextField source="name" />
</ReferenceField>
<TextField source="title" />
<EditButton />
</Datagrid>
</List>
);

Related

Show issue on React-admin, row is unclickable

Hello i'm hiring for a solution my show doesn't work on the row of my table. The cursor doesn't change to let me click on a row and even if i click nothing happened. That's my code
//in App.tsx
<Admin dataProvider={DataProvider} authProvider={authProvider}>
<Resource name="users" list={UsersList} show={UserShow}/>
</Admin>
// in users.tsx
export const UsersList = () => {
// const isSmall = useMediaQuery((theme : any) => theme.breakpoints.down("sm"));
return (
<List filters={userFilters}>
<Datagrid>
<TextField source="id" />
<TextField source="firstname" />
<TextField source="lastname" />
<EmailField source="email" />
<TextField source="phone" />
<TextField source="candidatureStatus" />
<TextField source="created_at" />
</Datagrid>
</List>
);
};
export const UserShow = () => (
<Show>
<SimpleShowLayout>
<TextField label="test" source="email" />
<TextField source="firstname" />
<TextField source="lastname" />
</SimpleShowLayout>
</Show>
)
Even if i followed the tutorial on react admin i can't display a showScreen
If you want to open the Show form when clicking on a row in the List, you need to add:
<Datagrid rowClick="show">
https://marmelab.com/react-admin/Datagrid.html#rowclick

Filter by different or multiple sources in react admin list

Is there any way to filter react admin lists by multiple sources, or to change the source on the front end with react admin? I've tried running the source as a state variable, but when updated it only adds to the query instead of replacing it.
Example filter list
const UserFilter = (props) => (
<Filter {...props}>
<TextInput label="Search By ID" source="uid" alwaysOn />
</Filter>
);
export const UserList = (props) => (
<List {...props} filters={<UserFilter />}>
<Datagrid>
<RichTextField label="User ID" source="uid" />
<RichTextField label="Email" source="email" />
<RichTextField label="Admin" source="isAdmin" />
<ShowButton label="" />
</Datagrid>
</List>
);

React-Admin ReferenceInput issues

I am trying to reference category in my create and edit product page. Please find the code below:
const validateProduct = (values) => {
const errors = {};
if (!values.name) {
errors.name = ['Product name is required'];
}
if (!values.category) {
errors.category = ['Product category is required'];
}
return errors
};
export const ProductCreate = (props) => (
<Create {...props}>
<SimpleForm validate={validateProduct}>
<TextInput source="name" />
<ReferenceInput label="category" source="category._id" reference="categories">
<SelectInput optionText="name" />
</ReferenceInput>
<TextInput source="price" />
<LongTextInput source="description" />
<TextInput source="image" />
</SimpleForm>
</Create>
);
const ProductTitle = ({ record }) => {
return <span>Product {record ? `"${record.name}"` : ''}</span>;
};
export const ProductEdit = (props) => (
<Edit title={<ProductTitle />} {...props}>
<SimpleForm validate={validateProduct}>
<DisabledInput source="id" />
<TextInput source="name" />
<ReferenceInput label="category" source="category._id" reference="categories">
<SelectInput optionText="name" />
</ReferenceInput>
<TextInput source="price" />
<LongTextInput source="description" />
<TextInput source="image" />
</SimpleForm>
</Edit>
);
There are few issues with the ReferenceInput:
Validation does not work for ReferenceInput.
Existing category is not selected by default in the edit product page.
I want the category validation and category selection enabled in add/edit pages. How do I achieve that in React-Admin?
Thanks

Bulk action in admin-on-rest

I used bulkActions props for Admin-on-rest List but don't show anything when I select rows. How to can I use the bulk action?
const AccountingBulkActions = props => (
<BulkActions {...props}>
<BulkDeleteAction />
</BulkActions>
);
export const AccountingList = (props) => (
<List
{...props}
bulkActions={<AccountingBulkActions />}
title="Accounting">
<Datagrid
headerOptions={{ adjustForCheckbox: true, displaySelectAll: true }}
bodyOptions={{ displayRowCheckbox: true }}
rowOptions={{ selectable: true }}
options={{ multiSelectable: true }}>
<DateField source="createdAt" />
<TypeLabel source="type" />
<GenderLabel source="gender" />
<NumberField source="paymentPrice" />
<NumberField source="totalPrice" />
</Datagrid>
</List>
);
Bulk actions are a new feature only available on react-admin. You'll have to upgrade your admin-in-rest app.

Is it possible to have conditional columns in a List/DataGrid in Admin on REST?

If I apply a filter in a List component in Admin on REST, I want to only show the filtered column (TextField) once this specific filter is selected, because the filter is fuzzy and I want to see the different results at a glance. But when no filter is set, the column is supposed to be hidden.
I implemented it like this so far.
const ConditionalFilterTextField = (props) => {
const show = ... // if filter is set in URL
return (show) ? <TextField {...props} /> : null
}
...
<List {...props} filters={<MyFilter />}>
<Datagrid>
...
<ConditionalFilterTextField sortable={false} source="filter_field" label="My Label" />
...
</Datagrid>
</List>
This does work in a way, but then again not really. It shows the label of the column and an empty space when I return null (when the filter is not set and the column is supposed to be hidden).
How can I control visibility of a TextField depending on whether a filter is set or not? How can I force a rerender of the List when I want to add a column?
Edit:
This is similar to your answer, #Gildas, but doesn't work for me. Some detail might be wrong?
in itemList.js
class ItemList extends Component {
render() {
const props = this.props
// Find out if current filter is source of field.
const filter = props.itemsFilters
const showFieldA = (filter && filter.fieldA) ? true : false
return <List {...props} filters={<ItemsFilter />} perPage={50}>
<Datagrid>
<ReferenceField sortable={false} source="id" reference="items" linkType="show">
<TextField source="fieldB" />
</ReferenceField>
<TextField sortable={false} source="fieldC" />
<TextField sortable={false} source="fieldD" />
<DateField sortable={false} source="fieldE" />
{ (showFieldA === true) ? <TextField sortable={false} source="fieldA" /> : null }
<ShowButton />
<EditButton />
</Datagrid>
</List>
}
}
const ItemsFilter = (props) => (
<Filter {...props}>
<TextInput label="FilterSearch" source="q" />
<TextInput label="FilterA" source="fieldA" />
</Filter>
)
function mapStateToProps(state) {
return {
itemsFilters: state.admin.resources.items.list.params.filter
}
}
export default connect(mapStateToProps)(ItemList)
...
in App.js
<Resource name="items" list={ItemList} show={ItemShow} edit={ItemEdit} />
const MyList = (props) => {
const show = ... // if filter is set in URL
return (
<List {...props} filters={<MyFilter />}>
<Datagrid>
...
{show ? <TextField {...props} /> : null}
...
</Datagrid>
</List>
);
}

Resources