I am using React-admin to create a customer dashboard where they can find their invoices for all months. Now I would like to add search function to this so that customers can search invoices according to any field,say entity_name.
I am able to add search element on ui, but its not working.
I added search functionality by importing {Filter, TextInput} from React-admin. And I am using data from "ra-data-simple-rest"; and running sever on port 5000 in my local machine.
Here is my code:
const InvoiceFilter = (props) => (
<Filter {...props}>
<TextInput source="entity_name" alwaysOn />
</Filter>
);
const InvoiceList = (props) => {
return (
<List {...props} filters={<InvoiceFilter />}>
<Datagrid>
<TextField source="id" />
<TextField source="entity_name" />
<DateField source="period_start" />
<DateField source="period_end" />
<TextField source="total" />
</Datagrid>
</List>
);
};
You should use proper components for the filter function.
the filters props is for FilterForm
<FilterForm filters={postFilters} />
Placing the filters props in List component is not doing anything.
Create proper filter and pass it to a proper component like shown in the documentation here
Based on the docs, you could try:
const invoiceFilters = [
<TextInput source="entity_name" alwaysOn />
);
const InvoiceList = () => {
return (
<List filters={invoiceFilters}>
<Datagrid>
<TextField source="id" />
<TextField source="entity_name" />
<DateField source="period_start" />
<DateField source="period_end" />
<TextField source="total" />
</Datagrid>
</List>
);
};
Related
I have following List component where customerid and technicianid are
ReferenceField. Sometimes I have technicianid as null. So the UI keeps showing the loading bar (as shown in the image below).
Question:
How can I tell the ReferenceField to handle null and just show the empty string.
export const AppointmentList = (props) => (
<List title="All Appointments" {...props}>
<Datagrid>
<ReferenceField source="customerid" reference="customers" label="Customer" >
<TextField source="name" />
</ReferenceField>
<TextField source="name" label="Name" />
<DateField source="scheduleddt" label="Schedule Date" />
<ReferenceField source="technicianid" reference="technicians" label="Technician" >
<TextField source="name" />
</ReferenceField>
<DateField source="createddatetime" label="Created" />
</Datagrid>
</List>
);
You'll need the 'allowEmpty' attribute.
export const AppointmentList = (props) => (
<List title="All Appointments" {...props}>
<Datagrid>
<ReferenceField source="customerid" reference="customers" label="Customer" >
<TextField source="name" />
</ReferenceField>
<TextField source="name" label="Name" />
<DateField source="scheduleddt" label="Schedule Date" />
<ReferenceField source="technicianid" reference="technicians" label="Technician" allowEmpty>
<TextField source="name" />
</ReferenceField>
<DateField source="createddatetime" label="Created" />
</Datagrid>
</List>
);
https://marmelab.com/admin-on-rest/Inputs.html#referenceinput
We are currently working on it :)
I know the usage of both the components is clearly different, ReferenceManyFields used to make request to certain resource by filtering the target with the current id.
ReferenceArrayFields used to make request to certain resource by filtering the referenced id using the source that contain some ids.
ReferenceManyFields has target props, ReferenceArrayFields has source props. Is there any way to send the request based on the target and source ?
Here is my code..
export const ApplicationEdit = (props) => {
return (
<Edit {...props} >
<SimpleForm>
<ReferenceManyFields reference="applications" target="customer_id" source="costumer_id" addLabel={true} label="Application History">
<Datagrid>
<TextField source="id" />
<DateField source="date" />
<TextField source="amount" />
<TextField source="status" />
<TextField source="customer_id" />
</Datagrid>
</ReferenceManyFields>
</SimpleForm>
</Edit>
);
}
This is not possible currently but it looks like a valid use case to me. I'll see if we can address this in next version
I want to create a Datagrid inside Create, Edit page to display and manage n-to-n relationship. But I don't know how to pass props into List and Datagrid and what props should be passed.
The Resource to manage this Datagrid named caregiver_student and I put it in my custom restClient file.
Basic info
Relationship info
Here is my code:
<Edit title={<CaregiverTitle />} {...props}>
<TabbedForm>
<FormTab label="Personal Info">
<DisabledInput source="id" />
<TextInput source="name" />
<TextInput source="email" />
<TextInput source="phone" />
<RadioButtonGroupInput source="account_type" choices={[
{ id: 10, name: 'Caregiver' },
{ id: 20, name: 'Guardian' },
]} optionText="name" optionValue="id" />
<BooleanInput source="status" label="Active"/>
</FormTab>
<FormTab label="Relationship">
<List actions={<RelationActions/>} location={false} title={" "}>
<Datagrid>
<TextField source="id" />
<TextField source="name" label="Student"/>
<TextField source="relationship" />
<EditButton />
<DeleteButton />
</Datagrid>
</List>
</FormTab>
</TabbedForm>
</Edit>
Thank you for your help!
The linked resources should be enclosed in a ReferenceManyField
You can find a complete example in the demo,
especially the Customers Edit component
Someone started a PR which might help: https://github.com/marmelab/admin-on-rest/pull/744
I have a similar page with a tab that lists "Batchunits" that belong to a particular "batchid".
<FormTab label="resources.batches.tabs.batchunits">
<ReferenceManyField addLabel={false} reference="Batchunits" target="batchid">
<Datagrid bodyOptions={{ stripedRows: true, showRowHover: true}} >
<TextField source="unitcode" />
<DateField source="harvested" />
<BooleanField source="contaminated" label="Contaminated"/>
<TextField source="note" style={{ maxWidth: '10em', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} />
<EditUnitButton />
</Datagrid>
</ReferenceManyField>
</FormTab>
But in this setup, Formtab will not accept a Create "button" to create a record of another resource. e.g another "Batchunit. Would be very useful to create another linked Batchunit. Don't know how to do that...
I have a List view where I want to render a ReferenceField field based on the value of the current row being rendered in the table that the Datagrid component creates.
How can I access the current row's data? (the values of the columns of the current row).
I tried record.processed but I get an error saying that the record object doesn't exist (processed is a column in the record that I want to check in order to format the field). I also tried resource.processed, this.props.processed, and this.props.record.processed with no success.
The piece of code that shows what I'm trying to do is the following:
<List title="Sales Inquiries" filter={{ request_type: 'sales' }} {...props}>
<Datagrid>
<TextField source="id" />
<TextField source="firstname" label="First Name" />
<TextField source="lastname" label="Last Name" />
<TextField source="company" />
<TextField source="email" />
<DateField source="timestamp" label="Received" />
{record.processed ?
<ReferenceField label="Processed By" source="processedBy_id" reference="Users">
<TextField source="username" />
</ReferenceField>
: <span>Nobody</span> }
<ShowButton />
</Datagrid>
</List>
EDIT
Did as suggested by #kunal pareek Applied a HOC to the ReferenceField field that modifies it in order to show the proper content as follows:
const CustomField = (props) => (
<span>
{props.record.processed ?
<ReferenceField label="Processed By" source="processedBy_id" reference="Users">
<TextField source="username" />
</ReferenceField>
: <span>Nobody</span> }
</span>
);
the record is not really available at the location you want as a variable. It is passed to the component as a prop.
So you can do this.
<List title="Sales Inquiries" filter={{ request_type: 'sales' }} {...props}>
<Datagrid>
<TextField source="id" />
<TextField source="firstname" label="First Name" />
<TextField source="lastname" label="Last Name" />
<TextField source="company" />
<TextField source="email" />
<DateField source="timestamp" label="Received" />
<CustomField />
<ShowButton />
</Datagrid>
</List>
const CustomField = (props) => (
{props.record.processed ?
<ReferenceField label="Processed By" source="processedBy_id" reference="Users">
<TextField source="username" />
</ReferenceField>
: <span>Nobody</span> }
)
Above is just a simple example. I have taken your code straight and reformatted it, so it might not work straightaway. But I have been using this method to change the values of my components in several places.
You can also use HOCs. You can find examples here
https://marmelab.com/admin-on-rest/Theming.html
The dependent-input addon can help you with that.
Is there a way to do an if statement before showing the show page?
For instance if the id of the element I clicked on with the show button end with ".log" I want to have the show page look like this:
export const reportShow = ({ ...props }) => (
<Show title="Log" {...props}>
<SimpleShowLayout>
<ReferenceManyField label="Log" reference="archivedfiles" target="id">
<Datagrid>
<TextField source="id" label="Line" />
<TextField source="timestamp" label="Timestamp" />
<TextField source="severity" label="Severity" />
<TextField source="message" label="Message" />
</Datagrid>
</ReferenceManyField>
</SimpleShowLayout>
</Show>);
But if the id ends with .txt I want the show page to show a Report page which would have this:
export const reportShow = ({ ...props }) => (
<Show title="Report" {...props}>
<SimpleShowLayout>
<TextField source="id" label="Report Name" />
<TextField source="rmessage" label="Message" />
</SimpleShowLayout>
</Show>);
What would be the best way to go about this?
Maybe the aor-dependent-input addon can help you with that.
I ended up getting this to work by doing this:
export const archivedShow = ({ ...props }) => {
if (props.match.params.id.endsWith("txt")){
return (<Show title="Report" {...props}>
<SimpleShowLayout>
<ReferenceManyField label="Report" reference="archivedfiles" target="id">
<Datagrid>
<FormattedReportView/>
</Datagrid>
</ReferenceManyField>
</SimpleShowLayout>
</Show>
);
}
else {
return (
<Show title="Log" {...props} filters={< LogFilter/>}>
<SimpleShowLayout>
<ReferenceManyField label="Log" reference="archivedfiles" target="id">
<Datagrid>
<TextField source="id" label="Line" />
<TextField source="timestamp" label="Timestamp" />
<TextField source="severity" label="Severity" />
<TextField source="message" label="Message" />
</Datagrid>
</ReferenceManyField>
</SimpleShowLayout>
</Show>
);
}
}