# Detect Toggle Button Changes Using a MutationObserver

> This article shows how to detect changes of toggle buttons in the ribbon of the web editor using a MutationObserver. The state of a toggle button in the ribbon visualizes the state of a certain property. For example a toggled list button shows, that the current input position belongs to a list.

- **Author:** Malin Teegen
- **Published:** 2021-11-11
- **Modified:** 2025-11-16
- **Description:** This article shows how to detect changes of toggle buttons in the ribbon of the web editor using a MutationObserver. The state of a toggle button in the ribbon visualizes the state of a certain property. For example a toggled list button shows, that the current input position belongs to a list.
- **2 min read** (316 words)
- **Tags:**
  - ASP.NET
  - Document Editor
  - HTML5
  - JavaScript
  - MVC
  - Ribbon
  - Sample
- **Web URL:** https://www.textcontrol.com/blog/2021/11/11/detect-toggle-button-changes-using-a-mutationobserver/
- **LLMs URL:** https://www.textcontrol.com/blog/2021/11/11/detect-toggle-button-changes-using-a-mutationobserver/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2021/11/11/detect-toggle-button-changes-using-a-mutationobserver/llms-full.txt

---

In order to react to a toggle button change, add an event listener to the *ribbonTabsLoaded* event and identify the id of the desired ribbon element for example by using the browser developer tool.

