onDownloadAs event is not triggered

I am using the ONLYOFFICE Community Edition in my React.js project with the @onlyoffice/document-editor-react npm package. We have a requirement where, if the user clicks the Download As option in the document editor’s file menu, I need to make an API call to log who downloaded the document for audit purposes. I attempted to use the onDownloadAs event, but when I click the Download As option, the onDownloadAs event is not triggered.

Could you please assist me with this issue?

Hello @jeeva

Please note that Document Server is a tool for editing documents. When it comes to audit logging, the storage is responsible for gathering such information.

I believe workaround to this situation is to restrict downloading of the document via editor interface with Download as button and only leave option to perform download from your storage app.

Hi Constantine,

Thank you for your reply!

I believe there might be a slight misunderstanding. My main issue is not related to audit logging, but rather that the “Download As” event itself is not being triggered in the document editor.

We need to use the onDownloadAs event to execute custom logic (like making an API call) when a user clicks the “Download As” option in the file menu. However, the event is not being triggered when the button is clicked, which is the primary issue we’re facing.

Could you please assist with this or suggest any workaround to ensure that the “Download As” event is triggered properly?

Thank you again for your help!

Since React component does not support this method directly, you need to declare it in the config with regular API methods. Here are useful links:

Hai Constantine,

  1. 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;

  1. 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:

  1. 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?
  2. 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?
  3. 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?

It is supported. Usage of this event depends on the implementation of your application, so I cannot provide any real examples. Basic example is available in the description of event:

Using this example and calling downloadAs method will return a link to the file into the browser console.

I will verify this possibility and provide a feedback.

I’m afraid not, custom buttons for Files tab are not supported.