# Track Changes

> Track changes in the Document Editor: set the author, turn tracking on from JavaScript, list, accept and reject tracked changes and show the sidebar.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Document Editor > Track Changes
- **3105 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/track-changes/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/track-changes/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/track-changes/llms-full.txt

---

Review and approval workflows let several people change a document while someone decides which changes to keep. Track changes in the Document Editor supports them, and your code sets the author, turns tracking on and off, lists tracked changes and accepts or rejects them through the JavaScript API.

The examples extend the view of the [ASP.NET Core](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/document-editor/aspnet-core/llms-full.txt) tutorial.

### How Track Changes Works

When tracking is turned on, the editor records every insertion and deletion as a tracked change, with the name of the author and the time, and highlights it, so reviewers see what has changed. Each change stays marked until someone accepts it, which keeps the change, or rejects it, which undoes it.

Turning tracking off only stops the recording of new changes. Changes that were already recorded stay marked until they are accepted or rejected.

Users turn tracking on with the **Track Changes** button on the **Proofing** tab of the ribbon. The **Track Changes** group of the tab also accepts and rejects changes and moves through them. The sidebar, titled **Tracked Changes**, lists all changes with their author and time and lets users move through them and accept or reject them:

![Service agreement in the Document Editor with insertions underlined and deletions struck through in the color of their author, the Proofing tab with the Track Changes group, and the Tracked Changes sidebar listing five changes by Tim Typer and Paul Proof with kind and time](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/track-changes-sidebar.4f449301.webp)

### Set the Author

The editor records the current user as the author of a change. The current user is the first name in the list of user names that you pass to the editor. In an ASP.NET Core view, set [TextControlSettings.UserNames](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc/textcontrolsettings/usernames-property/llms-full.txt):

```cshtml
@using TXTextControl.Web.MVC

@Html.TXTextControl().TextControl(settings => {
    settings.UserNames = new string[] { "Tim Typer" };
}).Render()
```

In a JavaScript page, pass the names to [TXTextControl.init](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/init-method/llms-full.txt) as [userNames](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/documenteditorsettings/usernames-property/llms-full.txt) of the `editorSettings` object, a [DocumentEditorSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/documenteditorsettings/llms-full.txt). The same list sets the users who may edit editable regions of a protected document. Set it from the identity of the signed-in user, so that each change shows who made it. If the list is empty, changes are recorded without an author.

Your code reads the list with [getUserNames](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/getusernames-method/llms-full.txt). The JavaScript API has no method that changes it.

### Work With Tracked Changes

The following view sets the author and turns tracking on when the editor is loaded. Its buttons turn tracking on and off, accept the change at the input position, accept or reject all changes and list them. Replace the content of *Views/Home/Index.cshtml*:

```cshtml
@using TXTextControl.Web.MVC

@Html.TXTextControl().TextControl(settings => {
    settings.UserNames = new string[] { "Tim Typer" };
}).Render()

<input type="button" onclick="toggleTrackChanges()" value="Track Changes On/Off" />
<input type="button" onclick="acceptCurrentChange()" value="Accept Change" />
<input type="button" onclick="removeAllChanges(true)" value="Accept All" />
<input type="button" onclick="removeAllChanges(false)" value="Reject All" />
<input type="button" onclick="listTrackedChanges()" value="List Changes" />

<script>
    TXTextControl.addEventListener("textControlLoaded", function () {
        TXTextControl.setIsTrackChangesEnabled(true);
        TXTextControl.showSideBar(TXTextControl.SideBarType.TrackChanges);
    });

    TXTextControl.addEventListener("trackedChangeCreated", function (e) {
        console.log("New change by " + e.trackedChange.userName);
    });

    function toggleTrackChanges() {
        TXTextControl.getIsTrackChangesEnabled(function (enabled) {
            TXTextControl.setIsTrackChangesEnabled(!enabled);
        });
    }

    function acceptCurrentChange() {
        TXTextControl.trackedChanges.getItem(function (change) {
            if (change === null) {
                return; // no tracked change at the input position
            }
            TXTextControl.trackedChanges.remove(change, true);
        });
    }

    function removeAllChanges(accept) {
        TXTextControl.trackedChanges.getCount(function (count) {
            if (count === 0) {
                return;
            }
            TXTextControl.trackedChanges.elementAt(0, function (change) {
                TXTextControl.trackedChanges.remove(change, accept, function (removed) {
                    // Continue with the next change once this one is removed
                    if (removed === true) {
                        removeAllChanges(accept);
                    }
                });
            });
        });
    }

    function listTrackedChanges() {
        TXTextControl.trackedChanges.forEach(function (change) {
            change.getChangeKind(function (kind) {
                change.getUserName(function (userName) {
                    change.getText(function (text) {
                        var action = (kind === TXTextControl.ChangeKind.InsertedText) ? "inserted" : "deleted";
                        console.log(userName + " " + action + ": " + text);
                    });
                });
            });
        });
    }
</script>
```

