Reusing instances of the Document Editor reduces load and initialization time and significantly improves the user experience when editing smaller snippets of text on a page. Once loaded, the Document Editor can be easily reused by moving it in the DOM and dynamically loading the document.

The following screen capture shows three instances of the Document Editor that are being moved around in the DOM in order to edit different documents.

HTML Containers

In the HTML there is a mainContainer, which contains the document editor that has been initialized. The other DIV elements with the editorContainer class name will contain these instances when they are enabled.

<div id="mainContainer">
@Html.TXTextControl().TextControl(settings => {
settings.Dock = DockStyle.Fill;
}).Render()
</div>
<div class="row mb-3">
<div class="col-12">
<label for="container1" class="form-label">Document Editor 1</label>
<div id="container1" class="editorContainer inactive">
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-12">
<label for="container2" class="form-label">Document Editor 2</label>
<div id="container2" class="editorContainer inactive">
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-12">
<label for="container3" class="form-label">Document Editor 3</label>
<div id="container3" class="editorContainer inactive">
</div>
</div>
</div>
view raw test.html hosted with ❤ by GitHub

JavaScript: ContainerManager

The ContainerManager class handles the DOM manipulation when a new container is activated. All DIV elements with the class name editorContainer will have click events added to them in the constructor.

class ContainerManager {
constructor() {
this.currentContainer = null;
this.storedDocuments = {};
this.attachEventListeners();
}
async enableContainer(container, show) {
if (this.currentContainer !== null) {
await this.saveContainer(this.currentContainer);
this.currentContainer.classList.add("inactive");
}
container.classList.remove("inactive");
container.innerHTML = "";
container.appendChild(document.getElementById("mainContainer"));
await this.replaceContainer(this.currentContainer);
await this.loadContainer(container);
this.currentContainer = container;
if (show === true) {
document.getElementById("mainContainer").style.display = "inline-block";
document.getElementById("mainContainer").style.height = "100%";
window.dispatchEvent(new Event('resize'));
}
}
async replaceContainer(container) {
return new Promise(resolve => {
if (container === null) {
resolve(false);
} else {
TXTextControl.pages.elementAt(0, page => {
page.getImage(TXTextControl.ImageFormat.Png, 100, 7, function (image) {
const img = document.createElement("img");
img.src = "data:image/png;base64," + image;
img.className = "img-thumbnail";
container.innerHTML = "";
container.appendChild(img);
resolve(true);
});
});
}
});
}
async saveContainer(container) {
return new Promise(resolve => {
if (container === null) {
resolve(false);
} else {
var docs = this.storedDocuments;
TXTextControl.saveDocument(TXTextControl.StreamType.InternalUnicodeFormat, function (data) {
docs[container.id] = data;
resolve(true);
});
}
});
}
async loadContainer(container) {
return new Promise(resolve => {
if (container === null) {
resolve(false);
} else {
console.log(this.storedDocuments[container.id]);
if (this.storedDocuments[container.id] !== undefined) {
TXTextControl.loadDocument(TXTextControl.StreamType.InternalUnicodeFormat, this.storedDocuments[container.id].data, function () {
resolve(true);
});
} else {
TXTextControl.resetContents();
resolve(false);
}
}
});
}
attachEventListeners() {
const elements = document.getElementsByClassName("editorContainer");
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener("click", (elem) => {
if (elem.target !== this.currentContainer && elem.target.className.includes("editorContainer")) {
this.enableContainer(elem.target, true);
}
});
}
}
}
const containerManager = new ContainerManager();
view raw test.js hosted with ❤ by GitHub

When a container is clicked, an image of the first page of the document is created using the getImage TX Text Control .NET Server for ASP.NET
JavaScript API
Page Object
getImage Method
Gets an image of the page's contents as in the specified format in screen resolution.
method. This image is used to replace the Document Editor in inactive mode. The current state of the document is stored in the internal TX Text Control format in a dictionary.

Finally, the stored document is loaded into the moved document editor to display the document of that container.