In many document processes, a streamlined collaboration workflow enables an enormous productivity gains. In today's modern structures and specifically and remote work setups, collaboration processes are required to keep and increase productivity.
There are many commercial "out-of-the-box" tools and services to share documents. But integrating document review and approval workflows directly into your applications helps to streamline those processes and to keep your data in your own infrastructure.
Full Integration
Using TX Text Control and the DocumentViewer, documents can be shared across platforms and browsers. The DocumentViewer can be used to:
- Share documents
- Complete form fields
- Request signatures
- Add annotations
Event Handling
With the latest pre-release version of the DocumentViewer, we introduced an event handling for annotation changes. The following JavaScript code shows how to add this event handler:
TXDocumentViewer.addEventListener( | |
"annotationsChanged", | |
function() { alert("annotation changed!"); }); |
The sample in this article uses this new event and SignalR to synchronize annotations and annotation changes with other users.
Comments are also synchronized automatically when adding them to the annotations:
Using SignalR
The sample implements a very simple class AnnotationSync that is shared with all connected users in the SignalR Hub:
public class CollabHub : Hub | |
{ | |
public async Task SetAnnotationSync(AnnotationSync annotationSync) | |
{ | |
await Clients.All.SendAsync("ReceiveAnnotationSync", annotationSync); | |
} | |
} | |
public class AnnotationSync | |
{ | |
public string User { get; set; } | |
public string AnnotationJson { get; set; } | |
} |
The AnnotationJson can be exported and imported into the DocumentViewer and contains all annotations. It is a very small JSON package and therefore, it can be easily shared to synchronize the changes. The following JavaScript code shows how to listen for the SignalR changes in order to load the JSON into the DocumentViewer:
var _updating; | |
var _connection; | |
// connect to signalr hub | |
_connection = new signalR.HubConnectionBuilder().withUrl("/collabHub").build(); | |
_connection.start(); | |
_connection.on("ReceiveAnnotationSync", async function (annotationSync) { | |
// set flag to avoid infinite loops | |
_updating = true; | |
var currentJson = TXDocumentViewer.annotations.export(); | |
if (currentJson != annotationSync.annotationJson) | |
TXDocumentViewer.annotations.load(annotationSync.annotationJson); | |
setTimeout(function () { | |
_updating = false; | |
}, 1000); | |
}); |
Finally, the event annotationsChanged is used to export the annotations in order to invoke the server-side synchronization:
window.addEventListener("documentViewerLoaded", function () { | |
TXDocumentViewer.addEventListener("annotationsChanged", updateAnnotations); | |
}); | |
function updateAnnotations() { | |
if (_updating === true) | |
return; | |
var jsonAnnotations = TXDocumentViewer.annotations.export(); | |
// create sync object | |
var collaborationSyncObject = { | |
User: "Test", | |
AnnotationJson: jsonAnnotations | |
}; | |
// call signalr hub with sync object | |
_connection.invoke("SetAnnotationSync", | |
collaborationSyncObject).catch(function (err) { | |
return console.error(err.toString()); | |
} | |
); | |
} |
Download Sample
You can test this on your own by downloading the sample form our GitHub repository.