Hai Constantine,
- I’ve implemented the
onDownloadAs
event handler but still it’s not working
import Box from '@mui/material/Box';
import { DocumentEditorProps } from '../../interface/common';
import { OnlyOfficeDocumentType } from '../../utils/constants';
import { useGetUserQuery } from '../../store/Services/userService';
import { useAppSelector } from '../../store/hooks';
const documentServerUrl = 'http://localhost:80';
// Function to dynamically load external scripts
const loadScript = (src: string): Promise<void> => {
return new Promise((resolve, reject) => {
const existingScript = document.querySelector(`script[src="${src}"]`);
if (!existingScript) {
const script = document.createElement('script');
script.src = src;
script.async = false; // Important to maintain order
script.onload = () => {
resolve();
};
script.onerror = () => {
reject(new Error(`Failed to load script: ${src}`));
};
document.body.appendChild(script);
} else {
resolve();
}
});
};
const CustomizedDocumentEditor: React.FC<DocumentEditorProps> = ({
fileName,
id,
url,
mode,
token,
from,
isSave = false,
}) => {
// Fetch user data
useGetUserQuery('');
const { userId, fullName } = useAppSelector((state) => state.user);
// Determine file type and document type
const fileType = fileName.split('.').pop() || '';
const documentType = fileType
? OnlyOfficeDocumentType[fileType as keyof typeof OnlyOfficeDocumentType] || 'word'
: 'word';
// Prepare callback URL if saving is enabled
let callbackObj: { [key: string]: any } = {};
if (isSave) {
callbackObj = {
callbackUrl: `${process.env.REACT_APP_API_BASE_URL}/document/only-office/callback?id=${id}&from=${from}&userId=${userId}`,
};
}
// References for the editor container and instance
const editorContainerRef = useRef<HTMLDivElement>(null);
const editorInstanceRef = useRef<any>(null);
// State to track when the editor is ready
const [editorReady, setEditorReady] = useState(false);
useEffect(() => {
let isMounted = true;
// Function to initialize the editor after scripts are loaded
const initializeEditor = () => {
if ((window as any).DocsAPI && editorContainerRef.current) {
const config = {
document: {
fileType: fileType,
title: fileName,
url: url,
permissions: {
chat: false,
comment: false,
copy: true,
deleteCommentAuthorOnly: false,
download: true,
edit: !!isSave,
editCommentAuthorOnly: false,
fillForms: false,
modifyContentControl: false,
print: true,
protect: false,
review: false,
},
},
editorConfig: {
user: {
name: fullName || '',
id: userId || '',
},
mode: isSave ? 'edit' : mode || 'view',
customization: {
forcesave: isSave,
autosave: false,
toolbarNoTabs: true,
buttons: [
// List other buttons you want to include
'open',
'save',
'undo',
'redo',
'print',
// Exclude 'downloadAs' button
],
},
...callbackObj,
},
events: {
onDocumentReady: function () {
console.log('Document is ready');
setEditorReady(true);
},
onDownloadAs: function (data: any) {
console.log('Download As event triggered:', data);
// Implement your custom logic here
window.location.href = data.url;
},
// ... other events if needed ...
},
documentType: documentType,
token: token,
};
// Initialize the OnlyOffice editor
const editor = new (window as any).DocsAPI.DocEditor(
editorContainerRef.current.id,
config
);
editorInstanceRef.current = editor;
} else {
console.error('OnlyOffice scripts are not loaded.');
}
};
// Load scripts and initialize the editor
Promise.all([
loadScript(`${documentServerUrl}/web-apps/apps/api/documents/api.js`),
// You can add sdkjs.plugins.js if needed
])
.then(() => {
if (isMounted) {
initializeEditor();
}
})
.catch((error) => {
console.error('Error loading OnlyOffice scripts:', error);
});
// Cleanup function to destroy the editor instance
return () => {
isMounted = false;
if (editorInstanceRef.current) {
editorInstanceRef.current.destroyEditor();
editorInstanceRef.current = null;
}
};
}, [
fileType,
fileName,
url,
isSave,
mode,
fullName,
userId,
documentType,
callbackObj,
token,
documentServerUrl,
]);
return (
<Box sx={{ marginTop: '40px', width: '100%', height: '100vh' }}>
<button
disabled={!editorReady}
onClick={() => {
if (editorInstanceRef.current) {
editorInstanceRef.current.downloadAs();
}
}}
>
Download As
</button>
{/* Editor container */}
<div
id="docxEditor"
ref={editorContainerRef}
style={{ width: '100%', height: '100vh' }}
></div>
</Box>
);
};
export default CustomizedDocumentEditor;
- Unable to Hide “Download As” Button While Keeping “Save As Copy”:
- I want to hide the “Download As” button but keep the “Save As Copy” button visible and functional.
- I’ve tried various configurations in the
customization
object:
Option 1:
customization: {
toolbar: {
file: {
downloadAs: false,
saveAs: true,
open: true,
save: true,
},
},
},
Option 2:
customization: {
features: {
downloadAs: false,
},
},
Option 3:
customization: {
menu: {
fileMenu: {
downloadAs: false,
saveAs: true,
open: true,
save: true,
},
},
},
Using serviceCommand
:
- I tried using
serviceCommand
to manipulate the editor:
editorInstanceRef.current.serviceCommand('command', {
name: 'insertButton',
params: {
buttonName: 'CustomDownloadButton',
buttonOptions: {
text: 'Download As New Format',
tooltip: 'Download document in a different format',
execute: function () {
editorInstanceRef.current.downloadAs();
},
},
},
});
Questions:
- Is the
onDownloadAs
Event Supported in the Community Edition Version 8.1.1? If supported, could you please provide a sample code demonstrating how to implement this event effectively?
- How Can I Hide the “Download As” Button Alone Without Affecting the “Save As Copy” Option? Currently, when I set
download: false
in the permissions, the “Save As Copy” option is also hidden. Is there a way to hide only the “Download As” button while keeping “Save As Copy” accessible to users?
- Is It Possible to Add a Custom Button Using the
serviceCommand
Method? If so, could you provide a sample code example on how to implement a custom button within the OnlyOffice editor using serviceCommand
?