[]
The reports storage type and the exact manner to save a report displayed in the ActiveReportsJS designer's instance depend on the application's architecture. This page provides recipes for several common scenarios.
The ActiveReportsJS Report Designer component contains the "Save" and "Save As" buttons on the toolbar.
They are not enabled and not visible by default, however. The code should set up onSave
and onSaveAs
action handlers for the designer component instance to enable these buttons. Check Action Handlers page for more information. The onSaveAs
handler should return the Promise
that resolves to the object containing the id
and the optional displayName
properties of the report - the former uniquely identifies the report, the latter displays on the top bar of the designer component. The onSave
handler should return the Promise
that resolves to the object containing the optional displayName
property of the report.
Here is the example of the onSave
and onSaveAs
handlers that save reports in the React application's in-memory storage. You can use similar approach to save reports by sending requests to the REST API because these handlers are async
functions that return the Promise
object.
import React, { Fragment } from "react";
import {
Designer as ReportDesigner,
} from "@grapecity/activereports/reportdesigner";
export const DesignerHost: React.FC = () => {
const designerRef = React.useRef<ReportDesigner | undefined>();
const counter = React.useRef<number>(0);
const [reportStorage, setReportStorage] = React.useState(new Map());
React.useEffect(() => {
designerRef.current = new ReportDesigner("#designer-host");
designerRef.current.setActionHandlers({
onSave: function (info) {
const reportId = info.id || `report${counter.current++}`;
setReportStorage(new Map(reportStorage.set(reportId, info.definition)));
return Promise.resolve({displayName: reportId});
},
onSaveAs: function (info) {
const reportId = info.id || `report${counter.current++}`;
setReportStorage(new Map(reportStorage.set(reportId, info.definition)));
return Promise.resolve({id: reportId, displayName: reportId });
},
});
}, []);
return (
<div id="designer-host"></div>
);
};
Visit the Live Demo for the complete examples for React, Angular, Vue, and pure JavaScript applications.
The processCommand method of the ActiveReportsJS Report Designer component's instance accepts one of the save,
saveAs,
create,
open,
and render
arguments and invokes the corresponding action handler. Check Action Handlers page for more information. The getReport
method of the designer component returns the current report's info, including the isDirty
flag that indicates whether the report changed since the last save. It is possible to implement autosave functionality by using these two methods together. Here is the example of this approach for a React application, and Angular, Vue, or pure JavaScript applications can use the same technique.
import {
Designer as ReportDesigner,
templates,
} from "@grapecity/activereports/reportdesigner";
import React, { Fragment } from "react";
import "@grapecity/activereports/styles/ar-js-ui.css";
import "@grapecity/activereports/styles/ar-js-designer.css";
export const DesignerHost: React.FC = () => {
const designerRef = React.useRef<ReportDesigner | undefined>();
React.useEffect(() => {
designerRef.current = new ReportDesigner("#designer-host");
// onSave and onSave handlers are defined here just as shown above
const saveIntervalId = setInterval(async () => {
const reportInfo = await designerRef.current?.getReport();
if (reportInfo?.isDirty) {
designerRef.current?.processCommand("save");
}
}, 2000);
return () => clearInterval(saveIntervalId);
}, []);
return (
<div id="designer-host"></div>
);
};