Working asynchronously on a document with multiple authors is an important feature in many processes. Have in mind a contract that is to be the subject of negotiation between 2 or more parties. Traditionally, these documents are sent back and forth as an MS Word document to be red-lined by each of the parties involved. When implementing a document collaboration process, this is still very common and should be compatible.

With TX Text Control, comments can be added to any area of text and changes can be tracked. These comments are compatible with MS Word and can be imported and exported to and from supported formats.

Web-Based Collaboration

In modern web-based applications, documents do not need to be shared, but can be redlined directly in the browser by all participants.

The following is a screen capture video that shows the comments feature in action:

Red-Lining in TX Text Control

Combine Track Changes and Comments

Comments can also be added directly to tracked changes using the right-click menu or the ribbon bar. These comments are linked to the tracked change, so that when the change is removed (accepted or rejected), the comment is automatically removed as well.

Red-Lining in TX Text Control

The intelligent combination of tracked changes and the new comments feature provides a powerful toolkit for building collaborative processes into your applications.

A comment contains the location (index), the comment text, a timestamp, and author information. In addition, a comment can contain replies from other authors, which are stored in those comments to allow for a conversation.

JavaScript API

The JavaScript API provides a powerful interface to customize the behavior of comments in the Document Editor. The following code shows how to add a comment to the current input position:

async function insertComment(comment) {
return new Promise((resolve, reject) => {
TXTextControl.comments.add(comment, (e) => {
e.comment.getComment((comment) => {
resolve(comment);
});
});
});
}
view raw test.js hosted with ❤ by GitHub

Now, you can call insertComment function using async/await to handle it asynchronously:

const insertedComment = await insertComment("This is a new comment");
console.log(insertedComment);
view raw test.js hosted with ❤ by GitHub

Looping Through Comments

A forEach method for looping through all comments is provided in the comments collection. The following code returns the commented text and the comment for all comments in a document.

TXTextControl.comments.forEach((comment) => {
comment.getText((text) => {
comment.getComment((commentText) => {
console.log(text + ": " + commentText);
});
});
});
view raw test.js hosted with ❤ by GitHub

Getting Replies

Replies to a comment can be retrieved using the getReplies method. The following code shows how to get all replies for a all comments.

async function processComments() {
TXTextControl.comments.forEach(async (comment) => {
const replies = await new Promise((resolve, reject) => {
comment.getReplies((replies) => {
resolve(replies);
});
});
replies.forEach(async (reply) => {
const replyComment = await new Promise((resolve, reject) => {
reply.getComment((replyComment) => {
resolve(replyComment);
});
});
console.log(replyComment);
});
});
}
view raw test.js hosted with ❤ by GitHub

Deleting Comments

Comments can be deleted using the remove method. The following code shows how to delete all comments written by a specific author.

function deleteCommentsByName(index, numComments, TXTextControl, name) {
if (index >= numComments) {
return;
}
TXTextControl.comments.elementAt(index, (comment) => {
comment.getUserName((author) => {
if (author === name) {
TXTextControl.comments.remove(comment, () => {
TXTextControl.comments.getCount((newNumComments) => {
deleteCommentsByName(0, newNumComments, TXTextControl, name);
});
});
} else {
deleteCommentsByName(index + 1, numComments, TXTextControl, name);
}
});
});
}
TXTextControl.comments.getCount((numComments) => {
deleteCommentsByName(0, numComments, TXTextControl, "Tim Typer");
});
view raw test.js hosted with ❤ by GitHub

If a field is removed, all of the fields must be recursively fetched again, since the collection has been changed.

Locking Comments

You can programmatically lock comments added by authors other than the current user. The following code uses commentChanged and commentDeleted events to compare the author name with the current username to undo the action.

// Enable commands for TXTextControl
TXTextControl.enableCommands();
// Add event listeners for comment changes and deletions
TXTextControl.addEventListener("commentChanged", preventComment);
TXTextControl.addEventListener("commentDeleted", preventComment);
// Function to prevent comment changes from other authors
function preventComment(comment) {
TXTextControl.getUserNames(userNames => {
if (comment.commentedText.userName !== userNames[0]) {
TXTextControl.undo(() => {
TXTextControl.sendCommand(TXTextControl.Command.CommentsViewerRefresh);
alert("Comments from other authors cannot be changed!");
});
}
});
}
view raw test.js hosted with ❤ by GitHub

Conclusion

The Comments JavaScript API is a powerful interface to customize the behavior of comments in the Document Editor. This article provides useful tips and tricks to get the most out of it.