![MutationObserver](https://s1-www.textcontrol.com/assets/dist/blog/2021/11/11/a/assets/bullets.webp "MutationObserver")

### MutationObserver

A *MutationObserver* will allow you to react to changes in the DOM element. Switch statements can be used to distinguish between different cases.

It is important to use the correct observer configuration. Make sure to observe changes in the whole sub tree and also to pass the right root element as a target node in the *MutationObserver.observe()* method.

This code snippet shows how to detect toggles of the *Bullet List* dropdown in the ribbon *Home* tab. Therefore, the *Paragraph* group is passed as root element.

```
window.addEventListener("load", () => {
  TXTextControl.addEventListener("ribbonTabsLoaded", () => {
     // Obtain "Paragraph" ribbon group element (get further ribbon group element ids
     // by using the browser developer tools)
     const ribbonGroupParagraph = document.getElementById("ribbonGroupParagraph");

     const observer = new MutationObserver(mutations => {
        for (mutation of mutations) {
           switch (mutation.type) {
              case "attributes":
                 switch (mutation.attributeName) {
                    case "class":
                       // The "class" attribute of an element has been changed. 
                       // Get the affected element and figure out which button 
                       // was pressed via the element id.
                       const button = mutation.target;
                       switch (button.id) {
                          case "ribbonTabHome_drpDnBtnBulletList":
                             // "Bulleted list" button.
                             // The "toggled" state can be determined via the CSS class 
                             // "ribbon-button-selected".
                             if (button.classList.contains("ribbon-button-selected")) {
                                console.info("'Bulleted list' button toggled.")
                             }
                             else {
                                console.info("'Bulleted list' button un-toggled.")
                             }
                             break;

                          case "ribbonTabHome_drpDnBtnNumberedList":
                             // "Numbered list" button.
                             // ...
                             break;

                          // Get further button ids by browsing the html structure 
                          // using the browser developer tools.
                       }
                       break;
                 }
                 break;
           }
        }
     });

     // Observer configuration (We want to observe changes in the whole sub-tree of the 
     // "Paragraph" group root element).
     const config = { attributes: true, subtree: true };

     // Pass in the target node (in this case the "Paragraph" group root element) and 
     // the observer options.
     observer.observe(ribbonGroupParagraph, config);
  });
});
```

---

## About Malin Teegen

Malin Teegen is Head of Strategic Accounts and Marketing at Text Control in Bremen, Germany. She specializes in business development and the strategic expansion of customer relationships in the field of digital document processing. With a master's degree in marine biology from the University of Bremen and a certification in online marketing from Hamburg Media School, she combines analytical thinking with entrepreneurial vision. Her diverse experience in sales, online marketing, and digital journalism highlights her commitment to digital transformation and sustainable growth.

- [LinkedIn](https://www.linkedin.com/in/malin-teegen-32ba91255/)

---

## Related Posts

- [Implementing Conditional Table Cell Colors with MailMerge](https://www.textcontrol.com/blog/2020/10/08/implementing-conditional-table-cell-colors-with-mailmerge/llms.txt)
- [Best Practices for Adding Ribbon Tabs, Groups and Buttons to the TXTextControl.Web Ribbon Bar](https://www.textcontrol.com/blog/2017/12/21/best-practices-for-adding-ribbon-content-to-txtextcontrol-web/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)
- [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)
- [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)
- [Manipulating the Context Menu in the Document Editor using JavaScript](https://www.textcontrol.com/blog/2023/12/22/manipulating-the-context-menu-in-the-document-editor-using-javascript/llms.txt)
- [Document Editor: Initialization Events](https://www.textcontrol.com/blog/2023/10/23/document-editor-initialization-events/llms.txt)
- [Using the MVC DocumentViewer in ASP.NET Web Forms](https://www.textcontrol.com/blog/2021/08/12/using-the-mvc-documentviewer-in-aspnet-web-forms/llms.txt)
- [JavaScript Functions for Typical Form Field Tasks](https://www.textcontrol.com/blog/2020/04/15/javascript-functions-for-typical-form-field-tasks/llms.txt)
- [Document Collaboration: Implementing Comments with Document Targets](https://www.textcontrol.com/blog/2020/04/06/implementing-comments-with-document-targets/llms.txt)
- [Deploying the MVC HTML5 Editor to Azure App Services](https://www.textcontrol.com/blog/2018/04/06/deploying-the-mvc-html5-editor-to-azure-app-services/llms.txt)
- [Using the ASP.NET MVC DocumentViewer JavaScript API](https://www.textcontrol.com/blog/2017/04/28/using-the-aspnet-mvc-documentviewer-javascript-api/llms.txt)
- [MVC: Loading Files from the Backstage Menu](https://www.textcontrol.com/blog/2016/01/06/mvc-loading-files-from-the-backstage-menu/llms.txt)
- [MVC: Replace the File Menu with a Backstage View Menu](https://www.textcontrol.com/blog/2015/12/30/mvc-replace-the-file-menu-with-a-backstage-view-menu/llms.txt)
- [MVC: Replace the Ribbon Table Menu with a Quick Insert Table Drop-down](https://www.textcontrol.com/blog/2015/12/23/mvc-replace-the-ribbon-table-menu-with-a-quick-insert-table-drop-down/llms.txt)
- [MVC: Arrange a Docked Web.TextControl with a Custom Bar at the Top](https://www.textcontrol.com/blog/2015/12/18/mvc-arrange-a-docked-webtextcontrol-with-a-custom-bar-at-the-top/llms.txt)
- [MVC: Autosave and Restore Documents to and from the Local Browser Storage](https://www.textcontrol.com/blog/2015/12/14/mvc-autosave-and-restore-documents-to-and-from-the-local-browser-storage/llms.txt)
- [MVC: Loading and Saving Documents Through Controller HttpPost Methods](https://www.textcontrol.com/blog/2015/12/08/mvc-loading-and-saving-documents-through-controller-httppost-methods/llms.txt)
- [HTML5: Saving Documents in an MVC Controller Method](https://www.textcontrol.com/blog/2015/10/01/html5-saving-documents-in-an-mvc-controller-method/llms.txt)
- [Building a Touch-enabled Button Bar with Javascript](https://www.textcontrol.com/blog/2015/05/27/building-a-touch-enabled-button-bar-with-javascript/llms.txt)
- [Web.TextControl: JQueryUI Alert Boxes and Javascript Events](https://www.textcontrol.com/blog/2015/04/20/webtextcontrol-jqueryui-alert-boxes-and-javascript-events/llms.txt)
