# Context Menus

> Customize the context menus of the Document Editor: turn them off, add items with click handlers and sub menus, disable or remove built-in items by location.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Document Editor > Ribbon and UI > Context Menus
- **3249 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/ribbon-ui/context-menus/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/ribbon-ui/context-menus/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/ribbon-ui/context-menus/llms-full.txt

---

The menus that open on a right-click in the Document Editor can carry commands of your own application, lose built-in commands users shouldn't use or be turned off. You react to the `contextMenuOpening` event, add items with click handlers and change built-in items.

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, whose **Insert Table** button inserts a table with the ID 10.

### How Context Menus Work

When a user right-clicks into the text area, the editor opens a context menu whose items depend on where the user clicked: selected text, a table, a header, a misspelled word or a comment, for example. Before the menu is shown, the editor raises the `contextMenuOpening` event. Its handler receives the items of the menu and can change them:

- **Add items** with a text and a function that runs when the item is clicked.
- **Change built-in items**: disable them, replace their action or remove them.
- **Cancel the menu**, so that it isn't shown at all.

The built-in items carry out their commands on the server, in the Document Editor backend; custom items call your JavaScript function. Customizable context menus were introduced in version 31.0. In version 34.0, the context menus of the editor on the Core engine were changed to offer the same functions as on Windows, so test existing customizations after an upgrade.

### Turn Context Menus Off

To open no context menus at all, set [TextControlSettings.ContextMenusEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-web-mvc/textcontrolsettings/contextmenusenabled-property/llms-full.txt) to `false` in the view:

```cshtml
@Html.TXTextControl().TextControl(settings => {
    settings.UserNames = new string[] { "Tim Typer" };
    settings.ContextMenusEnabled = false;
}).LoadText(sDocument, TXTextControl.Web.StringStreamType.HTMLFormat).Render()
```

The other frontends have the same setting:

- **JavaScript API.** [TXTextControl.contextMenusEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/contextmenusenabled-property/llms-full.txt) turns the menus on or off while the editor runs: `TXTextControl.contextMenusEnabled = false;`.
- **Plain JavaScript page.** [DocumentEditorSettings.contextMenusEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/documenteditorsettings/contextmenusenabled-property/llms-full.txt) is passed in `editorSettings` to `TXTextControl.init`, as shown in [JavaScript](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/document-editor/javascript/llms-full.txt).
- **Angular and React.** The components have a `contextMenusEnabled` attribute; see [Angular](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/document-editor/angular/llms-full.txt) and [React](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/document-editor/react/llms-full.txt).

### Add Items to a Context Menu

The following code adds an **Upper Case** item to the context menu of selected text, and a **Table Tools** sub menu to the context menu of a table. Add it below the **Insert Table** button in *Views/Home/Index.cshtml*:

```html
<script>
    // Click handler of the "Upper Case" item
    function convertToUpperCase(args) {
        TXTextControl.selection.getText(function (text) {
            TXTextControl.selection.setText(text.toUpperCase());
        });
    }

    // Click handler of the "Show Table ID" item
    function showTableId(args) {
        TXTextControl.tables.getItem(function (table) {
            table.getID(function (id) {
                console.log(args.item.text + ": " + id);
            });
        });
    }

    function handleContextMenuOpening(e) {
        var location = TXTextControl.ContextMenuLocation;

        // Show the built-in items and the location in the browser console
        console.log(e.location, e.items);

        if ((e.location & location.TextSelection) !== 0) {
            e.items.push({ text: "" }); // separator
            e.items.push({ text: "Upper Case", clickHandler: convertToUpperCase });
        }

        if ((e.location & location.Table) !== 0) {
            e.items.push({ text: "" });
            e.items.push({
                text: "Table Tools",
                items: [
                    { text: "Show Table ID", clickHandler: showTableId }
                ]
            });
        }
    }

    TXTextControl.addEventListener("textControlLoaded", function () {
        TXTextControl.addEventListener("contextMenuOpening", handleContextMenuOpening);
    });
</script>
```

The code works as follows:

- The `contextMenuOpening` handler receives [ContextMenuEventArgs](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenueventargs/llms-full.txt). [items](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenueventargs/items-property/llms-full.txt) is the array of [ContextMenuItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/llms-full.txt) objects the menu shows. The code adds items with `push`.
- [location](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenueventargs/location-property/llms-full.txt) is a combination of [ContextMenuLocation](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/contextmenulocation-enumeration/llms-full.txt) values. The bitwise `&` tests whether a value is part of it, because a menu over a selection in a table has both `TextSelection` and `Table`.
- An item with an empty [text](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/text-property/llms-full.txt) is a separator line. An item with [items](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/items-property/llms-full.txt) opens a sub menu.
- [clickHandler](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/clickhandler-property/llms-full.txt) is the function that runs when the item is clicked. It receives [ContextMenuItemClickEventArgs](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitemclickeventargs/llms-full.txt), whose [item](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitemclickeventargs/item-property/llms-full.txt) is the clicked item.
- The click handlers work with what the menu was opened for: [Selection.getText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/selection/gettext-method/llms-full.txt) and [setText](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/selection/settext-method/llms-full.txt) change the selected text, and [TableCollection.getItem](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/tablecollection/getitem-method/llms-full.txt) without an ID passes the table at the input position, whose ID [Table.getID](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/table/getid-method/llms-full.txt) passes.

