I had to change in the restclient after like this:
var parentresource = '';
switch (resource) {
case 'details':
parentresource = `products/${params.id}/${resource}`;
break;
default:
parentresource = `${resource}`;
}**
url = `${apiUrl}/${**parentresource**}?${fetchUtils.queryParameters(query)}`;
break;
I have a EditView where in one tab I have got:
<ReferenceManyField addLabel={false} reference="details" target="id">
<Datagrid>
<NumberField source="quantity" label="Quantity" />
<TextField source="measurementUnit" label="Measurement" />
<NumberField source="purchasePrice" label="Purchase Price" />
<NumberField source="salesPrice" label="Sales Price" />
<NumberField source="discountPercent" label="Discount Percent" />
<NumberField source="salesTaxPercent" label="Sales Tax Percent" />
<TextField source="supplier" label="Supplier" />
<DateField source="createdDate" label="Created Date" />
<TextField source="status" label="Status" />
<EditButton basePath="/products" />
</Datagrid>
</ReferenceManyField>
When I click EditButton the url in the browser needs to needs to be http://localhost:5000/#/details/1?_k=5f7qc1 but the url to grab data from should be http://localhost:5000/api/products/2/details/1
Any easier way to do this?
That's the job of a custom restclient
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 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>
);
}
}
Trying Kendo UI JSP editable grid. Grid is working with few problems.
(Version : Kendo UI v2015.3.1111 )
Export: Even with allPages="allPages", its exporting only current
page.
After CREATE, GRID is not updated with server response which has user createDate. Same with Update, grid not updated with update date
even though the updated user object is passed.
Grid shows user added even if it failed in the backend. How to handle error response for create /update and show the failed message ?
Any help greatly appreciated.
Controller create part:
#RequestMapping(value = "/user/create", method = RequestMethod.POST)
public #ResponseBody User create(#RequestBody Map<String, Object> model) {
log.debug("create");
User target = new User();
target.setUserName((String)model.get("UserName"));
target.setFirstName((String)model.get("firstName"));
target.setLastName((String)model.get("lastName"));
target.setOpenDate(getDateFromStr((String)model.get("openDate")));
target.setEditDate(getDateFromStr((String)model.get("editDate")));
User user = userDao.createUser(target);
log.info("user"+user.getUserId()+user.getOpenDate());
return user;
}
JSP PART:
<c:url value="/user/create" var="createUrl" />
<c:url value="/user/read" var="readUrl" />
<c:url value="/user/update" var="updateUrl" />
<c:url value="/user/destroy" var="destroyUrl" />
<c:url value="/user/saveexcel" var="saveExcelUrl" />
<c:url value="/user/savepdf" var="savePdfUrl" />
<kendo:grid name="grid" pageable="true" sortable="true" height="750px" filterable="true">
<kendo:grid-scrollable/>
<kendo:grid-pdf fileName="KendoUIGridExport.pdf" allPages="allPages" proxyURL="${savePdfUrl}"/>
<kendo:grid-excel fileName="KendoUIGridExport.xlsx" allPages="allPages" proxyURL="${saveExcelUrl}" />
<kendo:grid-editable mode="popup" confirmation="Are you sure you want to remove this item?"/>
<kendo:grid-toolbar>
<kendo:grid-toolbarItem name="create"/>
<kendo:grid-toolbarItem name="excel"/>
<kendo:grid-toolbarItem name="pdf"/>
</kendo:grid-toolbar>
<kendo:grid-columns>
<kendo:grid-column title="User Name" field="userName" width="120px"/>
<kendo:grid-column title="First Name" field="firstName" width="120px" />
<kendo:grid-column title="Last Name" field="lastName" width="120px" />
<kendo:grid-column title="Open Date" field="openDate" width="120px" format="{0:MM/dd/yyyy}" />
<kendo:grid-column title="Edit Date" field="editDate" width="120px" format="{0:MM/dd/yyyy}" />
<kendo:grid-column title=" " width="150px">
<kendo:grid-column-command>
<kendo:grid-column-commandItem name="edit" />
<kendo:grid-column-commandItem name="destroy" />
</kendo:grid-column-command>
</kendo:grid-column>
</kendo:grid-columns>
<kendo:dataSource pageSize="10" serverPaging="false" serverSorting="false" serverFiltering="false" serverGrouping="false" >
<kendo:dataSource-transport>
<kendo:dataSource-transport-create url="${createUrl}" type="POST" dataType="json" contentType="application/json"/>
<kendo:dataSource-transport-read url="${readUrl}" type="POST" dataType="json" contentType="application/json"/>
<kendo:dataSource-transport-update url="${updateUrl}" type="POST" dataType="json" contentType="application/json" />
<kendo:dataSource-transport-destroy url="${destroyUrl}" type="POST" dataType="json" contentType="application/json" />
<kendo:dataSource-transport-parameterMap>
<script>
function parameterMap(options,type) {
return JSON.stringify(options);
}
</script>
</kendo:dataSource-transport-parameterMap>
</kendo:dataSource-transport>
<kendo:dataSource-schema>
<kendo:dataSource-schema-model id="userId">
<kendo:dataSource-schema-model-fields>
<kendo:dataSource-schema-model-field name="userName" type="string" >
<kendo:dataSource-schema-model-field-validation required="true" />
</kendo:dataSource-schema-model-field>
<kendo:dataSource-schema-model-field name="firstName" type="string">
<kendo:dataSource-schema-model-field-validation required="true" />
</kendo:dataSource-schema-model-field>
<kendo:dataSource-schema-model-field name="lastName" type="string">
<kendo:dataSource-schema-model-field-validation required="true" />
</kendo:dataSource-schema-model-field>
<kendo:dataSource-schema-model-field name="openDate" type="date" editable="false" />
<kendo:dataSource-schema-model-field name="editDate" type="date" editable="false"/>
</kendo:dataSource-schema-model-fields>
</kendo:dataSource-schema-model>
</kendo:dataSource-schema>
</kendo:dataSource>
</kendo:grid>
Resolved myself: For pdf, allPages="true" works.
Grid refresh: FOR requestEnd event
function onRequestEnd(e) {
if (e.type == "create") {
e.sender.read();
}
else if (e.type == "update") {
e.sender.read();
}
}