JavaScript API
The pages about tables, fields, track changes and the other features of the Document Editor all build on the concepts of its JavaScript API. Before you write code that changes the document, get to know the TXTextControl object, when your code can use it, how its asynchronous methods return results and how its objects are organized.
What the JavaScript API Is
The Document Editor adds a global object named TXTextControl to the page. Its properties and methods give your code access to the document in the editor: the text and its formatting, tables, images, fields, sections, tracked changes and comments, the current selection and the input position. Its events tell your code what the user does.
All frontends use the same component in the browser, so the API is the same in an ASP.NET Core view, a plain JavaScript page, an Angular or React application and a Blazor page. Only the moment when the object becomes available differs.
The Document Viewer has an API of its own, the TXDocumentViewer object; see Document Viewer.
When the Object Is Available
Two moments matter: when the TXTextControl object exists, so that your code can attach event handlers, and when the editor raises textControlLoaded, after which your code can change the document.
| Frontend | The object exists | Where your code goes |
|---|---|---|
| ASP.NET Core | When the page has loaded | A <script> element in the view, below the editor. See ASP.NET Core. |
| JavaScript | When the editor script from the backend has loaded | After the call of TXTextControl.init. See JavaScript. |
| Angular | When the txDocumentEditorLoaded event is raised on document | In a handler of this event, with declare const TXTextControl: any;. See Angular. |
| React | When the function of the onLoad property runs | In this function. See React. |
| Blazor | In the page that contains the component | JavaScript in the page. See Blazor. |
In every frontend, wait for textControlLoaded before you read or change the document:
TXTextControl.addEventListener("textControlLoaded", function () {
// The editor is ready: the document can be read and changed from here on
TXTextControl.selection.setText("Hello from the JavaScript API");
});
Events describes the order of the events during initialization.
Settings of TXTextControl.init
In a plain JavaScript page, TXTextControl.init creates the editor from a ComponentSettings object, and its editorSettings property holds a DocumentEditorSettings object. Both were added in version 32.0. The JavaScript tutorial shows the call.
ComponentSettings property | Sets |
|---|---|
| containerID, containerElement | The div element the editor is placed in, by its ID or as the element; containerID is always required, also when containerElement is set, and containerElement wins if both are set |
| webSocketURL | The WebSocket URL of the backend; required |
| replaceContainer | true replaces the container element with the editor instead of adding the editor to it as a child |
| domContentLoaded | A function that is called as soon as the elements of the editor have been inserted into the page |
| editorSettings | The DocumentEditorSettings below |
DocumentEditorSettings property | Sets |
|---|---|
| editMode | Whether the text is read-only, can be selected or can be edited, a value of EditMode |
| userNames | The users who can edit their editable regions of a read-only document |
| culture, uiCulture | The culture of formats such as dates, and the language of the user interface |
| contextMenusEnabled | Whether a right-click opens a context menu |
| reconnectTimeout | How many seconds the editor tries to reconnect after the connection is lost |
| connectionID | A unique ID string of the connection |
| webSocketProtocols | Additional WebSocket subprotocols, for example to pass an authentication token |
| customQueryParams | An object of custom query parameters |
| formattingPrinter | The name of a printer whose text dimensions format the document |
The formatting printer, like setFormattingPrinter, is only used by the Windows-based synchronization service of earlier versions. The platform-independent backend of the current version doesn't support printer-specific formatting, so the setting has no effect there; see Viewing and Printing.
Callbacks
Many methods of the API are asynchronous. They don't return a value; instead, they take a callback function that receives the result when it is available:
function showSelection() {
TXTextControl.selection.getStart(function (start) {
TXTextControl.selection.getLength(function (length) {
console.log("The selection starts at " + start + " and is " + length + " characters long");
});
});
}
- Selection.getStart passes the start position of the selection to its callback.
- The second call runs inside the first callback, because it needs the result of the first. Code after
getStartin the same function would run before the callback. - Methods that return nothing, such as most set methods, take an optional callback that is called when the operation has completed. Use it when the next step depends on the change.
Some members return their result directly: btoaUTF8 and atobUTF8 encode and decode strings, and properties such as TXTextControl.selection return objects directly.
Handle Errors
Many methods take an optional error callback as their last parameter. It receives an ErrorArgument with the error message in msg. By default, an error that isn't handled is thrown. Set handled to true to stop that:
function getTableCount() {
TXTextControl.tables.getCount(function (count) {
console.log(count + " tables");
}, function (error) {
console.log("Failed: " + error.msg);
error.handled = true; // don't throw the error
});
}
The unhandledError event is raised before an error is thrown, so a single handler can log all errors that no error callback handles.
Promises and async/await
The API has no methods that return promises. When several calls depend on each other, nested callbacks become hard to read. Wrap a call in a Promise and use async and await instead:
function getSelectionRange() {
return new Promise(function (resolve, reject) {
TXTextControl.selection.getStart(function (start) {
TXTextControl.selection.getLength(function (length) {
resolve({ start: start, length: length });
}, reject);
}, reject);
});
}
async function logSelection() {
var range = await getSelectionRange();
console.log(range.start + ", " + range.length);
}
Awaiting each step also keeps the order: calls that are sent one after another without waiting aren't guaranteed to complete in that order. This matters especially when a loop changes the text of many elements. The blog article New JavaScript API: Working with Callbacks and Promises explains the pattern.
The Object Model
Text Parts
A document consists of text parts: the main text, the headers and footers and the text frames. Each text part is a FormattedText object, which provides the collections of that part, such as tables, paragraphs, textFields, formFields, trackedChanges and comments, and its own selection.
TXTextControl itself inherits from FormattedText and represents the main text. TXTextControl.tables therefore returns the tables of the main text, while a HeaderFooter or a TextFrame returns its own tables through the same property. In the reference, these inherited members are documented on the FormattedText page.
Collections
Collections such as TableCollection or SectionCollection derive from Collection, which provides three methods:
- getCount passes the number of elements to its callback.
- elementAt passes the element at an index.
- forEach calls a function for each element with the element, its index and the number of elements.
Each collection adds its own methods, such as add, getItem and remove.
Objects of the Main Text
Besides the inherited collections, TXTextControl has properties for the whole document, for example:
| Property | Returns |
|---|---|
| selection | The current Selection, with its text and formatting |
| inputPosition | The InputPosition: page, line, column and text position of the cursor |
| sections | The sections of the document |
| headersAndFooters | All headers and footers of the document |
| images and textFrames | The images of the text part with the input focus, and all text frames of the document |
| textParts | All text parts: the main text, the text frames and the headers and footers |
| ribbon | The ribbon bar |
To select text, assign an object with the start position and the length: TXTextControl.selection = { start: 2, length: 5 };. A SubTextPart is a part of the text that your code defines, to work with a smaller piece of the document. Editing Text and Subtext Parts describe both.
Enumerations
Enumerations are properties of the TXTextControl object, for example TXTextControl.StreamType.WordprocessingML or TXTextControl.HighlightMode.Always. Pass these names instead of numbers.
Obsolete Members
Some older properties are marked obsolete in the reference and will be removed. They have been replaced by get and set methods, which follow the callback model: use setIsTrackChangesEnabled instead of the isTrackChangesEnabled property, and setEditMode instead of editMode. The event textControlChanged is obsolete as well; use changed. Articles written for older versions still use some of these members.
Group Changes Into One Undo Step
When your code makes several changes, each one is a step of its own for the user's undo command. Call beginUndoAction with a name before the changes and endUndoAction after them, and all changes in between are undone and redone in one step.
Remove the Editor
In a single-page application, the page isn't reloaded when the user navigates to another view. Before you remove the editor from the page or create it again, call removeFromDom. It closes the WebSocket connection gracefully and removes the editor with its event handlers and CSS references. If your code adds the editor script to the page dynamically, remove its script element as well before you load it again.
Find Members in the Reference
The JavaScript API reference lists every object with its properties, methods, callbacks and enumerations. For each method, it documents the parameters in their order, which parameters are optional, and the callback type with the value it receives. The members that a version added are listed on the What's New pages, for example Version 34.0.
Next Steps
- Events: react to what users do in the editor.
- Loading and Saving Documents: load and save documents from JavaScript.
- Text and Paragraph Formatting: format the selection.
- Tables: add and change tables.