The code works as follows:

- [setIsTrackChangesEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/setistrackchangesenabled-method/llms-full.txt) turns tracking on or off, and [getIsTrackChangesEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/getistrackchangesenabled-method/llms-full.txt) passes the current state. The older property `isTrackChangesEnabled` is obsolete.
- [showSideBar](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/showsidebar-method/llms-full.txt) opens the Track Changes sidebar, selected with `TrackChanges` from [SideBarType](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/sidebartype-enumeration/llms-full.txt).
- [TXTextControl.trackedChanges](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/formattedtext/trackedchanges-property/llms-full.txt) returns the [TrackedChangeCollection](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchangecollection/llms-full.txt). Its [getItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchangecollection/getitem-method/llms-full.txt) passes the change at the input position, or `null`.
- [TrackedChangeCollection.remove](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchangecollection/remove-method/llms-full.txt) accepts a change with `true` and rejects it with `false`. A rejected insertion is removed, and a rejected deletion is restored.
- `removeAllChanges` removes the first change and, once its callback reports success, calls itself again until no change is left. Each change is removed only after the previous one has been removed.
- [TrackedChange](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/llms-full.txt) passes its kind with [getChangeKind](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/getchangekind-method/llms-full.txt), `InsertedText` or `DeletedText` from [ChangeKind](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/changekind-enumeration/llms-full.txt), its author with [getUserName](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/getusername-method/llms-full.txt), and the changed text with [getText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/gettext-method/llms-full.txt).

Type some text in the editor, delete a word and click **List Changes**: the browser console shows both changes with the author Tim Typer. Click **Reject All** to restore the original text.

### Other Properties of a Tracked Change

| Method | Passes or sets |
|---|---|
| [getStart](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/getstart-method/llms-full.txt), [getLength](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/getlength-method/llms-full.txt) | The one-based position of the first changed character and the number of characters |
| [getChangeTime](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/getchangetime-method/llms-full.txt) | The time of the change as a Unix timestamp |
| [setHighlightColor](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/sethighlightcolor-method/llms-full.txt), [setHighlightMode](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/sethighlightmode-method/llms-full.txt) | The color and whether the change is highlighted |
| [setActive](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchange/setactive-method/llms-full.txt) | Whether the change is active; an inactive change isn't highlighted |

### React to Tracked Changes

The editor raises these events:

- `trackedChangeCreated` and `trackedChangeDeleted` when a change is recorded or removed, `trackedChangeChanged` when the text of a change is altered and `trackedChangeStateChanged` when a change becomes active or inactive. The handlers receive [TrackedChangeEventArgs](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/trackedchangeeventargs/llms-full.txt) with the author, kind, time and position of the change.
- `cannotTrackChange` when a change of the document can't be added to the tracked changes. The handler receives a default message.

[Events](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/events/llms-full.txt) lists all events.

### Save Documents With Tracked Changes

Tracked changes are saved and loaded with DOCX, RTF and the TX Text Control format, and they are compatible with the tracked changes of MS Word. A document that your users review in the editor can therefore be opened in MS Word with its changes, and the other way around. Save the document as described in [Loading and Saving Documents](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/load-save/llms-full.txt).

To process tracked changes on the server, for example to accept all changes before a document is archived, use [ServerTextControl.TrackedChanges](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/trackedchanges-property/llms-full.txt). The blog article [Document Redlining and Approval Workflows with TX Text Control Track Changes in .NET C#](https://www.textcontrol.com/blog/2024/08/07/document-redlining-and-approval-workflows-with-tx-text-control-track-changes-in-net-csharp/) describes a complete workflow.

### Next Steps

- [Comments](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/comments/llms-full.txt): add comments to text and to tracked changes.
- [Events](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/events/llms-full.txt): the events of tracked changes.
- [Document Protection](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/protection/llms-full.txt): protect documents and set editable regions.

---

## Nearby

- **Previous:** [Signature Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/signature-fields/llms-full.txt)
- **Next:** [Comments](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/comments/llms-full.txt)
