Angular
In an Angular application, two npm packages add the DS Server components: tx-ds-document-editor for the Document Editor and tx-ds-document-viewer for the Document Viewer. Each component loads its script from DS Server, gets an access token and creates the editor or viewer in your template. Their attributes, defaults, settings objects and load events are listed below, taken from the README and the type declarations of version 5.0.0.
Step-by-step tutorials are in Getting Started: Document Editor in Angular and Document Viewer in Angular.
Packages and Requirements
| Package | Version | Module | Component | @angular/core |
|---|---|---|---|---|
| @txtextcontrol/tx-ng-ds-document-editor | 5.0.0 | DocumentEditorModule | tx-ds-document-editor | >=19.0.0 <=21.*.* |
| @txtextcontrol/tx-ng-ds-document-viewer | 5.0.0 | DocumentViewerModule | tx-ds-document-viewer | >=19.0.0 <=21.*.* |
Both packages support Angular 19, 20 and 21 through their peer dependencies on @angular/core and @angular/common, and install @angular/cdk in the same version range. Their READMEs require DS Server 5.0.0 or later. You also need a security profile of your DS Server, or a trial token, as Overview explains.
Install the Packages
Add a package with the Angular CLI in the folder of your project:
ng add @txtextcontrol/tx-ng-ds-document-editor
ng add @txtextcontrol/tx-ng-ds-document-viewer
ng add installs the package and imports its module into the root module of the application; for the viewer, it also imports HttpClientModule. The viewer component always needs HttpClient, which it uses to request its access token.
The components are declared in their modules, not as standalone components. The Angular CLI creates standalone applications by default since version 17. In such an application, ng add installs the package but finds no root module to import into: the schematic of version 5.0.0 prints a message that asks you to add the module (and, for the viewer, HttpClientModule) to your components yourself, while the READMEs name the error Bootstrap call not found. Either create the project with ng new --no-standalone, or import the module yourself into the imports of the standalone component that shows the editor or viewer, and for the viewer add HttpClientModule as well:
import { Component } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { DocumentViewerModule } from '@txtextcontrol/tx-ng-ds-document-viewer';
({
selector: 'app-root',
imports: [DocumentViewerModule, HttpClientModule],
templateUrl: './app.component.html'
})
export class AppComponent { }
Write the Attributes
In a template, write string values as plain attributes. Bind Boolean values, numbers, arrays and objects with square brackets:
<tx-ds-document-editor
width="1000px"
height="600px"
serviceURL="https://ds.example.com"
oauthClientID="<client ID>"
oauthClientSecret="<client secret>"
editMode="ReadAndSelect"
[userNames]="['user1', 'user2']">
</tx-ds-document-editor>
width, height and serviceURL are required. serviceURL must start with http:// or https://; otherwise, the component throws the error Invalid service URL. When the component is initialized, it removes oauthClientID and oauthClientSecret from the rendered element.
tx-ds-document-editor
| Attribute | Type | Default | Description |
|---|---|---|---|
width | string | none | The width of the component, such as "1024px" |
height | string | none | The height of the component |
serviceURL | string | none | The URL of DS Server |
oauthClientID | string | none | The client ID of the security profile |
oauthClientSecret | string | none | The client secret of the security profile |
accessToken | string | none | An access token your application has requested; when it is set, oauthClientID and oauthClientSecret are ignored |
documentData | string | none | A document to load, Base64-encoded |
documentFileFormat | string | none | The format of documentData, required with it: 'HTML', 'RTF', 'TXT', 'TX', 'DOC', 'PDF', 'DOCX' or 'XLSX' |
jsonData | string | none | The JSON data source for the Reporting tab |
editMode | string | 'Edit' | 'Edit', 'ReadAndSelect', 'ReadOnly' or 'UsePassword' |
contextMenusEnabled | boolean | true | Whether a right-click opens a context menu |
formattingPrinter | string | '' | The name of a printer whose text dimensions and capabilities are used to format the document |
culture | string | '' | The culture for formats such as dates and times, such as 'de-DE' |
uiCulture | string | '' | The culture of the user interface strings, such as 'en-US' |
userNames | string[] | [] | The users who can edit the editable regions assigned to them when the document is read-only |
reconnectTimeout | number | 0 | The time in seconds after which the editor stops trying to reconnect after the connection is lost |
customQueryParams | object | {} | Query parameters the editor adds to the address of its WebSocket connection |
The component loads documentData when the editor raises textControlLoaded, and jsonData when it raises ribbonTabsLoaded.
The dsDocumentEditorLoaded Event
The component loads the editor script from DS Server at run time, so the global TXTextControl object doesn't exist when your component is created. When the script has loaded, the component raises dsDocumentEditorLoaded on the document object. Handle it in the component that holds the editor:
import { Component, HostListener } from '@angular/core';
declare const TXTextControl: any;
({
selector: 'app-root',
templateUrl: './app.component.html',
standalone: false
})
export class AppComponent {
('document:dsDocumentEditorLoaded')
onDsDocumentEditorLoaded() {
// TXTextControl exists from now on
TXTextControl.addEventListener('ribbonTabsLoaded', () => {
console.log('The ribbon tabs have been loaded.');
});
}
}
From then on, your code works with the TXTextControl object of the Document Editor's JavaScript API.
tx-ds-document-viewer
| Attribute | Type | Default | Description |
|---|---|---|---|
width | string | none | The width of the component, such as "1024px" |
height | string | none | The height of the component |
serviceURL | string | none | The URL of DS Server |
oauthClientID | string | none | The client ID of the security profile |
oauthClientSecret | string | none | The client secret of the security profile |
accessToken | string | none | An access token your application has requested; when it is set, oauthClientID and oauthClientSecret are ignored |
documentData | string | none | The document to display, Base64-encoded |
documentPath | string | none | The document name the viewer displays |
documentLoadSettings | DocumentLoadSettings | see below | How the document is loaded |
userNames | string[] | [] | The users who have access to editable regions |
dock | string | 'Fill' | How the viewer is docked: 'Fill' or 'Window' |
toolbarDocked | boolean | true | Whether the toolbar is docked or floating |
isSelectionActivated | boolean | true | Whether text can be selected and copied |
showThumbnailPane | boolean | true | Whether the thumbnail pane is visible |
resources | object | null | Strings of the user interface, as pairs of resource name and text |
signatureSettings | SignatureSettings | see below | The settings of a signature process |
customQueryParams | object | null | Custom query parameters, passed to the viewer as customQueryParams of its settings |
showThumbnailPane is an input of the component that the README doesn't list.
DocumentLoadSettings
| Property | Type | Default | Description |
|---|---|---|---|
loadEmbeddedComments | boolean | true | Whether comments in the document are loaded as annotations |
pdfjs | PDFJSSettings | see below | The location of PDF.js, which the viewer uses for PDF documents |
pdfjs.workerSourcePath | string | null | The path of the PDF.js worker script |
pdfjs.librarySourcePath | string | null | The path of the PDF.js library script |
SignatureSettings
| Property | Type | Default | Description |
|---|---|---|---|
showSignatureBar | boolean | false | Whether the signature bar is shown |
ownerName | string | '' | The name of the document owner |
signerName | string | '' | The name of the signer |
signerInitials | string | '' | The initials of the signer |
signatureBoxes | SignatureBox[] | [] | The boxes to sign |
signatureBoxName | string | 'txsign' | Deprecated: the name of the signature box; use signatureBoxes |
defaultSignatureFont | SignatureFontSettings | none | The default font of text-based signatures: family, a CSS font family |
uniqueId | string | '' | A unique ID of the signature |
redirectUrlAfterSignature | string | '' | The URL to which DS Server sends the signed document in an HTTP POST request after a successful signing process, as a SignatureData object (see Custom Signing Endpoints) |
customSigning | boolean | false | Whether your own code handles the signing process |
A SignatureBox has a name, signingRequired, which is true by default, and a style: "Signature", the default, or "Initials".
<tx-ds-document-viewer
width="1000px"
height="800px"
serviceURL="https://ds.example.com"
oauthClientID="<client ID>"
oauthClientSecret="<client secret>"
documentData="SGVsbG8gdGhlcmU="
[signatureSettings]="{
showSignatureBar: true,
ownerName: 'Paul',
signerName: 'Jacob',
signerInitials: 'JK',
redirectUrlAfterSignature: 'https://your.app/signed',
signatureBoxes: [{ name: 'txsign', signingRequired: true, style: 'Signature' }]
}">
</tx-ds-document-viewer>
The dsDocumentViewerLoaded Event
The viewer loads its script from DS Server as well. When it has initialized the viewer, the component raises dsDocumentViewerLoaded on the document object. Handle it with @HostListener('document:dsDocumentViewerLoaded'), as for the editor, and work with the TXDocumentViewer object from then on.
How the Components Authorize
With oauthClientID and oauthClientSecret, the components request their token from DS Server with the client credentials grant type, which the security profile must allow, and the credentials are visible in the page. To keep them on the server, request the token there and bind it to accessToken; the blog article DS Server: Authorizing Angular Client Components shows an ASP.NET Core endpoint that does it. Overview compares the options.