Custom Toolbar Items in EJ2 TypeScript Rich Text Editor control
30 Jun 202521 minutes to read
The Syncfusion Rich Text Editor allows you to customize the toolbar using the toolbarSettings property. You can add custom commands with text, icons, or HTML templates and define their position in the toolbar.
Adding a custom command
This example demonstrates how to add a custom “Ω” command to the toolbar for inserting special characters. Clicking the Ω icon opens a special character list, allowing users to insert symbols into the editor.
Custom toolbar configuration
To add a custom tool with a tooltip, define it in the items field of the toolbarSettings property.
{
tooltipText: 'Insert Symbol',
// To disable the custom toolbar items on source code view
command: 'Custom',
undo: true,
click: function() {
},
template: '<button class="e-tbar-btn e-btn" tabindex="-1" id="custom_tbar" style="width:100%"><div class="e-tbar-btn-text" style="font-weight: 500;"> Ω</div></button>'
}import { enableRipple } from '@syncfusion/ej2-base';
enableRipple(true);
import {
RichTextEditor,
Toolbar,
Link,
NodeSelection,
Image,
QuickToolbar,
HtmlEditor,
} from '@syncfusion/ej2-richtexteditor';
import { Dialog } from '@syncfusion/ej2-popups';
RichTextEditor.Inject(Toolbar, Link, Image, QuickToolbar, HtmlEditor);
let selection: NodeSelection = new NodeSelection();
// Initialization of Dialog
let dialog: Dialog = new Dialog({
header: 'Special Characters',
content: document.getElementById('rteSpecial_char'),
target: document.getElementById('container'),
showCloseIcon: true,
isModal: true,
visible: false,
height: 'auto',
width: '500px',
cssClass: 'e-rte-elements',
overlayClick: dialogOverlay,
buttons: [
{ buttonModel: { content: 'Insert', isPrimary: true }, click: onInsert },
{ buttonModel: { content: 'Cancel' }, click: dialogOverlay },
],
created: onCreated,
});
// Render initialized Dialog
dialog.appendTo('#customTbarDialog');
let editor: RichTextEditor = new RichTextEditor({
value: `<div style='display: block;'><p style='margin-right: 10px'>The custom command \"insert special character\" is configured as the last item of the toolbar. Click on the command and choose the special character you want to include from the popup.</p></div>`,
toolbarSettings: {
items: [
'Bold',
'Italic',
'Underline',
'|',
'Formats',
'Alignments',
'OrderedList',
'UnorderedList',
'|',
'CreateLink',
'Image',
'|',
'SourceCode',
{
tooltipText: 'Insert Symbol',
undo: true,
click: function () {
dialog.element.style.display = '';
selection = editor.formatter.editorManager.nodeSelection;
var range = selection.getRange(
editor.contentModule.getDocument()
);
selection.save(range, editor.contentModule.getDocument());
dialog.show();
},
template:
'<button class="e-tbar-btn e-btn" tabindex="-1" id="custom_tbar" style="width:100%"><div class="e-tbar-btn-text" style="font-weight: 500;"> Ω</div></button>',
},
'|',
'Undo',
'Redo',
],
},
});
editor.appendTo('#editor');
function dialogOverlay() {
let activeEle: HTMLElement = dialog.element.querySelector(
'.char_block.e-active'
);
if (activeEle) {
activeEle.classList.remove('e-active');
}
dialog.hide();
}
function onInsert() {
selection.restore();
let activeEle: HTMLElement = dialog.element.querySelector(
'.char_block.e-active'
);
if (activeEle) {
editor.executeCommand('insertText', activeEle.textContent, {
undo: true,
});
}
dialogOverlay();
}
function onCreated() {
var dialogCtn = document.getElementById('rteSpecial_char');
dialogCtn.onclick = function (e: Event) {
let target: HTMLElement = e.target as HTMLElement;
let activeEle: HTMLElement = dialog.element.querySelector(
'.char_block.e-active'
);
if (target.classList.contains('char_block')) {
target.classList.add('e-active');
if (activeEle) {
activeEle.classList.remove('e-active');
}
}
};
}<!DOCTYPE html>
<html lang="en">
<head>
<title>Essential JS 2 Rich Text Editor</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Typescript UI Controls" />
<meta name="author" content="Syncfusion" />
<link href="index.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-richtexteditor/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-lists/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='loader'>Loading....</div>
<div id='container' class='e-rte-custom-tbar-section'>
<div id='editor'>
</div>
<div id="customTbarDialog" style="display: none">
<div id="rteSpecial_char">
<div class="char_block" title="^">^</div>
<div class="char_block" title="_">_</div>
<div class="char_block" title="`">`</div>
<div class="char_block" title="{">{</div>
<div class="char_block" title="|">|</div>
<div class="char_block" title="}">}</div>
<div class="char_block" title="~">~</div>
<div class="char_block" title=" "> </div>
<div class="char_block" title="¡">¡</div>
<div class="char_block" title="¢">¢</div>
<div class="char_block" title="£">£</div>
<div class="char_block" title="¤">¤</div>
<div class="char_block" title="¥">¥</div>
<div class="char_block" title="₹">₹</div>
<div class="char_block" title="¦">¦</div>
<div class="char_block" title="§">§</div>
<div class="char_block" title="¨">¨</div>
<div class="char_block" title="©">©</div>
<div class="char_block" title="ª">ª</div>
<div class="char_block" title="«">«</div>
<div class="char_block" title="¬">¬</div>
<div class="char_block" title="­">­</div>
<div class="char_block" title="®">®</div>
<div class="char_block" title="¯">¯</div>
<div class="char_block" title="°">°</div>
<div class="char_block" title="±">±</div>
<div class="char_block" title="²">²</div>
<div class="char_block" title="³">³</div>
<div class="char_block" title="´">´</div>
<div class="char_block" title="µ">µ</div>
<div class="char_block" title="¶">¶</div>
<div class="char_block" title="·">·</div>
<div class="char_block" title="¸">¸</div>
<div class="char_block" title="¹">¹</div>
<div class="char_block" title="º">º</div>
<div class="char_block" title="»">»</div>
<div class="char_block" title="¼">¼</div>
<div class="char_block" title="½">½</div>
<div class="char_block" title="¾">¾</div>
<div class="char_block" title="¿">¿</div>
<div class="char_block" title="À">À</div>
<div class="char_block" title="Á">Á</div>
<div class="char_block" title="Â">Â</div>
<div class="char_block" title="Ã">Ã</div>
</div>
</div>
</div>
<style>
#special_char,
.char_block {
display: inline-block;
}
.char_block.e-active {
/* box-shadow: inset 3px 3px 7px 0px; */
outline: 1.5px solid;
}
.char_block {
width: 30px;
height: 30px;
line-height: 30px;
margin: 0 5px 5px 0;
text-align: center;
vertical-align: middle;
border: 1px solid #dddddd;
font-size: 20px;
cursor: pointer;
user-select: none;
}
#custom_tbar,
#custom_tbar div {
cursor: pointer;
}
#rteSection {
height: 500px;
}
.e-rte-quick-popup .e-rte-quick-toolbar .e-roatate-left::before {
content: '\e76e';
}
.e-rte-quick-popup .e-rte-quick-toolbar .e-roatate-right::before {
content: '\e726';
}
.e-richtexteditor textarea.e-content {
float: left;
}
.e-richtexteditor .e-rte-content {
overflow: hidden;
}
.e-rte-content .e-content.e-pre-source {
width: 100%;
}
.property-panel-content td {
width: 50%;
}
.property-panel-content td div {
padding-left: 10px;
padding-top: 10px;
}
.e-icon-btn.e-active .e-md-preview::before {
content: '\e350';
}
.e-icon-btn .e-md-preview.e-icons::before {
content: '\e345';
}
.e-icon-btn.e-active .e-md-preview::before,
#mdCustom .e-icon-btn.e-active .e-md-preview.e-icons::before {
content: '\e350';
}
#mdCustom .e-icon-btn .e-md-preview.e-icons::before {
content: '\e345';
}
#rteDialog.e-dialog .e-dlg-content {
padding: 0px 0px 5px 16px;
}
#custom_tbar .e-tbar-btn-text {
font-size: 16px;
}
.e-bigger #custom_tbar .e-tbar-btn-text {
font-size: 18px;
}
@media (min-width: 320px) and (max-width: 480px) {
.fabric.e-bigger #rteDialog {
min-width: 281px;
}
.fabric #rteDialog {
min-width: 241px;
}
.bootstrap.e-bigger #rteDialog,
.bootstrap #rteDialog {
min-width: 223px;
}
.highcontrast.e-bigger #rteDialog {
min-width: 283px;
}
.highcontrast #rteDialog {
min-width: 243px;
}
.material #rteDialog {
min-width: 224px;
}
.material.e-bigger #rteDialog {
min-width: 236px;
}
}
</style>
</body>
</html>When rendering any control for the custom toolbar, like a dropdown, the focus may be lost, causing it to render outside the Rich Text Editor and triggering a blur event. This can interfere with proper functionalities like cursor focus. To prevent this issue, it is recommended to assign the
e-rte-elementsclass to the control rendered in the custom toolbar.
Enabling and disabling toolbar items
You can use the enableToolbarItem and disableToolbarItem methods to control the state of toolbar items. This methods takes a single item or an array of items as parameter.
You can add the command name
Customto disable the custom toolbar items on source code view and other quicktoolbar operations.