I’m embedding the ONLYOFFICE editor using the @onlyoffice/document-editor-react
package in a React web application. I’m looking for a reliable way to automatically trigger the UpdateAllTOC()
command when the user finishes editing the document — ideally right before they leave the editor or immediately after they save.
I understand that calling Api.GetDocument().UpdateAllTOC()
is the correct way to programmatically update the table of contents, and it works fine when triggered manually via buttons or other explicit user actions.
However, my goal is to automate this process. So far, I’ve explored the following options:
What I want:
- Detect when the user has finished editing (or saving),
- Automatically run
UpdateAllTOC()
using the connector/command interface before the user leaves the editor.
What I tried:
- I tried listening to the
events_onDocumentStateChange
event and checking when event.data === false
. I then called connector.callCommand(...)
with Api.GetDocument().UpdateAllTOC()
. However, this doesn’t seem to have any effect — no TOC update, and no error in the console.
events_onDocumentStateChange={(event) => {
if (!event.data) {
connector?.callCommand(
() => {
const doc = Api.GetDocument()
doc.UpdateAllTOC()
},
() => {
console.log('TOC update done')
}
)
}
}}
I also understand that doing this on unmount or in beforeunload
is not reliable because async operations can be cut off by the browser.
My Questions:
- What is the recommended way to reliably trigger document-level commands like
UpdateAllTOC()
after editing is done?
- Is there an event in the ONLYOFFICE lifecycle that is best suited for this kind of automation?
- Why
events_onDocumentStateChange
is not working for this scenario?
Any best practices or suggestions for automating TOC updates in this type of workflow would be much appreciated.
Thanks in advance,
Leandro
Hello @leandro,
Please refer to this implementation:
"onDocumentStateChange": function (event) {
if (event.data === true) {
console.log("Document state changed, updating TOC. Type:", event.data);
connector.callCommand(
function () {
var doc = Api.GetDocument();
doc.UpdateAllTOC();
},
function () {
console.log('TOC update done!');
},
false // remember to provide isNoCalc (https://api.onlyoffice.com/docs/docs-api/usage-api/automation-api/#callcommand) callCommand's parameter
);
}
}
But please make sure that:
- The Connector is being initialized in onDocumentReady event:
"onDocumentReady": function() {
connector = docEditor.createConnector();
}
- You set up onDocumentStateChange event correctly: Events | ONLYOFFICE
Hi @DmitriiV,
I am using the @onlyoffice/document-editor-react
react component like this, and tried what you said, the connector is being initialized and events_onDocumentStateChange is being called I see it in the console, but the console.log inside the callCommand is never shown ( console.log('UpdateAllTOC')
), for some reason is not being called the callCommand callback that update the TOC
<DocumentEditor
config={documentEditorConfig}
documentServerUrl={DOCUMENT_SERVER_URL as string}
events_onDocumentReady={() => {
const connector = window.DocEditor.instances[DOC_EDITOR_ID].createConnector()
setConnector(connector)
}}
events_onDocumentStateChange={event => {
if (event.data === true) {
console.log('Document state changed, updating TOC. Type:', event.data)
connector.callCommand(
function () {
const doc = Api.GetDocument()
console.log('UpdateAllTOC')
doc.UpdateAllTOC()
},
function () {
console.log('TOC update done!')
},
false
)
}
}}
id={DOC_EDITOR_ID}
onLoadComponentError={onLoadComponentError}
/>
Your implementation is correct. Please make sure that you are using Document Server Developer Edition with Connector available. Additionally, check if other methods work with Connector
Yes I am using Document Server Developer Edition with Connector available, I am using this same connector state which I set here
events_onDocumentReady={() => {
const connector = window.DocEditor.instances[DOC_EDITOR_ID].createConnector()
setConnector(connector)
}}
to get selected text in an AI chat that interact with the document
connector?.executeMethod('GetSelectedText', [], (selectedText: string) => {
resolve(selectedText || null)
})
Also to add context menu items like this
connector?.attachEvent('onContextMenuShow', data => {
if (data?.type === 'Selection') {
connector?.addContextMenuItem([
{
onClick: onClickEditWithAI,
text: 'Edit with AI'
}
])
}
All these in this same instance of the editor and all of them works perfectly but for some unknown reason the connector.callCommand in events_onDocumentStateChange is not executed
Thank you for the provided details, we are checking, I will share as soon as I have news
Please try doing according to the below example (do not change any syntaxis, etc.):
const onDocumentStateChange = (event) => {
const connector = window.DocEditor.instances["docxEditor"].createConnector();
if (event.data === true) {
console.log("Document state changed, updating TOC. Type:", event.data);
connector.callCommand(() => {
// eslint-disable-next-line
const doc = Api.GetDocument();
console.log("UpdateAllTOC");
doc.UpdateAllTOC();
},
() => {
console.log("TOC update done!");
}
);
}
};
And add this to the config:
events:{
onDocumentStateChange: onDocumentStateChange
}