Select a word and right-click it: the menu contains **Upper Case**, which converts the word.

![Context menu of selected text in the Document Editor with the built-in items Cut, Copy, Paste, Character..., Paragraph..., Bullets and Numbering..., Styles... and Insert, and the custom item Upper Case below a separator](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-server/context-menu-custom-item.b14a5712.webp)

Click **Insert Table**, click into the table, right-click and choose **Table Tools > Show Table ID**: the console shows "Show Table ID: 10".

The handler is a named function, so that [removeEventListener](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/txtextcontrol/removeeventlistener-method/llms-full.txt) can remove it again: `TXTextControl.removeEventListener("contextMenuOpening", handleContextMenuOpening);`.

#### Where a Context Menu Opens

| `ContextMenuLocation` value | The menu opens for |
|---|---|
| `TextSelection`, `TextInputPosition` | Selected text, or the text input position |
| `Header`, `NoHeader`, `Footer`, `NoFooter`, `PageMargin` | The top or bottom page margin, with or without a header or footer |
| `PageNumberField` | A page number field |
| `SelectedFrame` | A selected text frame, image, chart or barcode |
| `Table`, `TextField`, `TableOfContents` | A selection or the input position in a table, a text field or a table of contents |
| `MisspelledWord` | A selection or the input position in a misspelled word |
| `TrackedChange`, `Comment` | A selection or the input position in a tracked change or a comment |

### Properties of a Menu Item

A custom item needs only a `text`; all other properties are optional:

| Property | Sets |
|---|---|
| [text](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/text-property/llms-full.txt) | The text of the item; an empty string makes a separator line |
| [clickHandler](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/clickhandler-property/llms-full.txt) | The function that runs when the item is clicked |
| [imageUrl](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/imageurl-property/llms-full.txt) | An icon, as an image URL or a base64-encoded data URL such as `data:image/png;base64,...` |
| [items](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/items-property/llms-full.txt) | The items of a sub menu |
| [dropDownIsScrollable](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/dropdownisscrollable-property/llms-full.txt) | Whether the sub menu can be scrolled; `false` by default |
| [isChecked](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/ischecked-property/llms-full.txt) | Whether a check mark is shown in front of the item; `false` by default |
| [isEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/isenabled-property/llms-full.txt) | Whether the item can be clicked; `true` by default |

### Change Built-In Items

Built-in items are `ContextMenuItem` objects in the same array. Find them by their `text` and change them before the menu opens. The texts of the built-in items aren't listed in the reference, and the items changed in version 34.0, so log `e.items` in the browser console, as the code above does, to see the items of your version.

The following handler cancels the menu in the page margins and disables the **Footnote** item of the **Insert** sub menu. It shows two more changes in comments:

```javascript
function findItem(items, text) {
  return (items || []).find(function (item) { return item.text === text; });
}

TXTextControl.addEventListener("textControlLoaded", function () {
  TXTextControl.addEventListener("contextMenuOpening", function (e) {
    // No context menu in the top and bottom page margins
    if ((e.location & TXTextControl.ContextMenuLocation.PageMargin) !== 0) {
      e.cancel = true;
      return;
    }

    var insert = findItem(e.items, "Insert");
    if (!insert) {
      return;
    }

    var footnote = findItem(insert.items, "Footnote");
    if (footnote) {
      footnote.isEnabled = false;

      // To replace the built-in action instead:
      // footnote.clickHandler = function (args) { args.cancel = true; console.log("Footnotes are not available."); };
    }

    // To remove the complete "Insert" item:
    // e.items.splice(e.items.indexOf(insert), 1);
  });
});
```

- [ContextMenuEventArgs.cancel](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenueventargs/cancel-property/llms-full.txt) with `true` suppresses the menu.
- [isEnabled](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitem/isenabled-property/llms-full.txt) with `false` shows the item disabled.
- A click handler set on a built-in item runs when the item is clicked. [ContextMenuItemClickEventArgs.cancel](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/javascript/contextmenuitemclickeventargs/cancel-property/llms-full.txt) with `true` keeps the click from being sent to the backend, so the built-in command isn't carried out.
- `splice` removes an item from the array, so that the menu doesn't show it.

Find items by their text rather than by their position in the array: the order of the built-in items isn't documented either. The blog article [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/) shows these changes step by step.

### Next Steps

- [Ribbon](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/ribbon-ui/ribbon/llms-full.txt): change the ribbon of the editor.
- [Localization](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/ribbon-ui/localization/llms-full.txt): the language of the user interface.
- [Events](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/events/llms-full.txt): all events of the editor.

---

## Nearby

- **Previous:** [Ribbon](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/ribbon-ui/ribbon/llms-full.txt)
- **Next:** [Custom Tabs](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/ribbon-ui/custom-tabs/llms-full.txt)
