# Reuse Document Editor Instances by Dynamically Moving them in the DOM

> Reusing the document editor by moving it in the DOM is a very fast and efficient way to edit documents or snippets in multiple places on a page. This technique and the logic behind it are explained in this article.

- **Author:** Bjoern Meyer
- **Published:** 2023-10-02
- **Modified:** 2026-07-17
- **Description:** Reusing the document editor by moving it in the DOM is a very fast and efficient way to edit documents or snippets in multiple places on a page. This technique and the logic behind it are explained in this article.
- **3 min read** (480 words)
- **Tags:**
  - ASP.NET
  - DOM
  - JavaScript
- **Web URL:** https://www.textcontrol.com/blog/2023/10/02/reuse-document-editor-instances-by-dynamically-moving-them-in-the-dom/
- **LLMs URL:** https://www.textcontrol.com/blog/2023/10/02/reuse-document-editor-instances-by-dynamically-moving-them-in-the-dom/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2023/10/02/reuse-document-editor-instances-by-dynamically-moving-them-in-the-dom/llms-full.txt

---

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.

[![Reusing Document Editor Instances](https://s1-www.textcontrol.com/assets/dist/blog/2023/10/02/a/assets/reuse.gif "Reusing Document Editor Instances")](https://s1-www.textcontrol.com/assets/dist/blog/2023/10/02/a/assets/reuse.gif)

### 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>
```

### 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();
```

When a container is clicked, an image of the first page of the document is created using the getImage 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.

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [Reuse Angular Document Editor Instances in Bootstrap Tabs](https://www.textcontrol.com/blog/2023/05/22/reuse-angular-document-editor-instances-in-bootstrap-tabs/llms.txt)
- [Build a Custom Backstage View in ASP.NET Core with TX Text Control](https://www.textcontrol.com/blog/2026/02/17/build-a-custom-backstage-view-in-aspnet-core-with-tx-text-control/llms.txt)
- [5 Document Workflows You Can Automate With JavaScript Rich Text Editor](https://www.textcontrol.com/blog/2026/01/14/five-document-workflows-you-can-automate-with-javascript-rich-text-editor/llms.txt)
- [Add JavaScript to PDFs with TX Text Control in C# .NET: Time-Based Alerts Made Easy](https://www.textcontrol.com/blog/2025/06/13/add-javascript-to-pdfs-with-tx-text-control-in-c-dot-net-time-based-alerts-made-easy/llms.txt)
- [Using the Document Editor in SPA Applications using the removeFromDom Method](https://www.textcontrol.com/blog/2024/09/02/using-the-document-editor-in-spa-applications-using-the-removefromdom-method/llms.txt)
- [Observe When the Reporting Preview Tab is Active Using MutationObserver](https://www.textcontrol.com/blog/2024/07/23/observe-when-the-reporting-preview-tab-is-active-using-mutationobserver/llms.txt)
- [Removing Empty Pages in TX Text Control with JavaScript](https://www.textcontrol.com/blog/2024/06/19/removing-empty-pages-in-tx-textcontrol-with-javascript/llms.txt)
- [Document Editor: Useful JavaScript Functions for Tables](https://www.textcontrol.com/blog/2024/06/19/document-editor-useful-javascript-functions-for-tables/llms.txt)
- [Extract Data from PDF Documents with C#](https://www.textcontrol.com/blog/2024/06/10/extract-data-from-pdf-documents-with-csharp/llms.txt)
- [Inject JavaScript to PDF Documents in C#](https://www.textcontrol.com/blog/2024/06/07/inject-javascript-to-pdf-documents-in-csharp/llms.txt)
- [Loading Documents from Azure Blob Storage into the TX Text Control Document Editor using pure JavaScript](https://www.textcontrol.com/blog/2024/04/08/loading-documents-from-azure-blob-storage-into-tx-text-control-document-editor-using-pure-javascript/llms.txt)
- [Building an ASP.NET Core Backend Application to Host the Document Editor and Document Viewer](https://www.textcontrol.com/blog/2024/03/14/building-an-asp-net-core-backend-application-to-host-the-document-editor-and-document-viewer/llms.txt)
- [Document Editor: How to Customize the Reconnecting Alert Message](https://www.textcontrol.com/blog/2023/12/18/document-editor-how-to-customize-the-reconnecting-alert-message/llms.txt)
- [Updating SubTextParts using JavaScript Promises](https://www.textcontrol.com/blog/2022/12/23/updating-subtextparts-using-javascript-promises/llms.txt)
- [MailMerge: Working with Image Placeholders](https://www.textcontrol.com/blog/2022/12/22/mailmerge-working-with-image-placeholders/llms.txt)
- [Sneak Peek 31.0: Customizing the Context Menu of the ASP.NET Document Editor](https://www.textcontrol.com/blog/2022/08/25/sneak-peek-310-customizing-the-context-menu-of-the-aspnet-document-editor/llms.txt)
- [Text Control Error Navigator Launched](https://www.textcontrol.com/blog/2022/08/15/text-control-error-navigator-launched/llms.txt)
- [Restoring the Merge Field Default Behavior](https://www.textcontrol.com/blog/2022/08/15/restoring-the-merge-field-default-behavior/llms.txt)
- [JavaScript: Avoid Flickering and Visual Updates by Grouping Undo Steps](https://www.textcontrol.com/blog/2022/07/25/javascript-avoid-flickering-and-visual-updates-by-grouping-undo-steps/llms.txt)
- [DS Server or TX Text Control? Different Deployment Scenarios](https://www.textcontrol.com/blog/2022/05/03/ds-server-or-tx-text-control-different-deployment-scenarios/llms.txt)
- [Document Editor: JavaScript Object Availability and Order of Events](https://www.textcontrol.com/blog/2022/05/03/documenteditor-javascript-object-availability-and-order-of-events/llms.txt)
- [Generating Interactive PDF Forms by Injecting JavaScript](https://www.textcontrol.com/blog/2022/03/31/generating-interactive-pdf-forms-by-injecting-javascript/llms.txt)
- [Deploying Documents with Annotations](https://www.textcontrol.com/blog/2022/01/07/deploying-documents-with-annotations/llms.txt)
- [Using TX Text Control .NET Server in Blazor Server Apps](https://www.textcontrol.com/blog/2022/01/06/using-tx-text-control-net-server-for-aspnet-in-blazor-server-apps/llms.txt)
- [Detect Toggle Button Changes Using a MutationObserver](https://www.textcontrol.com/blog/2021/11/11/detect-toggle-button-changes-using-a-mutationobserver/llms.txt)
